为啥我会在使用 WebGL 时看到这些奇怪的剪辑伪影?

Posted

技术标签:

【中文标题】为啥我会在使用 WebGL 时看到这些奇怪的剪辑伪影?【英文标题】:Why am I seeing these strange clipping artifacts with WebGL?为什么我会在使用 WebGL 时看到这些奇怪的剪辑伪影? 【发布时间】:2020-07-08 15:59:51 【问题描述】:

我正在使用 TWGL 创建一个 NxN 平面缓冲区,然后将其用作网格 (twgl.primitives.createPlaneBufferInfo),并在 Z 轴上相对于视频中的亮度值进行拉伸。一切看起来都不错,只是在 (-X, -Y) 和 (X, Y) 象限中出现了奇怪的剪切伪影。示例见附图...

我看到this post 提出了类似的问题,并建议进行深度排序,但鉴于相对深度是在着色器中动态决定的,我什至不知道如何进行这种排序。还有一个建议是禁用深度测试并启用面部剔除,但这不起作用。我认为必须有某种替代方案,因为我正在做的事情并不少见。也许我需要以不同的方式生成网格?我也不清楚为什么这只会发生在四个象限中的两个象限中。提前致谢!

【问题讨论】:

如果增加视频的最低亮度级别,使其永远不会为 0,会发生什么?例如,如果每个像素的视频亮度值在 0 到 255 之间,则将其重新映射为 1 到 255 之间。我认为伪影是由于应用视频的平面由许多矩形组成它再次由两个三角形中的每一个组成,并且这两个三角形不在一个精确的平面上(浮点舍入误差),当应用视频亮度时,如果乘以 0,这些舍入误差可能会导致一些乘法“错误”(黑色=否高度)。 嗯,我进行了一个超级简单的“亮度”计算(当然我可以转换为 HSL,但我只是想让它工作)。我继续往 Z 值添加 0.01,这样它就永远不会为 0。它似乎没有改变任何东西。你的想法是这样的吗? gl_Position = perspectiveMatrixUniform * viewMatrixUniform * vec4((matrixUniform * vec3(position.xy, 1.0)).xy, (intensity.r + intensity.g + intensity.b)/3.0 + 0.01, 1.0 ); 请注意,添加 .01 基线 Z 值不会导致问题消失 还值得注意的是,当我将对象进一步向右或向下移动时,问题会变得更糟。它根本不会发生在 (-X, Y) 或 (X, -Y) 象限中... 【参考方案1】:

经过大量的实验,我终于找到了问题所在。我生成的透视矩阵的第 16 个数组元素为零(换句话说,X、Y、Z、W 矩阵中的位置 [4,4])导致深度值变平。

我正在使用 twgl 生成我的透视矩阵。不知道为什么实现会以这种方式工作(对我来说似乎是一个错误):

_public.perspectiveMatrix = twgl.m4.perspective(_public.POV, width/height, 0.0, 100);

这是一个问题,因为我在顶点着色器中设置位置是这样的:

gl_Position = perspectiveMatrixUniform * viewMatrixUniform * vec4((matrixUniform * vec3(position.xy, 1.0)).xy, (intensity.r + intensity.g + intensity.b)/3.0 + 0.01, 1.0); 

如果我在初始化透视矩阵后立即添加以下行,一切都会按预期工作:

_public.perspectiveMatrix[15] = 1.0;

【讨论】:

以上是关于为啥我会在使用 WebGL 时看到这些奇怪的剪辑伪影?的主要内容,如果未能解决你的问题,请参考以下文章

流式 Flash 视频问题 - 剪辑

在 Firebug 中查看 CSS 伪元素

为啥这个 SVG 投影过滤器在路径很短时会剪切路径?

为啥着色器必须在 webgl 程序的 html 文件中?

为啥我会在 Apple iTunes Connect 设备中看到桌面设备?

WebGL 纹理问题(奇怪的图形故障和映射问题)