OpenGL shader - Missing pixels

I have recently got my shader working, and since then have looked around for a vert+frag shader to work with my texture.

This shader has been the closest one i can find thats works close to perfect, except it cuts off nearly half of what it is lighting. I don’t know why turns half of what it is lighting into black pixels. I’d kill for an answer.

Here are the shader files:

.vert


    varying vec3 normal, lightDir, eyeVec; 
    varying float att; 
     
    void main() 
    { 
        normal = gl_NormalMatrix * gl_Normal; 
        
        vec3 vVertex = vec3(gl_ModelViewMatrix * gl_Vertex); 
        lightDir = vec3(gl_LightSource[0].position.xyz - vVertex); 
        eyeVec = vVertex;
        
        float d = length(lightDir); 
        
        att = 1.0 / ( gl_LightSource[0].constantAttenuation +  
        (gl_LightSource[0].linearAttenuation*d) +  
        (gl_LightSource[0].quadraticAttenuation*d*d) ); 
        
        gl_Position = ftransform(); 
 
        gl_FrontColor = gl_Color; 
        gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; 
    } 

.frag


    varying vec3 normal, lightDir, eyeVec; 
    varying float att; 
    
    uniform sampler2D tex; 
    
    void main (void) 
    { 
        vec4 final_color =  (gl_FrontLightModelProduct.sceneColor * gl_FrontMaterial.ambient) + (gl_LightSource[0].ambient * gl_FrontMaterial.ambient) * att; 
        
        vec3 N = normalize(normal); 
        vec3 L = normalize(lightDir); 
 
        float lambertTerm = dot(N,L); 
        
        if(lambertTerm > 0.0) 
        { 
            final_color += gl_LightSource[0].diffuse * gl_FrontMaterial.diffuse * lambertTerm * att; 
            
            vec3 E = normalize(eyeVec); 
            vec3 R = reflect(-L, N); 
            
            float specular = pow( max(dot(R, E), 0.0), gl_FrontMaterial.shininess ); 
            
            final_color += gl_LightSource[0].specular * gl_FrontMaterial.specular * specular * att;  
        } 
        
        gl_FragColor = final_color; 
        gl_FragColor *= texture2D(tex, gl_TexCoord[0].st); 
    } 

And if i change " eyeVec = vVertex; " to " eyeVec = -vVertex; " in .vert, i magically get the other half of my missing lighting.

You should be adding the diffuse colour contribution regardless of whether lambert term is > 0. Only the Specular is calculated if NdotL is > 0

You should be adding the diffuse colour contribution regardless of whether lambert term is > 0.

What? If N*L is less than zero, then the normal is pointed away from the light. All lighting directly from that light must therefore be blocked (assuming we’re talking about a closed surface).

Does anyone figure how i would solve the missing pixels problem?

change:


vec3 vVertex = vec3(gl_ModelViewMatrix * gl_Vertex); 
lightDir = vec3(gl_LightSource[0].position.xyz - vVertex); 
eyeVec = vVertex;

to:


vec4 vVertex = gl_ModelViewMatrix * gl_Vertex; // naturally, here expect gl_Vertex.w=1.0
lightDir = vec3(gl_LightSource[0].position.xyz - vVertex.xyz);

vec4 eyePos =  gl_ModelViewMatrix * vec4(0,0,0,1);
eyeVec = vVertex.xyz - eyePos.xyz; // maybe = vVertex.xyz - gl_ModelViewMatrix[3].xyz;

A quick hack would be to assume eyeVec = vec3(0,0,-1) always

Note the circular cutoff you see with your light: that’s where your eyeVec.z happens to be 0.0f, and changes its sign.

Edit:
On a second thought, this might not be the case (and the above won’t fix anything); just make eyeVec = vec3(0,0,-1) always.

Quote:You should be adding the diffuse colour contribution regardless of whether lambert term is > 0.

What? If N*L is less than zero,

Ah, yes, of course. The reason I always include the term in all my stock shaders is because NdotL never becomes negative in the first place.


 float NdotL = max (0.0, dot (normal, Leye) );
//calc specular lighting
   float pf;
   if (NdotL == 0.0)
   	pf = 0.0;	//intensity
   else
   {
   	float NdotH = clamp(dot(normal, Heye), 0.0, 1.0);
   	pf = pow (NdotH, specularpower);
   }
   vec3 specularlight = vec3 (lightspecularcolor.rgb * specularintensity * pf);
   vec3 diffuselight = 0.8 * NdotL * lightcolour.rgb
   vec3 revserselight = 0.2 * (1.0-NdotL) * lightreversecolour.rgb;

@IIian Dinev

Changing the code you suggested leaves this result:
https://www.youtube.com/watch?v=Fp5HUeGaa-8
and


// maybe = vVertex.xyz - gl_ModelViewMatrix[3].xyz;

leaves the same result as


= vVertex.xyz - eyePos.xyz;


And


eyeVec = vec3(0,0,-1);

Renders just the negative portion:

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.