Three.js 光照阴影实时计算
在具有方向光源的作用下,物体会形成阴影投影效果。
平行光投影计算代码
Three.js物体投影模拟计算主要设置三部分,一个是设置产生投影的模型对象,一个是设置接收投影效果的模型,最后一个是光源对象本身的设置,光源如何产生投影。
var geometry = new THREE.BoxGeometry(40, 100, 40);
var material = new THREE.MeshLambertMaterial({
color: 0x0000ff
});
var mesh = new THREE.Mesh(geometry, material);
// mesh.position.set(0,0,0)
scene.add(mesh);
// 设置产生投影的网格模型
mesh.castShadow = true;
//创建一个平面几何体作为投影面
var planeGeometry = new THREE.PlaneGeometry(300, 200);
var planeMaterial = new THREE.MeshLambertMaterial({
color: 0x999999
});
// 平面网格模型作为投影面
var planeMesh = new THREE.Mesh(planeGeometry, planeMaterial);
scene.add(planeMesh); //网格模型添加到场景中
planeMesh.rotateX(-Math.PI / 2); //旋转网格模型
planeMesh.position.y = -50; //设置网格模型y坐标
// 设置接收阴影的投影面
planeMesh.receiveShadow = true;
// 方向光
var 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);
聚光光源投影计算代码
下面代码是聚光光源的设置,其它部分代码和平行光一样。
// 聚光光源
var 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;
模型.castShadow
属性
.castShadow
属性值是布尔值,默认false,用来设置一个模型对象是否在光照下产生投影效果。具体查看threejs文档Object3D
// 设置产生投影的网格模型
mesh.castShadow = true;
.receiveShadow
属性
.receiveShadow
属性值是布尔值,默认false,用来设置一个模型对象是否在光照下接受其它模型的投影效果。具体查看threejs文档Object3D
// 设置网格模型planeMesh接收其它模型的阴影(planeMesh作为投影面使用)
planeMesh.receiveShadow = true;
光源.castShadow
属性
如果属性设置为 true, 光源将投射动态阴影. 警告: 这需要很多计算资源,需要调整以使阴影看起来正确. 更多细节,查看DirectionalLightShadow. 默认值false.
// 设置用于计算阴影的光源对象
directionalLight.castShadow = true;
// spotLight.castShadow = true;
光源.shadow
属性
平行光DirectionalLight
的.shadow
属性值是平行光阴影对象DirectionalLightShadow
,聚光源SpotLight
的.shadow
属性值是聚光源阴影对象SpotLightShadow
。关于DirectionalLightShadow
和SpotLightShadow
两个类的具体介绍可以参考Three.js文档Lights / Shadows分类,
阴影对象基类LightShadow
平行光阴影对象DirectionalLightShadow
和聚光源阴影对象SpotLightShadow
两个类的基类是LightShadow
LightShadow
属性.camera
观察光源的相机对象. 从光的角度来看,以相机对象的观察位置和方向来判断,其他物体背后的物体将处于阴影中。
// 聚光源设置
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 ).
directionalLight.shadow.mapSize.set(1024,1024)
LightShadow
属性.map
该属性的值是WebGL渲染目标对象WebGLRenderTarget
,使用内置摄像头生成的深度图; 超出像素深度的位置在阴影中。 在渲染期间内部计算。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论