I’m getting weird results with a shader I wrote in glsl in AMD Render Monkey. I have a ATI Radeon Mobility X1400 graphics card.
Depending on the viewing angle, the sphere in the middle is invisible, solid or like this. It should be rendered solid. I’ve found a few ways to get rid of this problem, but they’re not very satisfying:[ul][li] not drawing the torus knot and its outline. [] adding a few useless if branches into the fragment shader.[] moving some of the lines of code around, without actually changing the shader.[*] removing the line with the discard statement[/ul][/li]Has anyone seen such behavior before?
The sphere is raytraced on a 4x4 quad, here is the code:
Vertex shader:
uniform float size;
varying vec3 pos;
varying vec3 center;
void main( void )
{
// billboarding
vec4 post = 1.25 * size * vec4(gl_Vertex.xy,0.0,0.0) * gl_ModelViewMatrix;
post.w = gl_Vertex.w;
pos = vec3(gl_ModelViewMatrix * post);
center = vec3(gl_ModelViewMatrix * vec4(0.0,0.0,0.0,1.0));
gl_Position = gl_ModelViewProjectionMatrix * post;
}
Fragment shader:
uniform sampler2D baseMap;
uniform float size;
uniform vec3 lightDir;
varying vec3 pos;
varying vec3 center;
void main( void )
{
vec3 k = dot(pos,center)/dot(pos,pos) * pos;
float d = size * size - dot(center,center) + dot(k,k);
if (d<0.0) discard;
float lk = length(k);
vec3 isect = (k * ((lk - sqrt(d))/lk));
vec4 scr = gl_ProjectionMatrix * vec4(isect,1.0);
float zb = scr.z/scr.w*0.5+0.5;
gl_FragDepth = zb;
vec3 normal = (isect-center)/size;
gl_FragColor = texture2D( baseMap, vec2(normal) );
float intensity = dot(lightDir,normal);
vec4 color;
if (intensity > 0.95)
color = vec4(0.5,1.0,0.5,1.0);
else if (intensity > 0.5)
color = vec4(0.3,0.6,0.3,1.0);
else if (intensity > 0.25)
color = vec4(0.2,0.4,0.2,1.0);
else
color = vec4(0.1,0.2,0.1,1.0);
gl_FragColor = color;
}