0
votes

VC++ 2010, OpenGL, GLSL, SDL

So I am having two major problems. I am hoping to primarily address this first one being: The normal map shader I am using does not work with normals that are pointing in the positive or negative x direction. z and y seem to work just fine (testing the texture and normals on a cube).

edit : It does not seem to be normals in the x direction, because when I rotate the geometry, the front facing quad will still work. So it seems whatever was originally oriented facing the x doesnt work.

Here is some simple test geometry:

glBegin(GL_QUADS);
    glNormal3f(0.0f, 0.0f, 1.0f);
    glTexCoord2f(0.0, 0.0); glVertex3f(-1.0f, 0.0f, 1.0f);
    glTexCoord2f(0.0, 1.0); glVertex3f(-1.0f, 2.0f, 1.0f);
    glTexCoord2f(1.0, 1.0); glVertex3f(1.0f, 2.0f, 1.0f);
    glTexCoord2f(1.0, 0.0); glVertex3f(1.0f, 0.0f, 1.0f);
glEnd();
glBegin(GL_QUADS);
    glNormal3f(-1.0f, 0.0f, 0.0f);
    glTexCoord2f(0.0, 0.0); glVertex3f(-1.0f, 0.0f, 1.0f);
    glTexCoord2f(0.0, 1.0); glVertex3f(-1.0f, 2.0f, 1.0f);
    glTexCoord2f(1.0, 1.0); glVertex3f(-1.0f, 2.0f, -1.0f);
    glTexCoord2f(1.0, 0.0); glVertex3f(-1.0f, 0.0f, -1.0f);
glEnd();

Vertex Shader

#define MAX_LIGHTS 8
#define NUM_LIGHTS 1

varying vec3 lightVec[MAX_LIGHTS];
varying vec3 viewVec;

attribute vec4 glTangent4f;

void main(void)
{
    gl_Position = ftransform();
    gl_TexCoord[0] = gl_MultiTexCoord0;

    vec3 n = normalize(gl_NormalMatrix * gl_Normal);
    vec3 t = normalize(gl_NormalMatrix * glTangent4f.xyz);
    vec3 b = cross(n, t);

    vec3 v;
    vec3 vVertex = vec3(gl_ModelViewMatrix * gl_Vertex);
    int i;
    for (i=0; i<NUM_LIGHTS; ++i)
    {
        vec3 lVec = gl_LightSource[i].position.xyz - vVertex;
        v.x = dot(lVec, t);
        v.y = dot(lVec, b);
        v.z = dot(lVec, n);
        lightVec[i] = v;
    }

    vec3 vVec = -vVertex;
    v.x = dot(vVec, t);
    v.y = dot(vVec, b);
    v.z = dot(vVec, n);
    viewVec = v;
}

Fragment Shader

#define MAX_LIGHTS 8
#define NUM_LIGHTS 1

varying vec3 lightVec[MAX_LIGHTS];
varying vec3 viewVec;

uniform sampler2D colorMap;
uniform sampler2D normalMap;

void main (void)
{
    vec2 uv = gl_TexCoord[0].st * 4.0;
    vec4 base = texture2D(colorMap, uv);
    vec4 final_color = vec4(0.2, 0.2, 0.2, 1.0) * base;
    vec3 vVec = normalize(viewVec);
    vec3 bump = normalize(texture2D(normalMap, uv).xyz * 2.0 - 1.0);
    vec3 R = reflect(-vVec, bump);

    int i;
    for (i=0; i<NUM_LIGHTS; ++i)
    {
        vec3 lVec = normalize(lightVec[i]);
        float diffuse = max(dot(lVec, bump), 0.0);
        vec4 vDiffuse = gl_FrontLightProduct[i].diffuse * diffuse * base;
        final_color += vDiffuse;

        float specular = pow(clamp(dot(R, lVec), 0.0, 1.0), gl_FrontMaterial.shininess);
        vec4 vSpecular = gl_FrontLightProduct[i].specular * specular * diffuse;
        final_color += vSpecular;
    }

    gl_FragColor = final_color;
}

The other problem (which I do not necessarily need to address right this moment) is the specular of the directional light seems to follow with the camera

2
What does/doesn't happen, compared with what you were expecting?slugonamission
Your shaders are missing #version directives. They are required for a shader to be compiled.pmr
I was expecting to see the normal mapping working on the second set of geometry that is facing in the x direction.grep
Okay. Can you post a screenshot of exactly what you are seeing when this runs?slugonamission
unfortunately screenshots just show up as black in my application right now.grep

2 Answers

2
votes
attribute vec4 glTangent4f;

Where do you actually provide this value? It's a vertex attribute, but your rendering code doesn't seem to provide anything.

0
votes

"How would I go about passing this surface tangent to the program?"

Have you computed the tangent basis for your object? I remember that wavefront objects usually don't include vertex tangent data, and in that case you need to calculate your tangent basis after having parsed the wavefront data. From the looks of your code, you don't seem to have no tangent data at all.

You can do a tangent approximation in the vertex shader, also, just using the normal.

I don't actually know how you would pass your tangent data to the program, because you are not using VBO's.

EDIT:

I see now that I made the idiotic assumption that you are loading your data from a 3d file format, which you are not, but you still need to compute the tangent somewhere.