Skip to content

一、光照阴影实时计算

在具有方向光源的作用下,物体会形成阴影投影效果。 light-4

1. 平行光投影计算

  • three.ts物体投影模拟计算主要设置三部分,一个是设置产生投影的模型对象, 一个是设置接收投影效果的模型,最后一个是光源对象本身的设置,光源如何产生投影。
    javascript
      const geometry = new THREE.BoxGeometry(40, 100, 40);
      const material = new THREE.MeshLambertMaterial({
          color: 0x0000ff
      });
      const mesh = new THREE.Mesh(geometry, material);
      // mesh.position.set(0,0,0)
      scene.add(mesh);
      // 设置产生投影的网格模型
      mesh.castShadow = true;
      
      //创建一个平面几何体作为投影面
      const planeGeometry = new THREE.PlaneGeometry(300, 200);
      const planeMaterial = new THREE.MeshLambertMaterial({
          color: 0x999999
      });
      // 平面网格模型作为投影面
      const planeMesh = new THREE.Mesh(planeGeometry, planeMaterial);
      scene.add(planeMesh); //网格模型添加到场景中
      planeMesh.rotateX(-Math.PI / 2); //旋转网格模型
      planeMesh.position.y = -50; //设置网格模型y坐标
      // 设置接收阴影的投影面
      planeMesh.receiveShadow = true;
      // 方向光
      const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
      // 设置光源位置
      directionalLight.position.set(60, 100, 40);
      scene.add(directionalLight);
      // 设置用于计算阴影的光源对象
      directionalLight.castShadow = true;
      // 设置计算阴影的区域,最好刚好紧密包围在对象周围
      // 计算阴影的区域过大:模糊  过小:看不到或显示不完整
      directionalLight.shadow.camera.near = 0.5;
      directionalLight.shadow.camera.far = 300;
      directionalLight.shadow.camera.left = -50;
      directionalLight.shadow.camera.right = 50;
      directionalLight.shadow.camera.top = 200;
      directionalLight.shadow.camera.bottom = -100;
      // 设置mapSize属性可以使阴影更清晰,不那么模糊
      // directionalLight.shadow.mapSize.set(1024,1024)
      console.log(directionalLight.shadow.camera);

2. 聚光光源投影计算

  • 聚光光源的设置
    javascript
    // 聚光光源
    const spotLight = new THREE.SpotLight(0xffffff);
    // 设置聚光光源位置
    spotLight.position.set(50, 90, 50);
    // 设置聚光光源发散角度
    spotLight.angle = Math.PI /6
    scene.add(spotLight); //光对象添加到scene场景中
    // 设置用于计算阴影的光源对象
    spotLight.castShadow = true;
    // 设置计算阴影的区域,注意包裹对象的周围
    spotLight.shadow.camera.near = 1;
    spotLight.shadow.camera.far = 300;
    spotLight.shadow.camera.fov = 20;

3. 模型.castShadow属性

  • .castShadow属性值是布尔值,默认false,用来设置一个模型对象是否在光照下产生投影效果。 具体查看three.ts文档Object3D
    javascript
      // 设置产生投影的网格模型
      mesh.castShadow = true;

4. .receiveShadow属性

  • .receiveShadow属性值是布尔值,默认false,用来设置一个模型对象是否在光照下接受其它模型的投影效果。 具体查看three.ts文档Object3D
    javascript
      // 设置网格模型planeMesh接收其它模型的阴影(planeMesh作为投影面使用)
      planeMesh.receiveShadow = true;

5. 光源.castShadow属性

  • 如果属性设置为true, 光源将投射动态阴影。 警告: 这需要很多计算资源,需要调整以使阴影看起来正确. 更多细节,查看DirectionalLightShadow。 默认值false
    javascript
      // 设置用于计算阴影的光源对象
      directionalLight.castShadow = true;
      // spotLight.castShadow = true;

6. 光源.shadow属性

  • 平行光DirectionalLight.shadow属性值是平行光阴影对象DirectionalLightShadow, 聚光源SpotLight.shadow属性值是聚光源阴影对象SpotLightShadow。 关于DirectionalLightShadowSpotLightShadow两个类的具体介绍可以参考three.ts文档 Lights / Shadows分类,

7. 阴影对象基类LightShadow

  • 平行光阴影对象DirectionalLightShadow和聚光源阴影对象SpotLightShadow两个类的基类是LightShadow
  • LightShadow属性.camera
    • 观察光源的相机对象. 从光的角度来看,以相机对象的观察位置和方向来判断,其他物体背后的物体将处于阴影中。
    javascript
    // 聚光源设置
    spotLight.shadow.camera.near = 1;
    spotLight.shadow.camera.far = 300;
    spotLight.shadow.camera.fov = 20;
  • LightShadow属性.mapSize
    • 定义阴影纹理贴图宽高尺寸的一个二维向量Vector2
    • 较高的值会以计算时间为代价提供更好的阴影质量。宽高分量值必须是2的幂, 直到给定设备的WebGLRenderer.capabilities.maxTextureSize, 尽管宽度和高度不必相同 (例如,(512, 1024)是有效的)。 默认值为 ( 512, 512 ).
      javascript
        directionalLight.shadow.mapSize.set(1024,1024)
  • LightShadow属性.map
    • 该属性的值是WebGL渲染目标对象WebGLRenderTarget,使用内置摄像头生成的深度图; 超出像素深度的位置在阴影中,在渲染期间内部计算。

Released under the MIT License.