so working on trying create spotlight in vertex shader, can produce directional and/or point light using phong lighting model.
im finding hard calculate correct angles spotlight, want spotlight comes 0,0,0 in eye space , looks down z co-ord.
i trying make (for now) in cone bright white , outside dark
#version 130 uniform mat4 model_view_matrix; uniform mat4 projection_matrix; uniform mat3 normal_matrix; uniform int light_mode; uniform vec4 light_pos; uniform vec3 light_ambient; uniform vec3 light_diffuse; uniform vec3 light_specular; uniform vec3 mtl_ambient; uniform vec3 mtl_diffuse; uniform vec3 mtl_specular; uniform float mtl_shininess; // spotlight test const float spotcutoff = 100.00f; in vec3 position; in vec3 normal; in vec2 texcoord; out vec2 st; out vec4 litcolour; vec3 phonglight(in vec4 position, in vec3 norm) { // s direction light vertex vec3 s; if (light_pos.w == 0.0) { s = normalize(light_pos.xyz); } else { s = normalize(vec3(light_pos - position)); } // v direction eye vertex vec3 v = normalize(-position.xyz); // r direction of light reflected vertex vec3 r = reflect(-s, norm); vec3 ambient = light_ambient * mtl_ambient; // diffuse component float sdotn = max(dot(s,norm), 0.0); vec3 diffuse = light_diffuse * mtl_diffuse * sdotn; // specular component vec3 spec = vec3(0.0); if (sdotn > 0.0) spec = light_specular * mtl_specular * pow(max(dot(r,v), 0.0), mtl_shininess); return ambient + diffuse + spec; } vec3 spotlight(in vec4 position, in vec3 norm) { vec3 ambient = vec3(0.2, 0.2, 0.2); vec3 lightdir = normalize(vec3(light_pos - position)); vec3 spotdir = vec3(0.0, 0.0, -1.0); float angle = degrees(acos(dot(spotdir, lightdir))); //angle = max (angle, 0); if ((angle) < spotcutoff) { return vec3(1.0, 1.0, 1.0); } float dist = sqrt(positon.x * position.x + position.y + position.y + position.z * position.z); if (dist < 1) { return vec3(1.0,1.0,0.0); } return vec3(0.2, 0.2, 0.2); } void main(void) { // convert normal , position eye coords vec3 eyenorm = normalize(normal_matrix * normal); vec4 eyepos = model_view_matrix * vec4(position, 1.0); // no lighting effect if (light_mode == 0) { litcolour = vec4(1.0, 1.0, 1.0, 1.0); } // directional overhead light else if (light_mode == 1) { litcolour = vec4(phonglight(eyepos, eyenorm), 1.0); } // point light else if (light_mode == 2) { litcolour = vec4(phonglight(eyepos, eyenorm), 1.0); } else if (light_mode == 3) { litcolour = vec4(spotlight(eyepos, eyenorm), 1.0); } //litcolour = vec4(normal*1000, 1.0); gl_position = projection_matrix * eyepos; st = texcoord; }
your spotlight defined position (ps) , direction (ds). every vertex @ position vp can compute d=vp-ps, normalize dn=normalize(d), , dot(dn,ds) give angle in spotlight. scale or compare cut off scalar!
alternatively, , in long term better, think of spotlight camera. same camera: model , view matrix! transform every vertex space, , project x,y,z,w x,y,z. z distance useful lighting , x,y can use in texture has round shape (or other).
one thing mind both techniques projection: make sure check light points forward! check sign of z or dot product!
Comments
Post a Comment