【问题标题】:Three.js: Casting shadowsThree.js:投射阴影
【发布时间】:2018-01-04 23:03:20
【问题描述】:

我正在使用 Three.js r88,虽然我尝试按照文档的示例使用 PointLight [docs] 添加阴影,但我一定遗漏了一些东西。这是我的场景:

  /**
  * Generate a scene object with a background color
  **/

  function getScene() {
    var scene = new THREE.Scene();
    scene.background = new THREE.Color(0x000000);
    return scene;
  }

  /**
  * Generate the camera to be used in the scene. Camera args:
  *   [0] field of view: identifies the portion of the scene
  *     visible at any time (in degrees)
  *   [1] aspect ratio: identifies the aspect ratio of the
  *     scene in width/height
  *   [2] near clipping plane: objects closer than the near
  *     clipping plane are culled from the scene
  *   [3] far clipping plane: objects farther than the far
  *     clipping plane are culled from the scene
  **/

  function getCamera() {
    var aspectRatio = window.innerWidth / window.innerHeight;
    var camera = new THREE.PerspectiveCamera(75, aspectRatio, 0.1, 1000);
    camera.position.set(0, 1, -30);
    return camera;
  }

  /**
  * Generate the light to be used in the scene. Light args:
  *   [0]: Hexadecimal color of the light
  *   [1]: Numeric value of the light's strength/intensity
  *   [2]: The distance from the light where the intensity is 0
  * @param {obj} scene: the current scene object
  **/

  function getLight(scene) {
    // SHADOW
    var light = new THREE.PointLight( 0xffffff, 1, 100 );
    light.position.set( 0, 10, 0 );
    light.castShadow = true;            // default false
    scene.add( light );

    var ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
    scene.add(ambientLight);
    return light;
  }

  /**
  * Generate the renderer to be used in the scene
  **/

  function getRenderer() {
    // Create the canvas with a renderer
    var renderer = new THREE.WebGLRenderer({antialias: true});
    // Add support for retina displays
    renderer.setPixelRatio(window.devicePixelRatio);
    // Specify the size of the canvas
    renderer.setSize(window.innerWidth, window.innerHeight);
    // SHADOW
    renderer.shadowMap.enabled = true;
    renderer.shadowMap.type = THREE.PCFSoftShadowMap;
    // Add the canvas to the DOM
    document.body.appendChild(renderer.domElement);
    return renderer;
  }

  /**
  * Generate the controls to be used in the scene
  * @param {obj} camera: the three.js camera for the scene
  * @param {obj} renderer: the three.js renderer for the scene
  **/

  function getControls(camera, renderer) {
    var controls = new THREE.TrackballControls(camera, renderer.domElement);
    controls.zoomSpeed = 0.4;
    controls.panSpeed = 0.4;
    return controls;
  }

  // Render loop
  function render() {
    requestAnimationFrame(render);
    renderer.render(scene, camera);
    controls.update();
  };

  var scene = getScene();
  var camera = getCamera();
  var light = getLight(scene);
  var renderer = getRenderer();
  var controls = getControls(camera, renderer);

  //Create a sphere that cast shadows (but does not receive them)
  var sphereGeometry = new THREE.SphereBufferGeometry( 5, 32, 32 );
  var sphereMaterial = new THREE.MeshPhongMaterial( { color: 0xffffff } );
  var sphere = new THREE.Mesh( sphereGeometry, sphereMaterial );
  sphere.castShadow = true; //default is false
  sphere.receiveShadow = false; //default
  scene.add( sphere );

  //Create a plane that receives shadows (but does not cast them)
  var planeGeometry = new THREE.PlaneGeometry( 50, 20, 32 );
  var planeMaterial = new THREE.MeshPhongMaterial({
    color: 0xffff00, side: THREE.DoubleSide})
  var plane = new THREE.Mesh( planeGeometry, planeMaterial );
  plane.receiveShadow = true;
  scene.add( plane );

  render();
body { margin: 0; }
  canvas { width: 100%; height: 100% }
  <script src='https://cdnjs.cloudflare.com/ajax/libs/three.js/88/three.min.js'></script>
  <script src='https://threejs.org/examples/js/controls/TrackballControls.js'></script>

有谁知道我可以做些什么来渲染阴影?对于其他人可以就这个问题提出的任何建议,我将不胜感激!

【问题讨论】:

    标签: three.js


    【解决方案1】:

    您的点光源与您的飞机位于同一平面上。这会导致阴影计算变为无穷大/NaN。

    将灯光稍微移向相机也会导致正确计算阴影。在下面的 sn-p 中,我将灯光位置的 Z 分量从0 更改为-1,得到了一个阴影。

    /**
      * Generate a scene object with a background color
      **/
    
      function getScene() {
        var scene = new THREE.Scene();
        scene.background = new THREE.Color(0x000000);
        return scene;
      }
    
      /**
      * Generate the camera to be used in the scene. Camera args:
      *   [0] field of view: identifies the portion of the scene
      *     visible at any time (in degrees)
      *   [1] aspect ratio: identifies the aspect ratio of the
      *     scene in width/height
      *   [2] near clipping plane: objects closer than the near
      *     clipping plane are culled from the scene
      *   [3] far clipping plane: objects farther than the far
      *     clipping plane are culled from the scene
      **/
    
      function getCamera() {
        var aspectRatio = window.innerWidth / window.innerHeight;
        var camera = new THREE.PerspectiveCamera(75, aspectRatio, 0.1, 1000);
        camera.position.set(0, 1, -30);
        return camera;
      }
    
      /**
      * Generate the light to be used in the scene. Light args:
      *   [0]: Hexadecimal color of the light
      *   [1]: Numeric value of the light's strength/intensity
      *   [2]: The distance from the light where the intensity is 0
      * @param {obj} scene: the current scene object
      **/
    
      function getLight(scene) {
        // SHADOW
        var light = new THREE.PointLight( 0xffffff, 1, 100 );
        light.position.set( 0, 10, -1 );
        light.castShadow = true;            // default false
        scene.add( light );
    
        var ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
        scene.add(ambientLight);
        return light;
      }
    
      /**
      * Generate the renderer to be used in the scene
      **/
    
      function getRenderer() {
        // Create the canvas with a renderer
        var renderer = new THREE.WebGLRenderer({antialias: true});
        // Add support for retina displays
        renderer.setPixelRatio(window.devicePixelRatio);
        // Specify the size of the canvas
        renderer.setSize(window.innerWidth, window.innerHeight);
        // SHADOW
        renderer.shadowMap.enabled = true;
        renderer.shadowMap.type = THREE.PCFSoftShadowMap;
        // Add the canvas to the DOM
        document.body.appendChild(renderer.domElement);
        return renderer;
      }
    
      /**
      * Generate the controls to be used in the scene
      * @param {obj} camera: the three.js camera for the scene
      * @param {obj} renderer: the three.js renderer for the scene
      **/
    
      function getControls(camera, renderer) {
        var controls = new THREE.TrackballControls(camera, renderer.domElement);
        controls.zoomSpeed = 0.4;
        controls.panSpeed = 0.4;
        return controls;
      }
    
      // Render loop
      function render() {
        requestAnimationFrame(render);
        renderer.render(scene, camera);
        controls.update();
      };
    
      var scene = getScene();
      var camera = getCamera();
      var light = getLight(scene);
      var renderer = getRenderer();
      var controls = getControls(camera, renderer);
    
      //Create a sphere that cast shadows (but does not receive them)
      var sphereGeometry = new THREE.SphereBufferGeometry( 5, 32, 32 );
      var sphereMaterial = new THREE.MeshPhongMaterial( { color: 0xffffff } );
      var sphere = new THREE.Mesh( sphereGeometry, sphereMaterial );
      sphere.castShadow = true; //default is false
      sphere.receiveShadow = false; //default
      scene.add( sphere );
    
      //Create a plane that receives shadows (but does not cast them)
      var planeGeometry = new THREE.PlaneGeometry( 50, 20, 32 );
      var planeMaterial = new THREE.MeshPhongMaterial({
        color: 0xffff00, side: THREE.DoubleSide})
      var plane = new THREE.Mesh( planeGeometry, planeMaterial );
      plane.receiveShadow = true;
      scene.add( plane );
    
      render();
    body { margin: 0; }
      canvas { width: 100%; height: 100% }
    <script src='https://cdnjs.cloudflare.com/ajax/libs/three.js/88/three.min.js'></script>
      <script src='https://threejs.org/examples/js/controls/TrackballControls.js'></script>

    【讨论】:

      猜你喜欢
      • 2016-06-21
      • 1970-01-01
      • 2013-08-03
      • 2017-12-12
      • 1970-01-01
      • 2019-01-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多