Sign in to follow this  
Enalis

Interesting Lighting Issue W/Screenshots!

Recommended Posts

So I just added a simple multipass lighting solution to my engine because I wanted to support some older hardware, normally I use a deferred renderer. But some of the hardware I want this to work on doesn't have the greatest FBO format support... so I got it all working except for two problems.

1. When the view frustum is near being paralel to a surface, there's an odd problem in the lighting where it seems to fill or not-fill (depending on the angle) entire triangles. I am using a standard per pixel lighting shader which I will post below along with screenshots.

Problem one screenshots...
High Angle (no issue)
[img]http://img163.imageshack.us/img163/8576/noissue.png[/img]


Low Angle (with issue):
[img]http://img84.imageshack.us/img84/3592/withissue.png[/img]


Here's my shader:
vert:
[code]

varying vec3 normal, tangent, bitangent;
varying vec3 light, light_half;
varying float light_distance;


uniform vec3 light_position;
void main(){
normal = normalize(gl_NormalMatrix * gl_Normal);
tangent = normalize(gl_NormalMatrix * gl_MultiTexCoord1.xyz);
bitangent = normalize(gl_NormalMatrix * gl_MultiTexCoord2.xyz);

vec4 eye_position = gl_ModelViewMatrix * gl_Vertex;
vec3 transformed_light_position = vec3(gl_ModelViewMatrix * vec4(light_position, 1.0));
vec3 temp = vec3(transformed_light_position - eye_position.xyz);
light = normalize(temp);
light_half = normalize(light + eye_position.xyz);
light_distance = length(temp);

gl_Position = ftransform();
gl_TexCoord[0].st = gl_MultiTexCoord0.st;
gl_FrontColor = gl_Color;
}
[/code]

frag:
[code]

varying vec3 normal, tangent, bitangent;
varying vec3 light, light_half;
varying float light_distance;

uniform int use_decal_map;
uniform sampler2D decal_map;
uniform int use_normal_map;
uniform sampler2D normal_map;
uniform float material_specularity;
uniform vec4 light_parameters;
uniform vec3 light_color;

void main(){
vec3 normal_vector = normalize(normal);
vec3 tangent_vector = normalize(tangent);
vec3 bitangent_vector = normalize(bitangent);

if (use_normal_map == 1){
mat3 tbn_matrix = mat3(normalize(tangent_vector), normalize(bitangent_vector), normalize(normal_vector));
vec3 normal_map_value = normalize(2.0 * texture2D(normal_map, gl_TexCoord[0].st).xyz - 1.0);
normal_vector = normalize(tbn_matrix * normal_map_value);
}

vec3 light_vector = normalize(light);
vec3 half_vector = normalize(light_half);
float normal_dot_light_vector = 0.0;
float normal_dot_half_vector = 0.0;
float light_factor = 0.0;

vec4 color_out = vec4(gl_Color.rgb, 1.0);

if (use_decal_map == 1){
color_out *= texture2D(decal_map, gl_TexCoord[0].st);
}

normal_dot_light_vector = max(dot(normal_vector, light_vector), 0.0);
if (normal_dot_light_vector > 0.0){
float attenuation_factor = (1.0 / (light_parameters.x + light_parameters.y * light_distance + light_parameters.z * light_distance * light_distance));
attenuation_factor *= (1.0 - pow((light_distance / light_parameters.w), 2.0));
light_factor += normal_dot_light_vector * attenuation_factor;
normal_dot_half_vector = max(dot(normal_vector, half_vector), 0.0);
light_factor += pow(normal_dot_half_vector, 16.0) * material_specularity * attenuation_factor;
}

color_out *= vec4((light_color * light_factor), 1.0);

gl_FragColor = color_out;
}
[/code]


NOTES:
- this is using glDepthFunc(GL_LEQUAL)
- as well as glBlendFunc(GL_ONE, GL_ONE)
- Not on an FBO

Share this post


Link to post
Share on other sites
not sure about your issue, but this is the 2nd time I've seen someone use the tbn matrix in the pixel shader. If this is not deferred rendering, you want to simply transform your light into the TBN space, not the textures pixels individually into camera space. Especially if doing multipass, your prob gonna need to save as much power as possible.

Share this post


Link to post
Share on other sites
I'll make that modification but in the meantime, anyone have any ideas? Could this be hardware related? The "older" hardware I talked about is an intel card :(.

Share this post


Link to post
Share on other sites
It appears to be in the light distance computation in the vertex shader... which makes sense that it's showing up as triangles because I don't think varying floats can really be interpolated with the other vectors to the fragment shader. Still not sure why it's happening though.

Share this post


Link to post
Share on other sites
Well think of it this way:

(picture is slightly warped, the star should be directly above the center of the flat quad.)
[code]
* = light
[ ] = quad

*

[ ]
[/code]

[ distance = ] distance. So your interpolating say 5 to interpolate to 5. Each pixel on the quad has its own distance (IE the center should be maybe 4 , so it would be distance from left to right, interpolate from 5 to 4 in middle back to 5 on the right. Your using vertex distance so it can only interpolate from 5 to 5 since they are both 5 away from the light. This is the same reason you cant get specular phong highlights on a per-vertex lighting.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this