I post because there I am lost with a shader that I tried to write (inspired by the one proposed by groverburger here), it produces an effect that I cannot solve, here is the problem in image:
We can see that the problem is in the corner of the wall, the transition between the two is completely messed up (I still played with the values to make it more obvious and this happens in all corners of the walls regardless of the direction).
And I can't determine if the problem comes from the shader or the normals of my wall model, so I prefer to share the shader with you first if someone more comfortable with GLSL than me can tell me if there is an error in it before I look at the normals of the model (which seems to me to be quite correct after dozens of proofreading...)
So here is my shader that I haven't stopped tweaking to always have the same result...
Code: Select all
// variables provided by g3d's vertex shader
varying vec4 worldPosition;
varying vec3 vertexNormal;
// the model matrix comes from the camera automatically
uniform mediump mat4 modelMatrix;
// value given by main program
uniform vec3 lightPosition;
// constant values
const float light_dist = 10;
const float ambient = 0.2;
vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 screen_coords) {
// Get the current pixel, if alpha is zero return nothing
vec4 pixel = Texel(texture, texture_coords);
if (pixel.a == 0.0) discard;
// Get the distance between the light position and the point in the world
vec3 delta_pos = lightPosition.xyz - worldPosition.xyz;
float dist = length(delta_pos);
if (dist > light_dist)
return vec4(pixel.rgb * ambient, 1.0) * color;
// Computed by the dot product of the normal vector and the direction to the light source
vec3 lightDirection = normalize(delta_pos);
vec3 normal = normalize(mat3(modelMatrix) * vertexNormal);
float diffuse = max(dot(lightDirection, normal), 0.0);
// Calculate the final brightness, taking into account the distance that light can travel and ambient value
float lightness = max(diffuse * smoothstep(light_dist, 0.0, dist) + ambient, ambient);
return vec4((pixel.rgb * color.rgb) * lightness, 1.0);
}
Edit: I just tried with the cube model provided in the g3d repository and there is the same behavior, so I actually think the normals are good.