help with GLSL shader

Started by
3 comments, last by Nitrogen 17 years, 7 months ago
I've hacked up the shader below by grabbing different bits of source code from here and there. But right now it only works if the model being drawn is drawen with an identity modelview. My main questions is this: What spaces should I send light data, eye data, and model data to a flexible, general purpose shader? Right now the light positions are in eye space and the eye position is in world space. Again, the problem arrises when objects are drawn with anything other than modelview. (The wrong sides get lit) Vertex Shader:

uniform vec4 view_position;

varying vec2 vTexCoord;
varying vec3 vLightVec;
varying vec3 vViewVec;

varying vec3 vTangent;
varying vec3 vBinormal;
varying vec3 vNormal;

void main(void)
{
   vec4 lightPos = gl_LightSource[0].position;
   vec3 rm_Tangent = gl_MultiTexCoord2.xyz;
   vec3 rm_Binormal = gl_MultiTexCoord1.xyz;
   gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;

   // construct a tangent space matrix from tan/binorm/norm   
   mat3 tanSpace = mat3( rm_Tangent, gl_Normal,rm_Binormal);
   
   vec3 tangent  = vec3( rm_Tangent.x,  rm_Tangent.y,  rm_Tangent.z);
   vec3 normal   = vec3(  gl_Normal.x,   gl_Normal.y,   gl_Normal.z);
   vec3 binormal = vec3(rm_Binormal.x, rm_Binormal.y, rm_Binormal.z);
   
    // find lightvec and xform it to tanspace.
   vec3 tempVec = lightPos.xyz - gl_Vertex.xyz;
   vLightVec.x = dot(tangent,  tempVec);
   vLightVec.y = dot(binormal, tempVec);
   vLightVec.z = dot(normal,   tempVec);
   
   // find viewvec and xform it to tanspace.
   tempVec  = view_position.xyz - gl_Vertex.xyz;
   vViewVec.x = dot(tangent,  tempVec);
   vViewVec.y = dot(binormal, tempVec);
   vViewVec.z = dot(normal,   tempVec);
   
   // load texcoords.
   vTexCoord = vec2(gl_MultiTexCoord0);
   
   vTangent   = rm_Tangent;
   vBinormal  = rm_Binormal;
   vNormal    = gl_Normal;  
}

}



Fragment Shader:

uniform sampler2D BumpMap;
uniform sampler2D BaseMap;

//materials
uniform vec4 Ka;
uniform vec4 Kd;
uniform vec4 Ks;

varying vec2 vTexCoord;
varying vec3 vLightVec;
varying vec3 vViewVec;

varying vec3 vTangent;
varying vec3 vBinormal;
varying vec3 vNormal;

float saturate( float inValue)
{
   return clamp(inValue, 0.0, 1.0);
}
void main(void)
{
	vec3 nvViewVec = normalize(vViewVec);

   float lightDist = length(vLightVec);
   float radius = gl_LightSource[0].linearAttenuation;
   float globalScalar = (radius-lightDist)/radius;
   vec4 base = texture2D(BaseMap, vTexCoord);
   vec3 bump = texture2D(BumpMap, vTexCoord).xyz * 2.0 - 1.0;
   
   // Standard lighting
   vec3  lVec     = normalize(vLightVec);

   float diffuse  = saturate(dot(lVec, bump));
   float specular = pow(saturate(dot(reflect(-nvViewVec, bump), lVec)), 16.0);
   
   gl_FragColor = ((diffuse*Kd*gl_LightSource[0].diffuse * base + specular*Ks*gl_LightSource[0].specular) + Ka*gl_LightSource[0].ambient * base)*globalScalar;
}

Here is a screenshot: normal and parallax maps As you can see, the wrong side of the cone is lit. All objects drawn are drawn with identity, and the cone has been rotated 180 around y. thanks in advance.
Advertisement
1st off make sure everything is in the same space.

2nd are your normals correct?

3rd are you sure your code is correct for TBN? Did verify the values for each vector?
"2nd are your normals correct?"
yes, I've used fixed func on the normals, and it looks fine.

"3rd are you sure your code is correct for TBN? Did verify the values for each vector?"

yes I'm sure, because the normal mapping looks great for ANY shape, so long as its modelview is identity.

I'm consered about #1, because looking at these lines:

// find lightvec and xform it to tanspace.
vec3 tempVec = lightPos.xyz - gl_Vertex.xyz;

// find viewvec and xform it to tanspace.
tempVec = view_position.xyz - gl_Vertex.xyz;

lightPos is in eye space and gl_Vertex is in object position.
view_position is world. So basically here the vectors are in two different spaces and I'm finding the distance between them. I know that dosn't work but I've tried matching the spaces, and I still get problems.
can you replace and tell us if it change something :
this :

vec3 tempVec = lightPos.xyz - gl_Vertex.xyz;

by :

vec3 tempVec = lightPos.xyz - gl_Position.xyz;


and this :

tempVec = view_position.xyz - gl_Vertex.xyz;

by :

tempVec = view_position.xyz - gl_Position.xyz;

EDIT : sorry i didn't read well the end of your last post but you should put everything in the same space (even it change nothing to your problem)

[Edited by - TheSeb on September 10, 2006 6:42:06 AM]
Sounds like you need to multiply your tangent space vectors by the modelview matrix as well.
Delphi C++ OpenGL Development: www.nitrogen.za.org

This topic is closed to new replies.

Advertisement