• Advertisement
Sign in to follow this  

GLSL Per-Pixel Lighting Issue

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

How do I fix the lighting here so that the squares are lit uniformly instead of each having a corner lit?

[img]http://i90.photobucket.com/albums/k276/krims2006/lightwrong.jpg[/img]

Do I have to use per-vertex lighting? How do I do that in GLSL?

Share this post


Link to post
Share on other sites
Advertisement
[quote name='polyfrag' timestamp='1351163822' post='4993752']
Do I have to use per-vertex lighting? How do I do that in GLSL?
[/quote]
No, you don't need to use per vertex lighting, this would be a step backward.

From your image I would guess, that the vertex normals of your tiles are invalid, this happens i.e when using a cube and the smooth function. I this case the upper left corner corner would point to the sun (receives a lot of light) and the right buttom corner would point away (shadow). Check your model and add either hard edges or turn off surface smooth for the tile base.

Share this post


Link to post
Share on other sites
Show us your lighting code.
It looks like every tile has the same lighting result? Which suggests you're doing the lighting in model space (instead of world or view space) and using the same (model-relative) sun position for each model.

Share this post


Link to post
Share on other sites
your normals are fine
you are using the internal vertex coordinates, ie. in_vertex.xyz instead of camera-world coordinates

Share this post


Link to post
Share on other sites
Fragment shader
[code]#version 120
uniform sampler2D texture1;
uniform sampler2D texture2;
uniform sampler2D shadowMap;
varying vec4 lpos;
varying vec3 normal;
varying vec3 light_vec;
varying vec3 light_dir;

void main (void)
{
vec3 smcoord = lpos.xyz / lpos.w;
float shadow = max(0.5, float(smcoord.z <= texture2D(shadowMap, smcoord.xy).x));
vec3 lvec = normalize(light_vec);
float diffuse = max(dot(-lvec, normal), 0.0);
vec4 texColor = texture2D(texture1, gl_TexCoord[0].st) * texture2D(texture2, gl_TexCoord[1].st);
gl_FragColor = vec4(gl_Color.xyz * texColor.xyz * shadow * diffuse * 2.0, texColor.w);
}[/code]

Vertex shader
[code]
uniform mat4 lightMatrix;
uniform vec3 lightPos;
uniform vec3 lightDir;
varying vec4 lpos;
varying vec3 normal;
varying vec3 light_vec;
varying vec3 light_dir;

void main(void)
{
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_TexCoord[1] = gl_MultiTexCoord1;
vec4 vpos = gl_ModelViewMatrix * gl_Vertex;
lpos = lightMatrix * vpos;
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
light_vec = vpos.xyz - lightPos;
light_dir = gl_NormalMatrix * lightDir;
normal = normalize(gl_NormalMatrix * gl_Normal);
gl_FrontColor = gl_Color;
}[/code] Edited by polyfrag

Share this post


Link to post
Share on other sites
I think the problem is in this line:

[CODE]light_vec = vpos.xyz - lightPos;[/CODE]

[i]vpos[/i] is in camera (view) space, while [i]lightPos[/i] is probably in world space. If you want to do your lighting calculations in view space, then you may need to transform [i]lightPos[/i] into view space first.

I haven't tested this, but this is my first suggestion from glancing at your shaders. I could be wrong, but give it a try.

Share this post


Link to post
Share on other sites
View space is the local coordinate system of camera. I.e. the one where 0,0,0 is at the center of camera and Z axis points "into" the camera.
You can transform a vector from world space to view space by multiplying it with the inverse of camera matrix. I.e.

lightpos_v = viewmatrix[sup]-1[/sup] * lightpos_w

Share this post


Link to post
Share on other sites
I think it already does that

[code]
void InverseMatrix(float dst[16], float src[16])
{
dst[0] = src[0];
dst[1] = src[4];
dst[2] = src[8];
dst[3] = 0.0;
dst[4] = src[1];
dst[5] = src[5];
dst[6] = src[9];
dst[7] = 0.0;
dst[8] = src[2];
dst[9] = src[6];
dst[10] = src[10];
dst[11] = 0.0;
dst[12] = -(src[12] * src[0]) - (src[13] * src[1]) - (src[14] * src[2]);
dst[13] = -(src[12] * src[4]) - (src[13] * src[5]) - (src[14] * src[6]);
dst[14] = -(src[12] * src[8]) - (src[13] * src[9]) - (src[14] * src[10]);
dst[15] = 1.0;
}[/code]
[code]
glGetFloatv(GL_PROJECTION_MATRIX, cameraProjectionMatrix);
glGetFloatv(GL_MODELVIEW_MATRIX, cameraModelViewMatrix);
InverseMatrix(cameraInverseModelViewMatrix, cameraModelViewMatrix);

glPushMatrix();
glLoadIdentity();
glTranslatef(0.5, 0.5, 0.5); // + 0.5
glScalef(0.5, 0.5, 0.5); // * 0.5
glMultMatrixf(lightProjectionMatrix);
glMultMatrixf(lightModelViewMatrix);
glMultMatrixf(cameraInverseModelViewMatrix);
glGetFloatv(GL_MODELVIEW_MATRIX, lightMatrix);
glPopMatrix();

glUniformMatrix4fvARB(uniformShadow_lightMatrix, 1, false, lightMatrix);
float mvLightPos[3];
mvLightPos[0] = cameraModelViewMatrix[0] * lightPos[0] + cameraModelViewMatrix[4] * lightPos[1] +
cameraModelViewMatrix[8] * lightPos[2] + cameraModelViewMatrix[12];
mvLightPos[1] = cameraModelViewMatrix[1] * lightPos[0] + cameraModelViewMatrix[5] * lightPos[1] +
cameraModelViewMatrix[9] * lightPos[2] + cameraModelViewMatrix[13];
mvLightPos[2] = cameraModelViewMatrix[2] * lightPos[0] + cameraModelViewMatrix[6] * lightPos[1] +
cameraModelViewMatrix[10] * lightPos[2] + cameraModelViewMatrix[14];
glUniform3fARB(uniformShadow_lightPos, mvLightPos[0], mvLightPos[1], mvLightPos[2]);
[/code] Edited by polyfrag

Share this post


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

  • Advertisement