使用点(n,l)作为纹理查找坐标 Webgl 时呈现伪像

Rendering artifacts when using dot(n,l) as texture lookup coordinate Webgl

我正在 glsl 中实现 xToon shader(pdf) 以用作 Three.js 的着色器。

我得到了一些渲染伪影,我认为问题是由于我不了解的 webgl 奇怪性造成的,可能与 Nan 或 Inf 或其他东西有关......我正在拔头发。

我将在下面包含完整的片段和顶点着色器,但我认为这是片段着色器中的违规代码:

....
vec3 n = normalize(vNormal);
vec3 l = normalize(lightDir);

float d = dot(n, l) * 0.5 + 0.5;

//vec2 texLookUp = vec2(d, loa);
vec2 texLookUp = vec2(d, 0.055);
vec4 dColor = texture2D(texture, texLookUp);
gl_FragColor = dColor;
....

尽我最大的调试努力,使用值 d 作为纹理查找向量的组成部分似乎存在一些问题。此代码会产生这些奇怪的工件:

那些轮廓上不应该有那些黄色 "lines"...

您可能已经注意到,我实际上并没有在此代码中使用 "loa" 值。有段时间我以为是我计算loa的方式有问题,不过好像这个bug是独立于loa的。

如有任何帮助,我们将不胜感激!

片段着色器:

uniform vec3 lightDir;
uniform sampler2D texture;

varying vec3 vNormal;
varying vec3 vPosition;
varying vec2 vUv;

// loa calculation for texture lookup
varying highp float loa;

void main() {

vec3 n = normalize(vNormal);
vec3 l = normalize(lightDir);

float d = dot(n, l) * 0.5 + 0.5;

//vec2 texLookUp = vec2(d, loa);
vec2 texLookUp = vec2(d, 0.055);
vec4 dColor = texture2D(texture, texLookUp);

gl_FragColor = dColor;
}

和顶点着色器:

uniform vec3 cameraPos;
uniform vec3 lightDir;
uniform vec3 focalPos;
uniform float inflate;
uniform float zmin;
uniform float r;


varying vec3 vNormal;
varying vec2 vUv;

varying float loa;

void main() {
vec3 n = normalize(normal);

// euclidiean distance to point from camera pos
float depth = length(cameraPos - position);

// 1. detail mapping correcting for perspective projection
float z = depth / zmin;

loa = 1.0 - (log2(z)/log2(r));

loa = clamp(loa, 0.055, 0.9);

vNormal = n;
vUv = uv;

gl_Position = projectionMatrix * modelViewMatrix * vec4(normal * inflate + position, 1.0 );
}

我通过将纹理设置为 ClampToEdgeWrapping 而不是 RepeatWrapping 解决了这个问题。这个堆栈溢出问题让我得到了这个答案:

这个博客post中很好地解释了解决方案: http://webglfundamentals.org/webgl/lessons/webgl-3d-textures.html

THREEjs 中处理此问题的函数是 Texture 的成员,并在 THREEjs 文档中进行了解释 here

我还需要将最小过滤器设置为“最近”以完全消除伪像。