glsl - OpenGL Converting from Directional/point to Spotlight -


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