Three.js_解决谍影锯齿闪烁重影模型的方法
renderer = new THREE.WebGLRenderer({
antialias: true,
logarithmicDepthBuffer: true,
});
logarithmicDepthBuffer, 官方解释: 是否使用对数深度缓存。如果要在单个场景中处理巨大的比例差异,就有必要使用, 默认是false。 使用了会带来额外的开销, 但是效果会变好.
渲染器渲染时有个特点, 距离越远的物体精度越低, 因此, 在远处, 多个材质可能集中在一个像素点上, 产生各种不正常现象, 这也叫z-fight.
由 logarithmicDepthBuffer 引起的模型显示不完整的问题
开启 logarithmicDepthBuffer 属性时,若单个模型过长时,会遇到某些视角模型显示不完整的问题,如下图所示:
此时需要关闭logarithmicDepthBuffer以修复
需要注意,该问题在微信小程序里,微信开发者工具模型显示是正常的完整的,到手机上看是不完整的。容易误判为近裁剪面的问题
关于深度冲突z-fighting:
创建两个重合的矩形平面Mesh,通过浏览器预览,当你旋转三维场景的时候,你会发现模型渲染的时候产生闪烁。
这种现象,主要是两个Mesh重合,电脑GPU分不清谁在前谁在后,这种现象,可以称为深度冲突Z-fighting
适当偏移,解决深度冲突,偏移尺寸相对模型尺寸比较小,视觉上两个平面近似还是重合效果。
所以在三维软件中建模的的时候,尽量避免两个Mesh完全重合,可以考虑适当偏移一定的距离。
当两个面间隙很小,也可能出现深度冲突。从纯理论的角度,你能分清0和0.0000…0000001的大小,但是实际上,电脑GPU精度是有限的
透视投影相机对距离影响(深度冲突):
相机近距离观察没有深度冲突,拉远看的话可能出现深度冲突
透视投影相机的投影规律是远小近大,和人眼观察世界一样,模型距离相机越远,模型渲染的效果越小,两个mesh之间的间距同样也会变小。当两个Mesh和相机距离远到一定程度,两个模型的距离也会无限接近0
当一个三维场景中有一些面距离比较近,有深度冲突,你可以尝试设置webgl渲染器设置对数深度缓冲区logarithmicDepthBuffer: true来优化或解决。logarithmicDepthBuffer: true作用简单来说,就是两个面间距比较小的时候,让threejs更容易区分两个面,谁在前,谁在后。有一点要注意,当两个面间隙过小,或者重合,你设置webgl渲染器对数深度缓冲区也是无效的。