在 three 中灯光,相机,投影这三个是配合使用的,相机决定投影的设置方式,例如正交相机就与透视相机的阴影设置方式不同,而灯光决定投影的位置与强度
在 three 中要启要阴影首先要在渲染上设置下列属性
- renderer.shadowMap.enabled = true; 用于在 three 中启用阴影,默认是不启用的
- renderer.shadowMap.type = THREE.PCFSoftShadowMap 阴影类型有四种 THREE.BasicShadowMap 性能最好但是锯齿明显,THREE.PCFShadowMap 性能与锯齿适中, THREE.PCFSoftShadowMap 性能较低,阴影更柔和,THREE.VSMShadowMap 性能更次,阴影更柔和
LightShadow 这个是阴影的基类 在启用阴影后所有产生阴影的灯光都会继承这个基类,这个有十二个属性,七个方法
- autoUpdate 自动更新阴影 默认为 true;
- camera 相机属性,决定了在指定范围内是否产生阴影 例 light.shadow.camera.near = 0.5;light.shadow.camera.far = 500; 这个可以设置物体的阴影程现在距离最近 0.5 与最远 500 处显示阴影
- Bias 偏移量 light.shadow.bias = -0.0001;// 可能会使阴影靠近物体表面 light.shadow.bias = -0.01; // 可能会使阴影离物体表面较远
- blurSamples 阴影的模似质量
- intensity 阴影的强度 有效的值范围是 0 - 1
- 值越大阴影越深
- map 只读属性 阴影贴图 获取阴影效果图
- mapPass 属性难解 内部使用
- mapSize 这个属性决定了阴影的质量 这个有width,height 两个属性决定了阴影的分辨率
- matrix 只读属性,查看和调试距阵属性
- needsUpdate 用来标记是否需要新阴影 布尔属性
- normalBias 设置正常偏移量,减少自阴问题 取值 0 - 1
- radius 阴影的模糊半径
- getFrameExtents 方法 内部使用
- updateMatrices 方法 更新阴影矩阵 可以与 autoUpdate 配合 定义何时更新阴影
- getFrustum 方法 创建一个视锥体对象用于可视化 使用示例
// 创建一个点光源
const pointLight = new THREE.PointLight(0xffffff, 1);
pointLight.castShadow = true;
scene.add(pointLight);
// 创建一个视锥体对象用于可视化
const frustum = pointLight.shadow.getFrustum();
// 创建一个几何体(如立方体)来可视化视锥体
const geometry = new THREE.BoxGeometry(
frustum.right - frustum.left,
frustum.top - frustum.bottom,
frustum.far - frustum.near
);
const material = new THREE.MeshBasicMaterial({ color: 0xff0000, wireframe: true });
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
// 渲染场景
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
animate();
- getViewportCount 方法 就是获取有多少个相机观测
- copy 方法 有一个参数 类型为 LightShadow 将参数的阴影设置复制到当前光源
- clone 方法 克隆当前的灯光实例
- toJSON 方法 将阴影转换为 JSON 也可以通过 fromJson 将JSON 恢复成阴影设置
// 创建一个点光源
const pointLight = new THREE.PointLight(0xffffff, 1);
pointLight.castShadow = true;
// 配置光源的阴影设置
pointLight.shadow.mapSize.width = 2048;
pointLight.shadow.mapSize.height = 2048;
pointLight.shadow.camera.near = 0.5;
pointLight.shadow.camera.far = 500;
pointLight.shadow.bias = -0.001;
// 将阴影设置转换为 JSON 格式
const shadowJSON = pointLight.shadow.toJSON();
console.log(shadowJSON);
// 从 JSON 数据恢复阴影设置
const restoredShadow = new THREE.PointLightShadow();
restoredShadow.fromJSON(shadowJSON);
// 应用恢复的阴影设置到新的光源
const newPointLight = new THREE.PointLight(0xffffff, 1);
newPointLight.castShadow = true;
newPointLight.shadow = restoredShadow;
PointLightShadow 设置点光源的阴影类 一个属性 一个方法
- isPointLightShadow 判断是否为点光源
- updateMatrices 方法 更新点光源距阵
使用示例
// 创建一个点光源
const pointLight = new THREE.PointLight(0xffffff, 1);
pointLight.castShadow = true;
// 获取点光源的阴影对象
const pointLightShadow = pointLight.shadow;
// 配置阴影设置
pointLightShadow.mapSize.width = 2048;
pointLightShadow.mapSize.height = 2048;
pointLightShadow.camera.near = 0.5;
pointLightShadow.camera.far = 500;
pointLightShadow.bias = -0.001;
// 在需要时手动更新矩阵
pointLightShadow.updateMatrices();
// 将点光源添加到场景中
scene.add(pointLight);
DirectionalLightShadow 两个属性
- camera 相机对象 定义相机投影的范围
- isDirectionalLightShadow 判断当前光是否是平行光
使用示例
// 创建一个方向光源
const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
// 设置光源的阴影
directionalLight.castShadow = true;
// 获取方向光的阴影对象
const directionalLightShadow = directionalLight.shadow;
// 配置阴影设置
directionalLightShadow.mapSize.width = 2048; // 阴影贴图的宽度
directionalLightShadow.mapSize.height = 2048; // 阴影贴图的高度
// 配置阴影相机
const shadowCamera = directionalLightShadow.camera;
shadowCamera.left = -500;
shadowCamera.right = 500;
shadowCamera.top = 500;
shadowCamera.bottom = -500;
shadowCamera.near = 1;
shadowCamera.far = 1000;
// 将方向光源添加到场景中
scene.add(directionalLight);
SpotLightShadow 三个属性
- camera 相机对象 定义相机投影的范围
- focus 改变阴影的聚集程序
- isSpotLightShadow 判断光源是否是取光灯
使用示例
// 创建一个聚光灯
const spotLight = new THREE.SpotLight(0xffffff, 1);
spotLight.castShadow = true;
// 获取聚光灯的阴影对象
const spotLightShadow = spotLight.shadow;
// 配置阴影设置
spotLightShadow.mapSize.width = 2048;
spotLightShadow.mapSize.height = 2048;
// 配置聚光灯的焦距
spotLightShadow.focus = 1; // 默认值,调节焦距可以影响阴影的聚焦效果
// 设置聚光灯的其他属性
spotLight.angle = Math.PI / 6; // 光束的角度
spotLight.penumbra = 0.1; // 光束边缘的模糊程度
spotLight.decay = 2; // 光的衰减程度
// 将聚光灯添加到场景中
scene.add(spotLight);
结语,在灯光使用中以上就是全部内容了,但是还有一些需要注意的部分,例如 新建一个物体 要通过设置物体是否接收阴影 receiveShadow,是否产生阴影 castShadow,还有材质相关 基些材质无法接收灯光。