Material 缩小时会透光 (three.js r78)

Material shines through when zooming out (three.js r78)

Material 缩小时闪耀 (three.js r78)

当缩小到一定范围时,其他对象后面的对象 material 开始发光。看起来很像人脸重叠时的效果(人脸在同一平面)

为了证明这一点,我制作了 a fiddle

在这个例子中,我绘制了两个细框(厚度为 1 并且框之间有一个空 space 也 1) 所以盒子没有相互接触,但 material 无论如何都会发光。

// geometry with thickness 1
var geometry = new THREE.BoxGeometry(20000, 20000, 1);

此截图演示效果:

此屏幕截图显示两个几何图形之间有一个 space。

缩放时有时出现有时消失(也取决于缩放距离和屏幕大小)。

我尝试使用不同的 material 属性,但我似乎找不到任何 material 设置来防止这种情况发生。

这是一个错误吗?还是 WebGL 限制?还是 3D 图形的一般限制? 还是我遗漏了什么,这实际上是 material 还是渲染器配置错误?

在我的模型中,这种效果确实令人不安且丑陋。我能以某种方式阻止这种情况发生吗?

此问题是由严重限制深度缓冲区精度的错误配置引起的。
OpenGL.org上是这样描述的:

You may have configured your zNear and zFar clipping planes in a way that severely limits your depth buffer precision. Generally, this is caused by a zNear clipping plane value that's too close to 0.0. As the zNear clipping plane is set increasingly closer to 0.0, the effective precision of the depth buffer decreases dramatically. Moving the zFar clipping plane further away from the eye always has a negative impact on depth buffer precision, but it's not one as dramatic as moving the zNear clipping plane.

正确,因为在示例中近裁剪平面值设置为 1
到目前为止,我知道这个问题的两个解决方案。


1) 简单增加相机near值:

// camera
camera = new THREE.PerspectiveCamera(
    45, window.innerWidth / window.innerHeight, 
    500, // <-- Increased near from 1 to 500
    150000
);

此解决方案在 this fiddle

中进行了演示

2) 配置 WebGL 渲染器以使用对数深度缓冲区:

// renderer
renderer = new THREE.WebGLRenderer({
    antialias: true,
    logarithmicDepthBuffer: true // <-- Set render to use logarithmic depth buffer
});

此解决方案在 this fiddle

中进行了演示
  • 此解决方案由@FastSnail 在他的评论中提出,来自this answer on Whosebug
  • 另请参阅 this YouTube movie
  • 中关于对数 VS 正常深度缓冲区的 OpenGL 演示
  • 还有另一个专门针对 three.js / WebGL 的演示 this YouTube movie
  • 另请参阅 this Whosebug question 了解对数深度缓冲区的更多背景知识

如果您知道任何其他解决方案,请post另一个答案。