ThreeJS中窄面3D物体开启接收阴影后出现纹理伪影问题
ThreeJS窄面物体开启receiveShadow后出现伪影的解决办法
问题现象
使用尺寸为(0.02, 0.15, 0.35)的BoxGeometry构建Mesh,开启receiveShadow后表面出现类似重复纹理的不良伪影;关闭该属性时显示正常。场景采用AmbientLight+DirectionalLight照明,方向光开启了castShadow。
核心原因
极薄的几何体在阴影接收计算时,受限于深度缓冲区的精度,容易出现**阴影痤疮(Shadow Acne)**或纹理化伪影。当物体某一面的厚度远小于其他维度,且与光源角度特殊时,深度值的计算误差会被放大,导致伪影出现。
解决方案
1. 修正属性拼写错误
代码中receiveshadow和castshadow为小写,不符合ThreeJS驼峰式命名规范,会导致阴影属性未正确生效,先修正:
mesh.receiveShadow = true; mesh.castShadow = true;
2. 优化方向光阴影相机参数
缩小阴影相机的视锥体范围,避免因视锥体过大导致深度精度不足:
directionalLight.shadow.camera.near = 0.1; directionalLight.shadow.camera.far = 50; // 根据场景物体尺寸调整相机边界,确保包裹目标物体 directionalLight.shadow.camera.left = -5; directionalLight.shadow.camera.right = 5; directionalLight.shadow.camera.top = 5; directionalLight.shadow.camera.bottom = -5; // 更新投影矩阵使参数生效 directionalLight.shadow.camera.updateProjectionMatrix();
3. 调整阴影偏移参数
通过阴影偏移解决深度冲突,微调bias和normalBias值:
// 负bias减少阴影 acne,值需根据场景微调 directionalLight.shadow.bias = -0.0001; // normalBias针对倾斜表面的阴影冲突 directionalLight.shadow.normalBias = 0.01;
4. 提升阴影贴图分辨率
增加阴影贴图尺寸,提高阴影计算精度:
directionalLight.shadow.mapSize.width = 2048; directionalLight.shadow.mapSize.height = 2048;
5. 增加几何体细分
给薄面维度增加细分,让顶点分布更均匀,辅助阴影计算:
// 第4-6个参数对应三个维度的细分,给薄面(第一个维度0.02)增加细分 let box = new THREE.BoxGeometry(0.02, 0.15, 0.35, 2, 1, 1);
总结
优先修正属性拼写错误,再结合阴影相机参数、偏移值和贴图分辨率的调整,基本可以解决窄面物体的阴影伪影问题。若仍有残留,可进一步微调细分数量和阴影偏移参数。
内容的提问来源于stack exchange,提问作者Reza Aalaei
相关产品推荐
相关产品推荐

