一、光照阴影实时计算
在具有方向光源的作用下,物体会形成阴影投影效果。
1. 平行光投影计算
three.ts
物体投影模拟计算主要设置三部分,一个是设置产生投影的模型对象, 一个是设置接收投影效果的模型,最后一个是光源对象本身的设置,光源如何产生投影。javascriptconst 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
。 关于DirectionalLightShadow
和SpotLightShadow
两个类的具体介绍可以参考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 ).javascriptdirectionalLight.shadow.mapSize.set(1024,1024)
- 定义阴影纹理贴图宽高尺寸的一个二维向量
LightShadow
属性.map
- 该属性的值是
WebGL
渲染目标对象WebGLRenderTarget
,使用内置摄像头生成的深度图; 超出像素深度的位置在阴影中,在渲染期间内部计算。
- 该属性的值是