(I deleted a previous question because now I know the problem and can give a better title. I guess I'll answer this myself.)
This example is from https://github.com/mrdoob/three.js/wiki/Getting-Started
The problem is that the example doesn't work for me on FF45 or GC50. It shows only the gray background. It does work on IE11.
A workaround is to use MeshPhongMaterial instead of MeshLambertMaterial. Then it works on all 3 browsers.
I'm using three.js R75 and Windows 10. I'm not sure if this is a problem in other situations.
<!DOCTYPE html>
<html>
<head>
<title>Getting Started with Three.js</title>
<script src="three.min.js"></script>
<script>
window.onload = function() {
var renderer = new THREE.WebGLRenderer();
renderer.setSize( 800, 600 );
document.body.appendChild( renderer.domElement );
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(
35, // Field of view
800 / 600, // Aspect ratio
0.1, // Near plane
10000 // Far plane
);
camera.position.set( -15, 10, 10 );
camera.lookAt( scene.position );
var geometry = new THREE.BoxGeometry( 5, 5, 5 );
var material = new THREE.MeshLambertMaterial( { color: 0xFF0000 } );
var mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
var light = new THREE.PointLight( 0xFFFF00 );
light.position.set( 10, 0, 10 );
scene.add( light );
renderer.setClearColor( 0xdddddd, 1);
renderer.render( scene, camera );
};
</script>
</head>
<body></body>
</html>
Related
I was making a sphere that can be moved by a mouse using three.js but the output is just a black screen as shown.
The code I used is:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>My first three.js app</title>
<style>
body { margin: 0; }
</style>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r79/three.min.js"></script>
<script>
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
camera.position.set( 0, 0, 50 );
camera.lookAt( 0, 0, 0 );
const renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
const geometry = new THREE.SphereGeometry( 15, 32, 16 );
const texture = new THREE.TextureLoader().load( 'https://i.imgur.com/kFoWvzw.jpg' );
const material = new THREE.MeshBasicMaterial( { map: texture } );
const sphere = new THREE.Mesh( geometry, material );
const controls = new OrbitControls( camera, renderer.domElement );
controls.mouseButtons = {
LEFT: THREE.MOUSE.ROTATE,
MIDDLE: THREE.MOUSE.DOLLY,
RIGHT: THREE.MOUSE.PAN
}
controls.update();
scene.add( sphere );
function animate()
{
requestAnimationFrame( animate );
sphere.rotation.x += 0.01;
sphere.rotation.y += 0.01;
renderer.render( scene, camera );
};
animate();
</script>
</body>
</html>
I couldn't explain why the code was unable to render the sphere. What went wrong?
Thank you!
Like the error message indicates, you are trying to use OrbitControls but it cannot be found. This is because it is not part of the core THREE.js library, but it is in the THREE.js examples directory so you need to import it separately.
You can import it through an HTML script tag like you do with THREE.js:
<script src="path/to/your/local/file/OrbitControls.js">.
Notice also that if you import it in your HTML, you should call it as
const controls = new THREE.OrbitControls(...);
as the js/ file adds the class to the THREE object.
See the docs or the source.
This is the complete code on how to move the camera on the Sphere.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>My first three.js app</title>
<style>
body { margin: 0; }
</style>
</head>
<body>
<script src="https://cdn.jsdelivr.net/npm/three#0.143/build/three.min.js"></script>
<script src=".\three.js-master\three.js-master\examples\js\controls\OrbitControls.js"></script>
<script>
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
camera.position.set( 0, 0, 50 );
camera.lookAt( 0, 0, 0 );
const renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
const geometry = new THREE.SphereGeometry( 15, 32, 16 );
const texture = new THREE.TextureLoader().load( 'https://i.imgur.com/kFoWvzw.jpg' );
const material = new THREE.MeshBasicMaterial( { map: texture } );
const sphere = new THREE.Mesh( geometry, material );
const controls = new THREE.OrbitControls( camera, renderer.domElement );
controls.update();
scene.add( sphere );
function animate()
{
requestAnimationFrame( animate );
sphere.rotation.x += 0.01;
sphere.rotation.y += 0.01;
renderer.render( scene, camera );
};
animate();
</script>
</body>
</html>
This is the correct code on how to move the camera on the Sphere...:-)
I intend to create an app that changes the color of reflected light by using the slider created via three.js GUI.
The HTML code I used to change the color of light at her will is:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>How to put GUI in three.js app?</title>
<style>
body { margin: 0; }
</style>
</head>
<body>
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<!-- MODULE option is more difficult to use in this simple setup:
<script src="https://threejs.org/examples/jsm/libs/lil-gui.module.min.js"></script>
-->
<script src="https://cdn.jsdelivr.net/npm/lil-gui#0.17"></script>
<script>
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
camera.position.set( 0, 0, 50 );
camera.lookAt( 0, 0, 0 );
const renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
const geometry2 = new THREE.SphereGeometry( 50, 32, 16 );
const texture2 = new THREE.TextureLoader().load( 'https://i.imgur.com/P4PQzYk.jpg' );
const material2 = new THREE.MeshPhongMaterial( { map: texture2 } );
const sphere2 = new THREE.Mesh( geometry2, material2 );
scene.add( sphere2 );
sphere2.position.set(100, 0, -500);
function greenDoge(newGreen)
{
const green = newGreen;
let colorofsun = new THREE.Color ("rgb( 255, green, 255");
const light = new THREE.PointLight( colorofsun , 2, 5000, 2 );
light.position.set( 0, 0, 0 );
if (scene) {
scene.remove(light)
}
scene.add( light );
}
greenDoge(10);
const GUI = lil.GUI;
const gui = new GUI();
const params = {
green: 0
}
const folderDoge = gui.addFolder( 'Change Color' );
folderDoge.add( params, 'green', 0, 255, 1).onChange( greenDoge );
folderDoge.open();
const controls = new THREE.OrbitControls( camera, renderer.domElement );
controls.update();
function animate()
{
sphere2.rotation.x += 0.00;
sphere2.rotation.y += 0.01;
renderer.render( scene, camera );
requestAnimationFrame(animate);
};
requestAnimationFrame(animate);
</script>
</body>
</html>
The HTML code did work, but when I tried to adjust the color of the light, the sphere remains white and the web browser becomes noticeably slower.
I don't know where I messed up. I couldn't find any reason why the sphere can't change color when I slide the slider GUI.
What is the reason why the color didn't change?
How do we also modify the code such that the color can be changed to our will? Any hints will be very welcome.
Thank you!
First of all there are very obvious errors in your code.
You're missing a closing bracket in your new THREE.Color constructor call and also you're trying to use a variable in a string, which will not work.
so this:
let colorofsun = new THREE.Color ("rgb( 255, green, 255");
should more look like this:
let colorofsun = new THREE.Color ("rgb( 255, " + green + ", 255 )");
Fixing this however does not fix your problem as there are many other issues. I think you should start reading more documentation and code samples.
but lets stick to your problem:
in your greenDoge function, you're creating a new instance of PointLight and after that you want to remove it from the scene. this will never work as a new created light cannot be in the scene without adding it first.
You would need to give your light a name to remove it and update your materials to have it added for that to work. You might want to read here.
However adding and removing the light every time the color changes is not necessary at all.
What you could do instead is just adding the light once and update its color like this:
let colorofsun = new THREE.Color ("rgb( 255, 255, 255)");
var light = new THREE.PointLight( colorofsun , 2, 5000, 2 );
light.position.set( 0, 0, 0 );
scene.add( light );
function greenDoge(newGreen)
{
light.color.setRGB(1, newGreen, 1);
}
note that the setRGB function is using values from 0 to 1. so you need to change your slider values accordingly.
folderDoge.add( params, 'green', 0, 1, 0.1).onChange( greenDoge );
You can read more about that on the github page of threejs.
I have tested PCL triangluation introduced here:
And from the experiment I got a .vtk file.
And I tried to render it via web browser whith three.js on windows.
It is like below:
See! There are many holes. These holes are triangles that have opposite normal vectors.
What I need is flipping those normal vectors that are opposite than others.
This way I believe I would get clean mesh image as shown below:
How can I do this?
Do I work with three.js?
Had I better work with pcl library? - the triangluation?
This is the html I tested:
<!DOCTYPE html>
<html lang="en">
<head>
<!--title>four.js webgl - loaders - vtk loader</title-->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<link type="text/css" rel="stylesheet" href="main.css">
</head>
<body>
<script type="module">
var console = (window.console = window.console || {});
import * as THREE from '../build/three.module.js';
import { TrackballControls } from './jsm/controls/TrackballControls.js';
import { VTKLoader } from './jsm/loaders/VTKLoader.js';
import { VertexNormalsHelper } from './jsm/helpers/VertexNormalsHelper.js';
let container, camera, controls, scene, renderer, vnh;
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 0.01, 1e10);
camera.position.set( -1, 0, 0 );
scene = new THREE.Scene();
scene.add( camera );
// light
const hemiLight = new THREE.HemisphereLight( 0xffffff, 0x000000, 1 );
scene.add( hemiLight );
const dirLight = new THREE.DirectionalLight( 0xffffff, 0.5 );
dirLight.position.set( 2, 2, 2 );
scene.add( dirLight );
const material = new THREE.MeshLambertMaterial( { color: 0xffffff } );
const loader = new VTKLoader();
loader.load( "models/vtk/point_cloud_mesh.vtk", function ( geometry )
//loader.load( "models/vtk/point_cloud_mesh_not_smoothed.vtk", function ( geometry )
{
//geometry.applyMatrix(new THREE.Matrix4().makeScale(-1, -1,-1));
//geometry.computeFaceNormals();
//var tmp;
//console.log(geometry.index.count);
//console.log(geometry.userData);
geometry.computeVertexNormals();
const mesh = new THREE.Mesh( geometry, material );
mesh.position.set( - 0.075, 0.005, 0 );
mesh.scale.multiplyScalar( 0.2 );
scene.add( mesh );
//vnh = new VertexNormalsHelper(mesh, 0.001, 0x00ff00, 1);
//scene.add( vnh );
} );
// renderer
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
container = document.createElement( 'div' );
document.body.appendChild( container );
container.appendChild( renderer.domElement );
// controls
controls = new TrackballControls( camera, renderer.domElement );
controls.minDistance = .1;
controls.maxDistance = 0.5;
controls.rotateSpeed = 5.0;
window.addEventListener( 'resize', onWindowResize );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
controls.handleResize();
}
function animate() {
requestAnimationFrame( animate );
controls.update();
//if (vnh) vnh.update();
renderer.render( scene, camera );
}
</script>
</body>
</html>
Thanks to WestLangley , I finally got a expected result as shown below:
Thank you WestLangley and Stackoverflow!!
But the question still remains. WestLangley's suggestion helps but it wouldn't be the only one solution. As you see below, some of the normal vectors are facing into the body of my hand. I believe there would be a way to make all the normal vectors face out of the body of my hand. Answers to this question still wanted...
I am new to three.js, but am just coming off of a project using Java and JMonkeyEngine, so I know my way around 3d.
My issue comes with loading a texture. I'm sure this question has come up quite a few times coming from the topics I've read, however the topics I have seen are older, and it didn't work with what I needed.
I took an example from the site and tried editing it to my own needs. I was able to load my texture fine, and it spun around just like the example....
HOWEVER, when I removed the animation from the rendering process my image poofed. I can use a regular square with color just fine, but no texture.
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js webgl - geometries</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,
user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
font-family: Monospace;
background-color: #000;
margin: 0px;
overflow: hidden;
}
</style>
</head>
<body>
<script src="three.min.js"></script>
<script>
var container, stats;
var camera, scene, renderer;
init();
animate();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
camera = new THREE.PerspectiveCamera(
45, window.innerWidth / window.innerHeight, 1, 2000 );
camera.position.y = 400;
scene = new THREE.Scene();
var light, object;
scene.add( new THREE.AmbientLight( 0x404040 ) );
light = new THREE.DirectionalLight( 0xffffff );
light.position.set( 0, 1, 0 );
scene.add( light );
var map = THREE.ImageUtils.loadTexture( 'butter.jpg' );
map.wrapS = map.wrapT = THREE.RepeatWrapping;
map.anisotropy = 16;
var material =
new THREE.MeshLambertMaterial(
{ ambient: 0xbbbbbb, map: map, side: THREE.DoubleSide } );
//
object = new THREE.Mesh(
new THREE.PlaneGeometry(100, 100, 4, 4 ), material );
object.position.set( -400, 0, 0 );
scene.add( object );
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
//
window.addEventListener( 'resize', onWindowResize, false );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
//
function animate() {
requestAnimationFrame( animate );
render();
}
function render() {
var timer = Date.now() * 0.0001;
camera.position.x = Math.cos( timer ) * 800;
camera.position.z = Math.sin( timer ) * 800;
camera.lookAt( scene.position );
for ( var i = 0, l = scene.children.length; i < l; i ++ ) {
var object = scene.children[ i ];
object.rotation.x = timer * 5;
object.rotation.y = timer * 2.5;
}
renderer.render( scene, camera );
}
</script>
</body>
I read up something here Using textures in THREE.js stating I needed to call the render after the texture loads. Sure, no problem, but it doesn't work. I assumed this could be the case, but I think about the animation. Did it load and since the animation is constant it just loaded after a render pass and then was okay during the rest of it, or something else?
Next I saw Texture from hard disk not loading in three.js - showing black
Now the user says he cannot see anything doing all sorts of things, I haven't tried any of that, but I'm using Netbeans 8.0 and it calls from the LocalHost, and I can see the animated textures, so I'm assuming this isn't the issue.
I saw another forum like this as well, with similar answers to the 2 above."
Any thoughts to think? Hopefully it's something simple.
Thanks for the help all, hopefully this library works out great!
EDIT: I found a post here ThreeJS texture issue saying there is an issue with chrome (which I was using as the browser to test). I tried the internal netbeans browser (it just gave me an error with webgl so meh) and ie didn;t work either...
I also tried to use a loader as suggested but his method gives off an "undefined" error.
I saw another post stating R58 -> R59 had changes to thw ImageLoader, so idk :(
EDIT2: Trying out the starting example of Three.JS I cannot get the texture to work stationary or during the animation.... weird..
<html>
<head>
<title>My first Three.js app</title>
<style>canvas { width: 100%; height: 100% }</style>
</head>
<body>
<script src="three.min.js"></script>
<script>
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
var geometry = new THREE.BoxGeometry(1,1,1);
var map = THREE.ImageUtils.loadTexture('butter.jpg', {}, function() {render();});
// render();
map.wrapS = map.wrapT = THREE.RepeatWrapping;
map.anisotropy = 16;
var material = new THREE.MeshLambertMaterial( { ambient: 0xbbbbbb, map: map, side: THREE.DoubleSide } );
//var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
var cube = new THREE.Mesh( geometry, material );
scene.add( cube );
camera.position.z = 5;
function render()
{
requestAnimationFrame(render);
cube.rotation.x += 0.1;
cube.rotation.y += 0.1;
renderer.render(scene, camera);
}
render();
</script>
</body>
EDIT3: Thought about this last night as I was going to sleep, and realized today that there is no NPOT... I tried another image that was 184x184 with no luck :(
How does one go about creating an ellipse in three.js?
I've looked at this:
Drawing an ellipse in THREE.js
But it would be cool if someone could provide a working example.
I've tried this:
ellipse = new THREE.EllipseCurve(0,0,200,400,45,45,10);
but that's not working for me. I have no idea what the parameters mean so I'm just blindly going about it.
edit: I am getting the error "defined is not a function" when I try to create an ellipse curve.
edit2: Figured out I had to include Curves.js for it to work but having a working example somewhere would still be really nice for me and other people since the stackoverflow link I pasted earlier doesn't have an example.
I am unfamiliar with THREE.js, but looking at the code the parameters seem to be
(Center_Xpos, Center_Ypos, Xradius, Yradius, StartAngle, EndAngle, isClockwise)
so a reason your definition isn't working is because you're setting the start and end angles both to the same thing.
There is an example here, and below is my example:
var scene = new THREE.Scene();
var material = new THREE.LineBasicMaterial({color:0x000000, opacity:1});
var ellipse = new THREE.EllipseCurve(0, 0, 1, 5, 0, 2.0 * Math.PI, false);
var ellipsePath = new THREE.CurvePath();
ellipsePath.add(ellipse);
var ellipseGeometry = ellipsePath.createPointsGeometry(100);
ellipseGeometry.computeTangents();
var line = new THREE.Line(ellipseGeometry, material);
scene.add( line );
Notice: this is not a complete example, you should add the rest code like <script src="js/three.min.js"></script> if you want to view the result.
You can directly set a circle geometry and set its scale as: object.scale.setY(2.5);
This could easily form an oval without using any shape or curve.
Here is a complete working example.
<!doctype html>
<html>
<head>
<title>example</title>
<script src="threejs/build/three.min.js"></script>
<script src="threejs/src/core/Curve.js"></script>
<script src="threejs/examples/js/controls/OrbitControls.js"></script>
</head>
<body>
<script>
var parent, renderer, scene, camera, controls, pivot1, pivot2, pivot3;
init();
animate();
function init() {
// info
info = document.createElement( 'div' );
info.style.position = 'absolute';
info.style.top = '30px';
info.style.width = '100%';
info.style.textAlign = 'center';
info.style.color = '#fff';
info.style.fontWeight = 'bold';
info.style.backgroundColor = 'transparent';
info.style.zIndex = '1';
info.style.fontFamily = 'Monospace';
info.innerHTML = 'Drag your cursor to rotate camera';
document.body.appendChild( info );
// renderer
renderer = new THREE.CanvasRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.physicallyBasedShading = true;
document.body.appendChild( renderer.domElement );
// scene
scene = new THREE.Scene();
// camera
camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 0.1, 100 );
camera.position.set( 20, 20, 20 );
// controls
controls = new THREE.OrbitControls( camera );
// axes
scene.add( new THREE.AxisHelper( 20 ) );
var material = new THREE.LineBasicMaterial({color:0x000000, opacity:1});
var ellipse = new THREE.EllipseCurve(0, 0, 1, 4, 0, 2.0 * Math.PI, false);
var ellipsePath = new THREE.CurvePath();
ellipsePath.add(ellipse);
var ellipseGeometry = ellipsePath.createPointsGeometry(100);
ellipseGeometry.computeTangents();
var line = new THREE.Line(ellipseGeometry, material);
scene.add( line );
}
function animate() {
requestAnimationFrame( animate );
controls.update();
renderer.render( scene, camera );
}
</script>
</body>
</html>