Jump to content
  • Advertisement
Sign in to follow this  
devildeath

GLSL Bumpmapping with Point Light - weired Problem

This topic is 2993 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I have some problem implementing Bumpmapping using GLSL. In general the main Bumpmapping Shader works but the specular part of the Light is not on the correct position. I looked at so many tutorials and so on but i did not find a solution for this problem because they always used a directional Light or Spot Light. The Shader itself is very complex because it looks at the Light and decides which kind of Lights we have to perform the right lighting calcuation. Thanks for Help. Greetings Devildeath [Vertex-Shader]
attribute vec3 tangent; //The inverse tangent to the geometry
//attribute vec3 binormal; //The inverse tangent to the geometry

varying vec3 vertex;
varying vec3 t, n; //, b;// n; // the tangent, binormal and normal

void main() {


	vertex = vec3(gl_ModelViewMatrix * gl_Vertex);  
	
	n = normalize(gl_NormalMatrix * gl_Normal);
	t = normalize(gl_NormalMatrix * tangent);
	vec3 b = normalize(cross(n, t)); 


    //Use the first set of texture coordinates in the fragment shader 
    gl_TexCoord[0] = gl_MultiTexCoord0;
    
    //Put the vertex in the position passed
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; 
}
[Fragment-Shader]
uniform sampler2D ColorTex1;

uniform sampler2D NormalMap; 

// the tangent, binormal and normal
varying vec3 vertex; 
varying vec3 t, n; // , b; //, n;
varying vec3 t2, n2;
vec3 tn, bn, nn; // normalized tangent, binormal and normal
vec3 tn2, bn2, nn2; // normalized tangent, binormal and normal
vec3 lightDirTangentSpace;
vec3 eyeVecTangentSpace;
vec3 lightDir;

mat3 rot;

vec3 toTangentSpace( in vec3 vector ) {

    return normalize(vector * rot);
}

float calculateAttenuation(in int i, in float dist) {
    return(1.0 / (gl_LightSource.constantAttenuation +
                  gl_LightSource.linearAttenuation * dist +
                  gl_LightSource.quadraticAttenuation * dist * dist));
}

void directionalLight(in int i, in vec3 N, in float shininess,
                      inout vec4 ambient, inout vec4 diffuse, inout vec4 specular) {
	
    // some code
}

void pointLight(in int i, in vec3 N, in vec3 V, in float shininess,
                inout vec4 ambient, inout vec4 diffuse, inout vec4 specular) {   
    // direction of pointlight
    lightDir = gl_LightSource.position.xyz - V;
    float dist = length(lightDir);
    // transform the Light direction into tangent space  
    lightDir = toTangentSpace( lightDir );
                
    float nDotL = dot(lightDir, N);
    
    if (nDotL > 0.0) {   
    	// transform the eye Vector into tangent space
	    vec3 eyeVec = toTangentSpace(-V);
	    
	//vec3 reflection = normalize(reflect(-lightDir, N));
	
    	float attenuation = calculateAttenuation(i, dist);
        diffuse  += gl_LightSource.diffuse  * attenuation * nDotL;
        
        float pf = 0.0;
		if (shininess > 0.0)
			pf = pow(max(dot(reflect(-eyeVec, N),lightDir), 0.0), shininess);
		//else
		//	pf = pow(max(dot(reflect(-eyeVec, N),lightDir), 0.0), 0.0);
        specular += gl_LightSource.specular * attenuation * pf;
    }
    ambient  += gl_LightSource.ambient;
}

void spotLight(in int i, in vec3 N, in vec3 V, in float shininess,
               inout vec4 ambient, inout vec4 diffuse, inout vec4 specular) {
    
    // some code
}

const vec4 AMBIENT_BLACK = vec4(0.0, 0.0, 0.0, 1.0);
const vec4 DEFAULT_BLACK = vec4(0.0, 0.0, 0.0, 0.0);

bool isLightEnabled(in int i) {
    // A separate variable is used to get
    // rid of a linker error.
    bool enabled = true;
   
    // If all the colors of the Light are set
    // to BLACK then we know we don't need to bother
    // doing a lighting calculation on it.
    if ((gl_LightSource.ambient  == AMBIENT_BLACK) &&
        (gl_LightSource.diffuse  == DEFAULT_BLACK) &&
        (gl_LightSource.specular == DEFAULT_BLACK))
        enabled = false;
       
    return(enabled);
}

void calculateLighting(in int numLights, in vec3 N, in vec3 V, in float shininess,
                       inout vec4 ambient, inout vec4 diffuse, inout vec4 specular  ) {
    // Just loop through each light, and if its enabled add
    // its contributions to the color of the pixel.
    for (int i = 0; i < numLights; i++) {
        if (isLightEnabled(i)) {
            if (gl_LightSource.position.w == 0.0)
                directionalLight(i, N, shininess, ambient, diffuse, specular);
            else if (gl_LightSource.spotCutoff == 180.0)
                pointLight(i, N, V, shininess, ambient, diffuse, specular);
            else
                spotLight(i, N, V, shininess, ambient, diffuse, specular);
        }
    }
}

void main() {

    // Normalize the normal. A varying variable CANNOT
    // be modified by a fragment shader. So a new variable
    // needs to be created.
	nn = normalize(n);
	tn =-normalize(t); 
	bn = normalize(cross(nn, tn));
	rot = mat3(tn, bn, nn);

    vec3 bumpNormal = normalize((texture2D(NormalMap, gl_TexCoord[0].st).xyz * 2.0) - 1.0);
    
    vec4  nAmb, nDiff, nSpec, color;

    // Initialize the contributions.
    nAmb  = vec4(0.0);
    nDiff = vec4(0.0);
    nSpec = vec4(0.0);
   
    // In this case the built in uniform gl_MaxLights is used
    // to denote the number of lights. A better option may be passing
    // in the number of lights as a uniform or replacing the current
    // value with a smaller value.
    calculateLighting(5, bumpNormal, vertex, gl_FrontMaterial.shininess, nAmb, nDiff, nSpec );
   
	color  = gl_FrontLightModelProduct.sceneColor  +
             (nAmb  * gl_FrontMaterial.ambient) +
             (nDiff * gl_FrontMaterial.diffuse) +
             (nSpec * gl_FrontMaterial.specular);

    // Re-initialize the contributions for the back
    // pass over the lights
    nAmb  = vec4(0.0);
    nDiff = vec4(0.0);
    nSpec = vec4(0.0);
          
    // Now calculate the back contribution. All that needs to be
    // done is to flip the normal.
	
    calculateLighting(5, -bumpNormal, vertex, gl_BackMaterial.shininess, nAmb, nDiff, nSpec );

    color += gl_BackLightModelProduct.sceneColor  +
             (nAmb  * gl_BackMaterial.ambient) +
             (nDiff * gl_BackMaterial.diffuse) +
             (nSpec * gl_BackMaterial.specular);
	
    color = clamp(color, 0.0, 1.0);    
    
    //Get the color of the texture
    vec4 decalCol = texture2D(ColorTex1, gl_TexCoord[0].st);
    gl_FragColor = decalCol * color;
}

Share this post


Link to post
Share on other sites
Advertisement
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!