c++ - opengl shader directional lights specular reflection increasing with distance -
the title says all.. using opengls built in lighting system, specularlight not increase or decrease distance object, shader implementation does.
vertex shader:
#version 330 layout (location = 0) in vec3 position; layout (location = 1) in vec2 texcoord; layout (location = 2) in vec3 normal; out vec2 texcoord0; out vec3 normal0; out vec3 worldpos0; uniform mat4 transform; uniform mat4 normalrotation; uniform mat4 transformprojected; void main() { gl_position = transformprojected * vec4(position, 1.0); texcoord0 = texcoord; normal0 = normalize((normalrotation * vec4(normal, 0.0))).xyz; worldpos0 = (transform * vec4(position, 1.0)).xyz; }
fragment shader:
#version 330 in vec2 texcoord0; in vec3 normal0; in vec3 worldpos0; out vec4 fragcolor; struct baselight { vec3 colordiffuse; vec3 colorspecular; float intensitydiffuse; }; struct directionallight { baselight base; vec3 direction; }; uniform vec3 tint; uniform sampler2d sampler; uniform vec3 eyepos; // camera pos uniform vec3 ambientlight; uniform vec3 emissivelight; //material uniform float specularintensity; uniform float specularpower; uniform directionallight directionallight; vec4 calclight(baselight base,vec3 direction, vec3 normal) { float diffusefactor = dot(normal, -direction); vec4 diffusecolorfinal = vec4(0,0,0,0); vec4 specularcolorfinal = vec4(0,0,0,0); if(diffusefactor > 0) { diffusecolorfinal = vec4(base.colordiffuse,1) * diffusefactor * base.intensitydiffuse; vec3 directiontoeye = normalize(eyepos - worldpos0); vec3 reflectdirection = normalize(reflect(direction, normal)); float specularfactor = dot(directiontoeye, reflectdirection); specularfactor = pow(specularfactor, specularpower); if(specularfactor > 0) specularcolorfinal = vec4(base.colorspecular,1) * specularfactor * specularintensity; } // return diffusecolorfinal + specularcolorfinal; } void main() { vec4 colord = texture(sampler, texcoord0.xy) * vec4(tint,1); vec3 normal = normal0; vec4 totallight = vec4(ambientlight,1) + vec4(emissivelight,1); totallight += calclight(directionallight.base,-directionallight.direction,normal); fragcolor = colord * totallight; }
as can see 2 images specular light takes larger surface area farther camera gets plane.in test opengls built in lighting, doesnt happen. there way fix this? im new lighting, maybe normal directional light sources? help!
im setting eyepos uniform camerapos. dont know if helps.
basically need have distance between fragment , light dist
. can problem directional light though because have direction , distant assumed infinite. maybe switch point light?
when youo have 'dist' use formula
att = 1.0 / (kc + kl*dist + kq*dist^2) kc - constant attenuation kl - linear attenuation kq - quadratic attenuation
simpler version (only kq used, rest set 1.0):
float attenuation = 1.0 / (1.0 + light.attenuation * pow(distancetolight, 2));
then in lighting equation multiply calculated color att
factor:
vec4 finalcolor = ambient + (diffusecolorfinal + specularcolorfinal)*att
http://www.ozone3d.net/tutorials/glsl_lighting_phong_p4.php#part_4
http://tomdalling.com/blog/modern-opengl/07-more-lighting-ambient-specular-attenuation-gamma/
Comments
Post a Comment