三.js:分层和解决z-fighting更有效:使用polygonOffsetFactor或禁用depthWrite的透明度?

Posted

技术标签:

【中文标题】三.js:分层和解决z-fighting更有效:使用polygonOffsetFactor或禁用depthWrite的透明度?【英文标题】:three.js: What is more efficient to layer and resolve z-fighting: using polygonOffsetFactor or transparency with depthWrite disabled? 【发布时间】:2018-08-12 07:00:00 【问题描述】:

我正在使用 THREE.js 开发一个图表软件。一些绘制的矩形在同一平面上,所以会出现 z-fighting,尤其是但不限于,当我移动相机时。

我找到了两种适合我的解决方案。

第一:

polygonOffset: true,
polygonOffsetUnits: 1,
polygonOffsetFactor: -rectCount

其中 rectCount 是绘制的矩形总数(因此每个下一个具有较小的 polygonOffsetFactor,因此绘制在前一个矩形的“顶部”)。

第二:

transparent: true,
depthWrite: false

renderOrder = rectCount.

我知道不透明物体和透明物体是按三分开排序的,所以如果我使用第二种方法,我也必须设置

transparent: true
opacity: 1

我想在上述矩形上绘制的所有其他对象。

第二个解决方案感觉更干净,TBH,更有效(而使用 polygonOffsetFactor 偶尔仍然会出现 z-fighting),但我担心为场景中的许多对象启用透明度(即使不透明度设置为 1)会对渲染效率有不利影响。假设我希望它足够轻巧,也可以在移动设备上运行。

我不知道 THREE 的内部结构,但我希望在考虑任何透明魔法之前先检查不透明度。

问题:我可以安全使用

transparent: true,
opacity: 1

在许多对象上,它不会严重影响渲染/CPU/GPU 周期?或者对于这种用例,使用 polygonOffsetFactor 被认为更有效?谢谢!

【问题讨论】:

请注意,this OpenGL polygonOffset 文档点 13.020 提到使用 polygonoffset 时有两个通道 - 这是可能答案的一些提示。 【参考方案1】:

刚刚看到这个贴花示例,可能会有所帮助。 https://github.com/mrdoob/three.js/blob/master/examples/webgl_decals.html

const decalMaterial = new THREE.MeshPhongMaterial( 
                specular: 0x444444,
                map: decalDiffuse,
                normalMap: decalNormal,
                normalScale: new THREE.Vector2( 1, 1 ),
                shininess: 30,
                transparent: true,
                depthTest: true,
                depthWrite: false,
                polygonOffset: true,
                polygonOffsetFactor: - 4,
                wireframe: false
             );

【讨论】:

【参考方案2】:

深度写入错误对于所有距离都更可靠。如果由于其他原因最终需要更高的深度排序精度,请考虑在渲染器构造函数中设置 logarithmicDepthBuffer:true。

【讨论】:

决定重写我的评论。谢谢你的指点:)。我使用的是小距离和小相机变焦值(0.3 ~ 3),所以虽然我很高兴了解另一种类型的 depthBuffer,但我假设它可能对小距离没有帮助。如果我理解正确,您确认depthWrite: false 比 polygonOffset 更可靠——我也相信是这种情况。对于任何对 logDepthBuffer 感兴趣的人,这里有一个 demo :)

以上是关于三.js:分层和解决z-fighting更有效:使用polygonOffsetFactor或禁用depthWrite的透明度?的主要内容,如果未能解决你的问题,请参考以下文章

2020-08-28unity3d 重叠面 图层抖动的解决方案,z-fighting.

z-fighting在unity中的解决方式

大数据之数据仓库分层

Oracle数据库设计第三范式

大数据平台中,数据仓库如何分层?

如何使我的 Rust 函数更通用和高效?