I'm trying a simple lighting shader which supports point and directional lights. Directional lights are done, but I'm struggling with the point lights. How can I get the vertex world position to calculate the light direction?? I'm using Libgdx and a sprite batcher, and also an orthographic camera. For now I've just made a (dirty) hack passing the position of the current sprite to be rendered (center position) to the fragment shader, and its working. For what I've read in glsl I could get the modelview matrix and multiply it with the current vertex position (with libgdx I guess that would be the "a_position" attribute) but I was unable to do it...
Vertex shader:
attribute vec4 a_position;
attribute vec2 a_texCoord0;
uniform mat4 u_projTrans;
varying vec3 position;
void main() {
vTexCoord = a_texCoord0;
position = a_position.xyz;
gl_Position = u_projTrans * a_position;
}
Fragment shader:
varying vec2 vTexCoord;
varying vec3 position;
uniform sampler2D u_texture0; //diffuse map
uniform sampler2D u_texture1; //normal map
uniform vec4 light_pos[2];
uniform vec4 light_color[2];
//uniform vec3 spritepos; // "Hack" variable with the sprite position...
void main() {
float attenFactor;
vec4 lightAmbientDiffuse= vec4(0.0,0.0,0.0,0.0);
vec4 lightSpecular = vec4(0.0,0.0,0.0,0.0);
vec3 ambient_light = vec3(0.1,0.1,0.1);
vec3 eyeDir = vec3(0.0,0.0,-1.0);
vec3 lightDir;
float shininess = 10.0;
int totalLights = 2;
vec3 normal = normalize((texture2D(u_texture1, vTexCoord.st).rgb * 2.0) - 1.0);
vec3 pos = position;
// pos = spriteposition; //this is what I do that makes it work
for (int i=0; i<totalLights; i++) {
if (light_pos[i].w != 0.0) {
float dist = distance(light_pos[i].xyz, pos);
float constantAttenuation = 0.01;
float linearAttenuation = 0.2;
float quadraticAttenuation = 0.5;
attenFactor = 1.0 / (constantAttenuation + linearAttenuation * dist + quadraticAttenuation * dist * dist );
lightDir = normalize(light_pos[i].xyz - pos);
}
else { // Directional light
attenFactor = 1.0;
lightDir = normalize(light_pos[i].xyz);
}
lightAmbientDiffuse += vec4(ambient_light * attenFactor, 0.0);
lightAmbientDiffuse += vec4(light_color[i].rgb * max(dot(normal, lightDir), 0.0) * attenFactor, 1.0);
vec3 r = normalize(reflect(-lightDir, normal));
lightSpecular += light_color[i] * pow(max(dot(r, -eyeDir), 0.0), shininess) * attenFactor;
}
vec4 texColor = texture2D(u_texture0, vTexCoord.st);
gl_FragColor = texColor * (lightAmbientDiffuse) + lightSpecular;
}
The pos variable is the uniform I send from my application.