Jump to content
  • Advertisement
Sign in to follow this  
eXt_

OpenGL cg lighting problems

This topic is 3911 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

I'm trying to learn to use cg shaders with opengl but I'm stuck with the lighting. The lighting seems to follow me whereever I go and/or depend on the angle of the camera. This is my shader:
struct vp_in {
    float4 position : POSITION;
    float3 normal : NORMAL;
    float2 texcoord : TEXCOORD0;
    float4 color : COLOR;
};

struct fp_in {
    float3 normal : TEXCOORD0;
    float2 texcoord : TEXCOORD1;
    float4 position : TEXCOORD2;
    float4 color : COLOR;
};

struct fp_out {
    float4 color: COLOR;
};

float3 light_pos;

float attenuation(float d){
    return 1 / ( 0.5 + 0.1 * d + 0.30 * d * d);
}

fp_in vp_main(vp_in IN, out float4 homogen : POSITION){

    fp_in OUT;

    // Clip space
    homogen = mul(glstate.matrix.mvp, IN.position);

    // General calculations
    float3 N = IN.normal;
    float3 light = mul(glstate.matrix.modelview[0], float4(light_pos,1)).xyz;
    float3 light_to_pos = light - IN.position.xyz;
    float3 L = normalize(light_to_pos);

    // Ambient
    float3 ambient = float3(0.1, 0.1, 0.1);

    // Diffuse
    float3 light_dist = length(light_to_pos);
    float diffuseLight = max(dot(N, L), 0);
    float3 diffuse = float3(1,1,1) * diffuseLight * attenuation(light_dist);

    // Sum of the components
    OUT.color.xyz = diffuse;
    OUT.color.w = 1;

    OUT.texcoord = IN.texcoord;

    return OUT;
}

fp_out fp_main(fp_in IN, uniform sampler2D texture : TEXUNIT0){
    fp_out OUT;

    // Texture
    float4 texcolor = tex2D(texture, IN.texcoord);

    OUT.color = IN.color * texcolor;

    return OUT;
}

sampler2D texture = sampler_state {
    generateMipMap = true;
    minFilter = Linear;
    magFilter = LinearMipMapLinear;
};

technique test_fx {
    pass P1 {
        VertexProgram = compile vp40 vp_main();
        FragmentProgram = compile fp40 fp_main(texture);
    }
}

Share this post


Link to post
Share on other sites
Advertisement
Looks like your light position and vertex position (and normal) are not in the same space. This line:
float3 light = mul(glstate.matrix.modelview[0], float4(light_pos,1)).xyz;
transforms the light position from object space to view space, but only if the position was in object space to begin with. In what space is the light position in when you pass it to the shader?

Share this post


Link to post
Share on other sites
Worldspace I belive (I'm not 100% sure of the terminology). The light position is relative to the world origo, not relative to the object.

Share this post


Link to post
Share on other sites
That's you problem. Like I said, the code line I copied transforms the light's position into view space if it's in object space. If it's not, the transformation is meaningless. Also, you leave your vertex position and normal in object space. For operations like vector subtraction and the dot product to work properly, the vectors must be in the same space.

The easiest option is probably to transform the light's position to object space outside the shader. Then you'll be doing the lighting in object space.

BTW, this line:

float3 light_to_pos = light - IN.position.xyz;

gives the vector from the vertex to the light, so you should name the variable to pos_to_light or something similar.

Share this post


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

  • Advertisement
×

Important Information

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

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!