2

I'm experimenting with generating terrain with noise functions, but I'm having problems with getting the BufferGeometry mesh to receive any light from PointLight. When setting AmbientLight I can see the BufferGeometry but with only PointLight it does not work. The CubeGeometry next to it works with both types of light. I also want the terrain to receive shadows. Do I need to run some extra method on the mesh? What am I missing here?

https://jsfiddle.net/cbo8fx1s/

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title></title>
    <script src="https://threejs.org/build/three.js"></script>
    <script>
      const scene = new THREE.Scene();
      const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
      camera.position.z = 30;
      const renderer = new THREE.WebGLRenderer({antialias: true});

      // scene.add(new THREE.AmbientLight(0xffffff));

      window.addEventListener('resize', () => {
        camera.aspect = window.innerWidth / window.innerHeight;
        camera.updateProjectionMatrix();
        renderer.setSize(window.innerWidth, window.innerHeight);
      });

      window.addEventListener('load', () => {
        renderer.setSize(window.innerWidth, window.innerHeight);
        document.body.appendChild(renderer.domElement);

        function animate() {
          requestAnimationFrame(animate);
          renderer.render(scene, camera);
        }
        animate();

        createScene();
      });

      function createScene() {
        (() => {
          const geometry = new THREE.BufferGeometry();
          // create a simple square shape. We duplicate the top left and bottom right
          // vertices because each vertex needs to appear once per triangle.
          const vertices = new Float32Array([
            -1.0, -1.0, 1.0,
            1.0, -1.0, 1.0,
            1.0, 1.0, 1.0,

            1.0, 1.0, 1.0,
            -1.0, 1.0, 1.0,
            -1.0, -1.0, 1.0
          ]);

          // itemSize = 3 because there are 3 values (components) per vertex
          geometry.addAttribute('position', new THREE.BufferAttribute(vertices, 3));

          const material = new THREE.MeshStandardMaterial({color: 0xffffff});
          const mesh = new THREE.Mesh(geometry, material);
          mesh.receiveShadow = false;
          scene.add(mesh);
        })();

        (() => {
          const geometry = new THREE.CubeGeometry(10, 8, 3);
          const material = new THREE.MeshStandardMaterial({color: 0xffffff});
          const mesh = new THREE.Mesh(geometry, material);
          mesh.castShadow = true;
          mesh.receiveShadow = false;
          mesh.position.y = 10;
          scene.add(mesh);
        })();

        (() => {
          const light = new THREE.PointLight(0x00ff00);
          light.position.z = 500;
          light.position.y = 500;
          scene.add(light);

          const light2 = new THREE.PointLight(0xff0000);
          light2.position.z = 500;
          light2.position.x = 500;
          scene.add(light2);
        })();
      }
    </script>
    <style>
      body {
        background: #000;
        margin: 0;
        overflow: hidden;
      }
    </style>
  </head>
  <body>
  </body>
</html>
gman
  • 100,619
  • 31
  • 269
  • 393
tirithen
  • 3,219
  • 11
  • 41
  • 65
  • Have a look at this: https://threejs.org/docs/index.html#api/en/lights/shadows/LightShadow. Pay attention to the settings of a renderer and the settings of the shadow of a light. – prisoner849 Sep 22 '18 at 07:51
  • 1
    Looks like you have absolutely no mention of normals, which are needed for lights to work. – pailhead Sep 22 '18 at 09:22

1 Answers1

8

Your geometry has no normals. Without normals, lights have no surface information to shade.

Add:

geometry.addAttribute('position', new THREE.BufferAttribute(vertices, 3));
geometry.computeVertexNormals() //<-- this

In order to have your square show up.

pailhead
  • 5,162
  • 2
  • 25
  • 46
  • Or, instead of adding normals, `material = new THREE.MeshStandardMaterial( { color: 0xffffff, flatShading: true } );` – WestLangley Sep 22 '18 at 14:40
  • While in this case, (triangle soup) the results are going to be the same, using flat shading will look different if you average your normals (by using indexed geometry / shared vertices). A device may be encountered that does not support `dxdf` but maybe not. Hi West, i hope you're doing alright :) – pailhead Sep 22 '18 at 19:14