Reputation: 21
I can't seem to figure out why my fragment and vertex shaders aren't working. I think I either have my view/perspective wrong, or maybe my normal map has negative values (since black is showing up lit). Either way, I've been at this for days and I can't seem to make traction.
The lighting system I copied into my project is from here: https://github.com/mattdesl/lwjgl-basics/wiki/ShaderLesson6
The only texture with a normal map is the building, and it seems to light up properly, but only from the bottom left. I would think too, that everything else would be totally dark. I also think my lights are supposed to be circular, not directional.
https://www.dropbox.com/s/pd8und7xbqz0kfh/Screenshot%202014-09-22%2023.17.22.png?dl=0
EDIT: Some research indicates that if I set my normal map's r,g,b values to .5 if they're less than .5 in the fragment shader, then at least those images without a normal map do not get lit up indicating part of the issue may have to do with negative normal map values.
ANOTHER EDIT: I'm using ftransform() in my vertex shader. Even if I do the fix above to darken everything not normal mapped, I can't figure out why my light source is angled. Messing with values won't get my light source to be circular unless I set NdotL to max(dot(N, L), 1.0);. This is what leads me to believe either my coordinate system isn't being translated correctly or that I have weird/negative values in my normal map causing issues. I don't understand this math well enough to tell what is going wrong.
One more thing, since I only created a normal for the one building, I'm passing in -1 as the textureId for the other images' normal maps. Could that be a problem?
Here's my vertex shader:
attribute vec4 Color;
varying vec2 vTexCoord;
varying vec4 vColor;
void main() {
vColor = Color;
vTexCoord = gl_MultiTexCoord0;
gl_Position = ftransform();
}
and my fragment shader:
struct Light{
//float intensity;
vec4 color;
vec3 position;
//vec3 direction;
};
//attributes from vertex shader
varying vec4 vColor;
varying vec2 vTexCoord;
//our texture samplers
uniform sampler2D u_texture; //diffuse map
uniform sampler2D u_normals; //normal map
//values used for shading algorithm...
uniform vec2 Resolution; //resolution of screen
uniform Light Lights[50]; //light position, normalized
uniform vec4 AmbientColor; //ambient RGBA -- alpha is intensity
uniform vec3 Falloff; //attenuation coefficients
uniform int LightCount;
void main() {
vec3 Sum = vec3(0.0);
//RGBA of our diffuse color
vec4 DiffuseColor = texture2D(u_texture, vTexCoord);
//set our defuse color to whatever color the image actually is.
//vec4 vColor = DiffuseColor;
//RGB of our normal map
vec3 NormalMap = texture2D(u_normals, vTexCoord).rgb;
//pre-multiply ambient color with intensity
vec3 Ambient = AmbientColor.rgb * AmbientColor.a;
int i = 0;
while(i < LightCount){
vec3 ThisLightPosition = Lights[i].position;
vec4 ThisLightColor = Lights[i].color;
//The delta position of light
vec3 LightDir = vec3(ThisLightPosition.xy - (gl_FragCoord.xy / Resolution.xy), ThisLightPosition.z);
//Correct for aspect ratio
LightDir.x *= Resolution.x / Resolution.y;
//Determine distance (used for attenuation) BEFORE we normalize our LightDir
float D = length(LightDir);
//normalize our vectors
vec3 N = normalize(NormalMap * 2.0 - 1.0);
vec3 L = normalize(LightDir);
float NdotL = max(dot(N, L), 0.0);
//Pre-multiply light color with intensity
//Then perform "N dot L" to determine our diffuse term
vec3 Diffuse = (ThisLightColor.rgb * ThisLightColor.a) * NdotL;
//calculate attenuation
float Attenuation = 1.0 / ( Falloff.x + (Falloff.y*D) + (Falloff.z*D*D));
//the calculation which brings it all together
vec3 Intensity = Ambient + Diffuse * Attenuation;
vec3 FinalColor = DiffuseColor.rgb * Intensity;
Sum += FinalColor;
i++;
}
gl_FragColor = vColor * vec4(Sum, DiffuseColor.a);
}
Upvotes: 0
Views: 1802
Reputation: 21
The problem was my normal maps. I was using the base rbg(0,0,0) as a blank normal, when in reality a blank normal map should be (128,128,255) (I.E. (.5,.5,1)).
Upvotes: 0