I'm implementing the xToon shader(pdf) in glsl to use as a shader with Three.js.
I'm getting some rendering artifacts, and I think the problem is due to webgl strangeness that I am not knowledgable about, perhaps relating to a Nan or Inf or something... I'm pulling my hair out.
I'll include the complete fragment and vertex shaders below, but I think this is the offending code located in the fragment shader:
....
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;
....
To the best of my debugging efforts there seems to be some problem with using the value d as a component of the texture look up vector. This code produces these strange artifacts:
There shouldn't be those yellow "lines" on those contours...
As you may have noted, I'm not actually using the "loa" value in this code. For a while I thought that this problem was in the way I was calculating loa, but it seems that this bug is independent of loa.
Any help would be much appreciated!
The fragment shader:
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;
}
And the vertex shader:
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 );
}
答案 0 :(得分:1)
我通过将纹理设置为ClampToEdgeWrapping而不是RepeatWrapping来解决问题。我被这个堆栈溢出问题引出了这个答案:
此博客文章中解释了解决方案: Using floor() function in GLSL when sampling a texture leaves glitch
在THREEjs中处理这个问题的函数是Texture的成员,并在THREEjs文档中进行了解释: http://webglfundamentals.org/webgl/lessons/webgl-3d-textures.html
此外,我需要将min过滤器设置为Nearest以完全摆脱伪影。