返回介绍

Three.js 光照阴影实时计算

发布于 2021-07-10 20:14:16 字数 3989 浏览 1050 评论 0 收藏 0

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

平行光投影计算代码

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。关于DirectionalLightShadowSpotLightShadow两个类的具体介绍可以参考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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文