A
Austin Scola
Guest
Hey I am trying to use a shader to add simple normal map lighting to my game. I am about 90% there, but there seems to be a discrepancy between the game coordinate system and my shader's coordinate system, and I can't seem to wrap my head around how to get them to line up. I know that it probably has something to do with which gm_matrix I need to multiply by, and I have tried to figure it out in the docs with no success. If anybody could help me out or point me in the right direction (no pun intended) I would greatly appreciate it!
This is the sort of result I am getting:
The location of the light is on the border of the light/dark region (NOT in the middle of the bright region) and it seems to be pointing in the wrong direction?
Here is my vertex code:
Here is my fragment code:
Here is the code that calls the shader from the object:
This is the sort of result I am getting:
The location of the light is on the border of the light/dark region (NOT in the middle of the bright region) and it seems to be pointing in the wrong direction?
Here is my vertex code:
Code:
attribute vec3 in_Position; // (x,y,z)
//attribute vec3 in_Normal; // (x,y,z) unused in this shader.
attribute vec4 in_Colour; // (r,g,b,a)
attribute vec2 in_TextureCoord; // (u,v)
varying vec2 v_vTexcoord;
varying vec4 v_vColour;
varying vec3 v_vPosition;
void main()
{
vec4 object_space_pos = vec4( in_Position.x, in_Position.y, in_Position.z, 1.0);
gl_Position = gm_Matrices[MATRIX_WORLD_VIEW_PROJECTION] * object_space_pos;
v_vColour = in_Colour;
v_vTexcoord = in_TextureCoord;
v_vPosition = (gm_Matrices[MATRIX_WORLD] * object_space_pos).xyz;
}
Code:
/// Normal Map Lighting Shader
// slighly modified from https://github.com/mattdesl/lwjgl-basics/wiki/ShaderLesson6#GeneratingNormals
// attributes from vertex shader
varying vec4 v_vColour;
varying vec2 v_vTexcoord;
varying vec3 v_vPosition;
// our texture samplers
// gm_BaseTexture is the diffuse map
uniform sampler2D normal_texture; //normal map
// values used for shading algorithm...
uniform vec2 Resolution; //resolution of screen
uniform vec3 LightPos; // light position in pixels
uniform vec4 LightColor; //light RGBA -- alpha is intensity
uniform vec4 AmbientColor; //ambient RGBA -- alpha is intensity
uniform vec3 Falloff; //attenuation coefficients
void main()
{
// RGBA of our diffuse color
vec4 DiffuseColor = texture2D(gm_BaseTexture, v_vTexcoord);
// RGB of our normal map
vec3 NormalMap = texture2D(normal_texture, v_vTexcoord).rgb;
// the delta position of the light
vec3 LightDir = LightPos - v_vPosition;
// 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); // convert to range -1.0 to 1.0, then normalize
vec3 L = normalize(LightDir);
// Pre-multiply light color with intensity
// Then perform "N dot L" to determine our diffuse term
vec3 Diffuse = (LightColor.rgb * LightColor.a) * clamp(dot(N, L), 0.0, 1.0);
// pre-multiply ambient color with intensity
vec3 Ambient = AmbientColor.rgb * AmbientColor.a;
// 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;
gl_FragColor = v_vColour * vec4(FinalColor, DiffuseColor.a);
}
Here is the code that calls the shader from the object:
Code:
/// @description Call the normal map shader
shader_set(shd_normal_map);
// get uniform handles
resolution = shader_get_uniform(shd_normal_map, "Resolution")
light_pos = shader_get_uniform(shd_normal_map, "LightPos")
light_color = shader_get_uniform(shd_normal_map, "LightColor")
ambient_color = shader_get_uniform(shd_normal_map, "AmbientColor")
falloff = shader_get_uniform(shd_normal_map, "Falloff")
//provide the normal map to the shader
t_normal_map = shader_get_sampler_index(shd_normal_map, "normal_texture");
spr = sprite_get_texture(spr_wall_normal, 0); //second number is the subimage!
texture_set_stage(t_normal_map, spr);
// set the uniforms
shader_set_uniform_f(resolution, 1024.0,768.0)
shader_set_uniform_f(light_pos, mouse_x, mouse_y, -10.0)
shader_set_uniform_f(light_color, 1.0, 0.8, 0.6, 1000.0)
shader_set_uniform_f(ambient_color, 0.6, 0.6, 1.0, 0.2)
shader_set_uniform_f(falloff, 4.0, 3.0, 1.0)
draw_self();
shader_reset();