zp1112 / blog

地址
http://issue.suzper.com/
36 stars 3 forks source link

解决threejs中的z-fighting问题 #26

Open zp1112 opened 5 years ago

zp1112 commented 5 years ago

z-fighting

当场景中的两个模型在同一个像素生成的渲染结果对应到一个相同的深度值时,渲染器就不知道该使用哪个模型的渲染结果了,或者说,不知道哪个面在前,哪个面在后,于是便开始“胡作非为”,这次让这个面在前面,下次让那个面在前面,于是模型的重叠部位便不停的闪烁起来。这便是Z-Fighting问题。原文链接

image

遇到的问题

地图texture平面和栅格的深度相同,导致栅格线若隐若现,一会栅格线在上面一会平面在上面。 image

带边框的立方体紧挨的时候,边框重叠导致边框模糊。 image

解决方法

  1. 让各模型渲染结果不要在同一个像素出现相同深度值
  2. 人为设置渲染顺序,这样即使出现相同深度值,也能正确渲染

使用方法1,将地图平面往下平移一个像素,就可以解决问题

rect.position.y =  -1;

但是没法解决第二个问题,紧挨着的立方体无法使用平移或者渲染顺序来解决。

使用 logarithmicDepthBuffer 缓冲

缓冲的级别越多,冲突的概率相应的也就越低,所以,我们可以使用一个精度更高的z缓冲,来代替原有的Z缓冲。对于这个方法,threejs官网已经提供了一个例子webgl_camera_logarithmicdepthbuffer。不过,官网的例子为了演示效果,写得比较复杂,实际上只需要将logarithmicDepthBuffer参数设为true即可:

var renderer = new THREE.WebGLRenderer({ logarithmicDepthBuffer: true });

得到较好的效果 image