Three.js渲染深度冲突(Z-Fighting)问题

目录

一、前言

二、解决方法

三、总结


一、前言

Z-Fighting就是深度冲突,当两个模型面非常紧密的平行排列在一起时通常会发生这种情况,该问题是由于深度缓冲没有足够的精度来决定哪个在前面,而导致其不断切换前后顺序,从而产生了我们眼中的闪烁。

二、解决方法

查找网上的资料,解决该问题主要有四种方法:1.开启对数深度缓存;2.调整合适的near、far值;3.手动设置渲染顺序;4.设置多边形偏移。其中方法1、2只在模型初始化时生效,对模型旋转依然会出现闪烁问题。

1.开启对数深度缓存,缓冲级别越多,冲突概率相应也越低,开启这个会影响一定的性能。

renderer = new THREE.WebGLRenderer( { logarithmicDepthBuffer: true } );
//logarithmicDepthBuffer 
//- 是否使用对数深度缓存。如果要在单个场景中处理巨大的比例差异,就有必要使用。 默认是false。

2.调整摄像机近裁剪面和远裁剪面之间的距离。这可以通过调整摄像机的 nearfar 属性来实现。将 near 属性设置为较小值,将 far 属性设置为较大值,可以扩大深度缓冲区域的范围,减少 Z-fighting 的可能性。

const camera = new THREE.PerspectiveCamera(45, width / height, 0.1, 5000)

3.手动设置物体的渲染顺序(renderOrder)。

/**
*前面黄色的平面为plane
*/
plane.renderOrder  = 2

<!--需要注意的是,对于多个物体之间的渲染顺序,需要根据实际情况来设置。如果两个物体的深度差距很大,那么`renderOrder`属性的设置可能不会产生明显的效果。在这种情况下,需要使用更高级别的技术来解决z-fighting问题。-->

4.使用多边形偏移。

/**
*前面黄色的平面为plane
*/
//开启多边形偏移
plane.polygonOffset = true 
//当两个参数都为负值(深度减小)时,网格将被拉向摄影机(因此,位于前面)。
//当两个参数都为正值(增加深度)时,网格将被推离摄影机(因此,被推到后面)。
plane.polygonOffsetFactor = 0.75
plane.polygonOffsetUnits = 4.0

三、总结

开启对数深度缓存与调整相机nearfar只是降低深度冲突的可能性,推荐使用多边形偏移来处理由深度冲突导致的闪烁问题。

猜你喜欢

转载自blog.csdn.net/qq_52013792/article/details/129355237