2

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:

Shader render

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 );
}
Nicol Bolas
  • 378,677
  • 53
  • 635
  • 829
  • I think your formulation of `d` is off. Try `max(dot(n,l), 0)` instead. – WacławJasper Jul 12 '16 at 04:24
  • Well I don't really understand what that would do, and it didn't fix the issue, but it did weirdly seem to make the yellow artifacts "thinner" when I did the following: float d = max(dot(n, l), 0.0) * 0.5 + 0.5; I also tried: float d = min(max(dot(n, l), 0.0), 1.0) * 0.5 + 0.5; but that didn't have a noticeable effect. The reason that I ...* 0.5 + 0.5 is to transform the range from [-1.0, 1.0] to [0.0, 1.0] – Nick Gimbal Jul 12 '16 at 22:42
  • So another clue is that if I use fract(dot(n,l)), then the problem is greatly accentuated... – Nick Gimbal Jul 12 '16 at 23:10
  • What does your lookup texture looks like? Is it yellow on the left side? Can do you a `gl_FragColor = vec4(d);` on the same model and upload it? – WacławJasper Jul 13 '16 at 04:02
  • Can you put together a web page (jsfiddle or jsbin, for example) with your code? – Kirill Dmitrenko Jul 14 '16 at 06:12
  • [The gl_FragColor = vec4(d);](http://imgur.com/M37aVQF) [In this image d is mapped to red for the offending areas.](http://imgur.com/E7HZgBd) – Nick Gimbal Jul 14 '16 at 22:40
  • Thanks so much for the help!! @WacławJasper – Nick Gimbal Jul 14 '16 at 22:47

1 Answers1

1

I solved the problem by setting the texture to ClampToEdgeWrapping instead of RepeatWrapping. I was led to this answer by this stack overflow question:

Using floor() function in GLSL when sampling a texture leaves glitch

The solution is explained very well in this blog post: http://webglfundamentals.org/webgl/lessons/webgl-3d-textures.html

And the functions to deal with this in THREEjs are members of the Texture and are explained in the THREEjs docs here.

Also I needed to set the min filter to Nearest to fully get rid of the artifacts.

xxx
  • 421
  • 6
  • 18