首页 > 解决方案 > 出现在特定 GPU 上的片段着色器法线伪影

问题描述

我正在从RGB编码的高度图计算法线:

在此处输入图像描述

float unpackFactor = vec3(256.0 * 255.0, 255.0, 255.0 / 256.0);

float unpackOffset = -32768.0;

因此我编辑了 phong 着色器内置dHdxy_fwd()函数:

vec2 dHdxy_fwd() {
    float texelSize = 1.0 / 256.0;
    vec2 dSTdx = vec2(texelSize, .0);
    vec2 dSTdy = vec2(.0, texelSize);

    float Hll = bumpScale * dot(texture2D(displacementMap, vUv).rgb, unpackFactors) + unpackOffset;
    float dBx = bumpScale * dot(texture2D(displacementMap, vUv + dSTdx).rgb, unpackFactors) + unpackOffset - Hll;
    float dBy = bumpScale * dot(texture2D(displacementMap, vUv + dSTdy).rgb, unpackFactors) + unpackOffset - Hll;

    return vec2(dBx, dBy);
}

不幸的是,高度的解码会导致纹理的绿色通道周围出现伪影——发生在iPhone 7、iPhone XS和我的 Mac的Radeon 455 专用 GPU上:

在此处输入图像描述

这些工件如下所示:

在此处输入图像描述

放大:

在此处输入图像描述

然而,在Intel HD Graphics 530(集成 GPU)上,看不到这样的伪影——它看起来应该是完美的(忽略瓷砖接缝):

在此处输入图像描述

放大:

在此处输入图像描述

为什么某些(大多数经过测试的)GPU 上会出现伪影?知道如何摆脱它们吗?似乎有些数值不稳定,但我在纹理精度、压缩总高度值等方面摸索,但还没有运气。

标签: three.jsshaderwebglfragment-shadernormals

解决方案


推荐阅读