5

I'm currently learning webGL and three.js. So, for test reasons, I tried to create a plane geometry and two cube geometries and a point light:

function initLights () {
    var c = context;

    var pointLight = new THREE.PointLight( 0xffffff, 1, 100 );
    pointLight.position.set( 10, 10, 10 );

    c.scene.add(pointLight);
}

function initObjects () {
    var c = context;

    /**
     * Defining the materials
     */

    var lambertRedMaterial = new THREE.MeshLambertMaterial({
            color  : 0xff0000
            , side : THREE.DoubleSide
        });

    var lambertWhiteMaterial = new THREE.MeshLambertMaterial({
            color     : 0xffffff
            , side    : THREE.DoubleSide
        });

    /**
     * Defining the floor
     */
    var floorGeometry = new THREE.Geometry();

    floorGeometry.vertices.push(new THREE.Vector3(-5.0, 0.0, -5.0));
    floorGeometry.vertices.push(new THREE.Vector3( 5.0, 0.0, -5.0));
    floorGeometry.vertices.push(new THREE.Vector3( 5.0, 0.0,  5.0));
    floorGeometry.vertices.push(new THREE.Vector3(-5.0, 0.0,  5.0));
    floorGeometry.faces.push(new THREE.Face3(2, 1, 0));
    floorGeometry.faces.push(new THREE.Face3(3, 2, 0));


    var floorMesh = new THREE.Mesh(floorGeometry, lambertWhiteMaterial);
    floorMesh.position.set(0.0, 0.0, 0.0);

    /**
     * Defining a cube
     */
    var cubeGeometry1 = new THREE.CubeGeometry(2.0,0.25,1);
    var cube1 = new THREE.Mesh( cubeGeometry1, lambertRedMaterial );
    cube1.position.set(0.0, 1.0, 0.0);

    var cubeGeometry2 = new THREE.CubeGeometry(2.0,0.25,1);
    var cube2 = new THREE.Mesh( cubeGeometry2, lambertRedMaterial );
    cube2.position.set(0.0, 1.35, 0.0);

    c.scene.add(floorMesh);
    c.scene.add(cube1);
    c.scene.add(cube2);
}

The context with a camera and the scene was defined before. The weird thing is, that the cubes are displayed correctly, but the plane is not displayed.

When I set the y-position of the plane to 1.0, then I can see, that it intersects with the lower cube. Also, it's displayed when I use MeshBasicMaterial, but I want to use MeshLambertMaterial for lighting reasons.

Has anybody an idea, if I forgot something, or what the problem could be?

Many thanks in advance.

viggity
  • 14,639
  • 7
  • 79
  • 91
  • As a start, call `geometry.computeFaceNormals();`. Then call `scene.add( new THREE.FaceNormalsHelper( floorMesh );` – WestLangley Feb 13 '14 at 18:54
  • Yeah, great! The geometry.computeFaceNormals(); did the trick! Can you explain me, why I need to call this? scene.add( new THREE.FaceNormalsHelper( floorMesh ); is not necessary. If I put it into my code, it draws a yellow line. I guess the line is the representation of the normalized orthogonal vector. – Benjamin Groener Feb 13 '14 at 19:22

1 Answers1

4

MeshLambertMaterial requires face normals or vertex normals for the lighting calculation.

Face normals are used for "flat shading" and vertex normals are used for "smooth shading".

You can compute face normals by calling geometry.computeFaceNormals();. For vertex normals, you can call geometry.computeVertexNormals();.

For visual cues, use the three.js helpers, such as this one:

scene.add( new THREE.FaceNormalsHelper( mesh ) );

Also, if you are just learning, the advice in this answer may be helpful to you.

three.js r.65

Community
  • 1
  • 1
WestLangley
  • 92,014
  • 9
  • 230
  • 236
  • What did you mean, by saying "If you are just learning ..." Would you recommend a different way, for later projects? – Benjamin Groener Feb 13 '14 at 21:15
  • You said in your first sentence that you were learning WebGL and three.js, so I thought the recommendations in the other answer would be helpful to you. :-) I rephrased my post. – WestLangley Feb 13 '14 at 21:43
  • Yep, I read this question and answer already. Thanks for the tips, they are really helpful! :-) – Benjamin Groener Feb 13 '14 at 22:10