I have a scene with one mesh with PNG textures. I taken PointLight code from ThreeJS example and added to my project:
var intensity = 15;
var pointLight = new THREE.PointLight( color, intensity, 20 );
pointLight.castShadow = true;
pointLight.shadow.camera.near = 1;
pointLight.shadow.camera.far = 60;
pointLight.shadow.bias = - 0.005;
But I not see light and shadows on my mesh:
I created a codepen for reproduce this case
How I can resolve this issue?
There were multiple problems with your pen:
You have to tell the renderer to globally enable shadow maps like so:
renderer.shadowMap.enabled = true
You have to tell the extruded shape to receive shadows:
mesh.receiveShadow = true;
The extruded shaped used MeshBasicMaterial in your pen. This is an unlit material which means it does not react on lights. The codepen below now uses MeshPhongMaterial. You might want to consider to add an ambient or hemisphere light so all parts of your mesh are lit.
Codepen: https://codepen.io/anon/pen/vPPJxW?editors=1010
three.js R102
While rotating camera, lens flare has some rotation based on camera angle, please see this fiddle: http://jsfiddle.net/e4kf3u7t/1/
I want to avoid that, making lens flare always facing camera without rotation, like Sprite behavior: http://jsfiddle.net/e4kf3u7t/3/
Sample code:
var flareColor = new THREE.Color( 0xffffff );
var lensFlare = new THREE.LensFlare( textureFlare0, 200, 0.0, THREE.NormalBlending, flareColor );
lensFlare.position.y = 100;
lensFlare.position.z = 200;
scene.add(lensFlare);
The reason why I want to use Lensflare instead of Sprite is as you can see in fiddle, lens flare disappearing when it center hiding behind another geometry, Sprite doesn't act like that.
when I set a point light at a THREE.BoxGeometry object it looks like this:
THREE.BoxGeometry with point light
var light = new THREE.PointLight (0xffffff, 1, 100);
light.position.set (10, 10, 10);
scene.add (light);
var geometry = new THREE.BoxGeometry (1, 1, 1);
var material = new THREE.MeshPhongMaterial ();
var cube = new THREE.Mesh (geometry, material);
scene.add (cube);
When I now set a point light at a THREE.PolyhedronGeometry object it looks like this:
THREE.PolyhedronGeometry with point light
var light = new THREE.PointLight (0xffffff, 1, 100);
light.position.set (10, 10, 10);
scene.add (light);
var geometry = new THREE.PolyhedronGeometry (vertices, faces, 1, 0);
var vertices = [-1,-1,-1,1,-1,-1,1,1,-1,-1,1,-1,-1,-1,1,1,-1,1,1,1,1,-1,1,1];
var faces = [2,1,0,0,3,2,0,4,7,7,3,0,0,1,5,5,4,0,1,2,6,6,5,1,2,3,7,7,6,2,4,5,6,6,7,4];
var material = new THREE.MeshPhongMaterial ();
var cube = new THREE.Mesh (geometry, material);
scene.add (cube);
I want to know, where this behaviour comes from and how I can manage to make polyhedrons' faces behave as nice as boxs?
I read that it might be related to geometry.computeFaceNormals().
So I tried it out, but it doesn't make any difference.
when something is different with how light behaves on a surface, first candidates to look at are normals
this is true for the box face
boxGeometry.faces[i].normal.equals(boxGeometry.faces[i].vertexNormals[j]);//true
so box has only simple normal for each face
the polyhedron has different face normal from the vertex normals
polyhedronGeo.faces[i].normal.equals(polyhedronGeo.faces[i].vertexNormals[j]);//not true
and some of the vertex normals are not equal among each other
polyhedronGeo.faces[i].vertexNormals[j].equals(polyhedronGeo.faces[i].vertexNormals[k]);
//not true for some j,k
that is why the light looks ~shadowy - normal is interpolated for the shader from vertexNormals
to modify the polyhedron to look like box just change the vertex notmals to match the face normal
as for
geometry.computeFaceNormals();
it will only compute the face normals, not the vertexNormals
there is another function
geometry.computeVertexNormals();
but that would create vertex normals as are in polyhedron
Thanks Derte. Your reflection got me closer to the point. So with advanced keywords I found this: https://github.com/mrdoob/three.js/issues/1982
The answer to my question is this line, flattening shading for "free forms":
material.shading = THREE.FlatShading;
I've done a terrain using planegeometry object. I set a vertexes' y coordinate to bump my terrain. Then I added a directional light to my scene and see that there is no shadowing of the "hills" etc.
I added also a sphere and noticed that there is also no shadow on this terrain.
var light = new THREE.DirectionalLight(0xffffff, 1);
light.castShadow = true;
light.shadowCameraVisible = true;
light.position.set(-300, 120, -200); // CHANGED
scene.add(light);
scene.add( new THREE.DirectionalLightHelper(light, 0.2) );
Directional light with sphere above the terrain
But when I replaced directional light by a spotlight I've seen shadowing on a terrain that I want to have.
var slight = new THREE.SpotLight(0xffffff,1);
slight.position.set(-100,60,100);
slight.shadowCameraVisible = true;
scene.add(slight);
scene.add(new THREE.SpotLightHelper(slight, 0.5));
Spotlight with terrain
So the questions are:
how can I do a light that looks like sunshine so the terrain will be not plane color but depend on light? (in future it will be a part of a real city)
what should I do to see the objects' shadows on the terrain? (from fiddle example: sphere's shadow)
Thanks
You are modifying the vertices of your terrain. When you do so, you have to also modify the vertex normals. One way to do that is like so:
geometry.computeVertexNormals();
To create shadows you must enable them.
renderer.shadowMap.enabled = true;
three.js r.130
I am creating a scene & have used a boolean function to cut out holes in my wall. However the lighting reveals that the resultant shapes have messed up faces. I want the surface to look like one solid piece, rather than fragmented and displaying lighting backwards. Does anyone know what could be going wrong with my geometry?
The code that booleans objects is as follows:
//boolean subtract two shapes, convert meshes to bsps, subtract, then convert back to mesh
var booleanSubtract = function (Mesh1, Mesh2, material) {
//Mesh1 conversion
var mesh1BSP = new ThreeBSP( Mesh1 );
//Mesh2 conversion
var mesh2BSP = new ThreeBSP( Mesh2 );
var subtract_bsp = mesh1BSP.subtract( mesh2BSP );
var result = subtract_bsp.toMesh( material );
result.geometry.computeVertexNormals();
return result;
};
I have two lights in the scene:
var light = new THREE.DirectionalLight( 0xffffff, 0.75 );
light.position.set( 0, 0, 1 );
scene.add( light );
//create a point light
var pointLight = new THREE.PointLight(0xFFFFFF);
// set its position
pointLight.position.x = 10;
pointLight.position.y = 50;
pointLight.position.z = 130;
// add to the scene
scene.add(pointLight);
EDIT: Using WestLangley's suggestion, I was able to partially fix the wall rendering. And by using material.wireframe=true; I can see that after the boolean operation my wall faces are not merged. Is there a way to merge them?
Your problems are due to two issues.
First, you should be using FlatShading.
Second, as explained in this stackoverflow post, MeshLambert material only calculates the lighting at each vertex, and interpolates the color across each face. MeshPhongMaterial calculates the color at each texel.
You need to use MeshPhongMaterial to avoid the lighting artifacts you are seeing.
three.js r.68