2

Another new project for work has pushed me into the relm of ThreeJS (the webGL library being used by our project). In the process of learning, I've been trying to modify this example:

Example by Threehouse Blog

I've created an octahedron from vertices and faces. This was practice because the object I'm going to have to render in the end is much more complex, and I wanted to make sure I understood how to set-up vertices and faces.

However, once I modified the example, I have no lighting and the polyhedron is completely black! I've tried several solutions, but none of them seem to be working:

Setting the color in the mesh

Setting individual face colors

I'm a bit stumped :( Here's the current code:

    <!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>G Beam Class Test</title>
    </head>
    <body>
        <script type="text/javascript" src="js/three.min.js"></script>
        <script type="text/javascript" src="js/OrbitControls.js"></script>
        <script>
            var scene, camera, renderer;
            var gbeam;

            init();
            animate();

            // initiate the graphics
            function init() {
                // Create the scene and set the scene size.
                scene = new THREE.Scene();
                var WIDTH = window.innerWidth,
                    HEIGHT = window.innerHeight - 50;

                // Create a renderer and add it to the DOM.
                renderer = new THREE.WebGLRenderer({antialias:true});
                renderer.setSize(WIDTH, HEIGHT);
                document.body.appendChild(renderer.domElement);

                // Create a camera, zoom it out from the model a bit, and add it to the scene.
                camera = new THREE.PerspectiveCamera(45, WIDTH / HEIGHT, 0.1, 10000);
                camera.position.set(0,6,0);
                scene.add(camera);

                // Create an event listener that resizes the renderer with the browser window.
                window.addEventListener('resize', function() {
                  var WIDTH = window.innerWidth,
                      HEIGHT = window.innerHeight;
                  renderer.setSize(WIDTH, HEIGHT);
                  camera.aspect = WIDTH / HEIGHT;
                  camera.updateProjectionMatrix();
                });

                // Set the background color of the scene.
                renderer.setClearColorHex(0xffffff, 1);

                // Create a light, set its position, and add it to the scene.
                var directionalLight = new THREE.DirectionalLight(0xffffff);
                directionalLight.position.set(1, 1, 1).normalize();
                scene.add(directionalLight);

                // create vertecies
                var vertices = [
                    new THREE.Vector3(0, 0, 2),
                    new THREE.Vector3(1, 0, 0),
                    new THREE.Vector3(0, 1, 0),
                    new THREE.Vector3(-1, 0, 0),
                    new THREE.Vector3(0, -1, 0),
                    new THREE.Vector3(0, 0, -2)
                ];

                var faces = [
                    new THREE.Face3(0, 1, 2),
                    new THREE.Face3(0, 2, 3),
                    new THREE.Face3(0, 3, 4),
                    new THREE.Face3(0, 1, 4),

                    new THREE.Face3(5, 1, 2),
                    new THREE.Face3(5, 2, 3),
                    new THREE.Face3(5, 3, 4),
                    new THREE.Face3(5, 1, 4)
                ];


                // create the geometry
                var geometry = new THREE.Geometry();
                geometry.vertices = vertices;
                geometry.faces = faces;

                // compute normals.
                geometry.computeVertexNormals();
                geometry.computeFaceNormals();



                // Build the mesh
                var material = new THREE.MeshLambertMaterial({color: 'blue'});
                material.side = THREE.DoubleSide;
                var mesh = new THREE.Mesh(geometry, material);
                mesh.rotation.x = Math.PI * 0.1;
                //
                scene.add(mesh);

                // Add OrbitControls so that we can pan around with the mouse.
                controls = new THREE.OrbitControls(camera, renderer.domElement);
            };

            // Renders the scene and updates the render as needed.
            function animate() {
                // Read more about requestAnimationFrame at http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/
                requestAnimationFrame(animate);

                // Render the scene.
                renderer.render(scene, camera);
                controls.update();
            }
        </script>
    </body>
</html>
Community
  • 1
  • 1
Frank
  • 153
  • 12
  • One thing to note is that your camera far plane is at 20000. For the coordinates of your scene it should be close to 1000. 20000 is huge for any scene anyway. – gaitat Aug 26 '14 at 18:40
  • Thanks, I've adjusted it a bit. I honestly think with the final product this could be even smaller. The entire object I'll be rendering will occur relatively close to the origin, and I'll have to be zoomed in a bit to get all of it's detail anyway. – Frank Aug 27 '14 at 10:53
  • You have a lot of problems. [Here is a fiddle](http://jsfiddle.net/mLgyesjd/) showing your work. I modified it to some extent to get you started. You need to specify each of your faces with vertices in counterclockwise winding order. That is your job. :-) – WestLangley Aug 28 '14 at 14:35
  • Wow, thanks a bunch! This is great information and should keep me working for the next day or two :) I'll post an update once I get more working. – Frank Aug 28 '14 at 15:28
  • If you want to direct a comment to a particular user, you must use the `@username` keyword, otherwise the user may not be alerted to your comment. – WestLangley Aug 28 '14 at 16:43
  • @WestLangley Thanks for the help! I've updated [the fiddle](http://jsfiddle.net/mLgyesjd/1/) with my changes, thanks for all your help! – Frank Aug 28 '14 at 16:48

1 Answers1

1

You need to compute the geometry normals for the lighting to work.

geometry.computeFaceNormals();
geometry.computeVertexNormals();
WestLangley
  • 102,557
  • 10
  • 276
  • 276
mrdoob
  • 19,334
  • 4
  • 63
  • 62
  • I've tried adding these two calculations just after adding the faces and vertices to the geometry. Is there something else I'm missing? I'm still getting a solid black object with no lighting :( – Frank Aug 27 '14 at 10:54
  • Can you do a jsfiddle for it? – mrdoob Aug 27 '14 at 19:18
  • I'm having trouble getting the javascript to work in Fiddle. Here's the link: http://jsfiddle.net/abxp4zsf/2/ , and I'm going to update my original post with the full code, so if anyone can help me set-up the fiddle that would be awesome as well. – Frank Aug 28 '14 at 12:07
  • Another update: Changing the material to a MeshBasicMaterial allows the color to show up, but then the lighting won't work (since it only works on Lambert and Phong materials). – Frank Aug 28 '14 at 13:13