title: WebGl Spotlight Shader
body: <p>I have been trying to program a basic webgl spotlight shader, but no matter how hard I try, I cannot get the spotlights position to be relative to the world.<br><br>The code that I am currently using is below, I have tried almost every coordinate frame that I can to get this working, but no matter what I do, I only get partially correct results. <br><br>
  For example if I switch to world coordinates the spotlights position will be correct, but it will only reflect off one object, or if I use the view space the light will work but it's position is relative to the camera.<br><br>
  In it's current state, the spotlight seems to be relative to each objects frame. (Not sure why.) <br>Any help in solving helping this issue is greatly appreciated.</p>
  
  <p><b>Vertex Shader:</b></p>
  
  <pre><code>attribute vec4 vPosition;
  attribute vec4 vNormal;
  attribute vec2 vTexCoord;
  
  varying vec3 L, E, N,D;
  varying vec2 fTexCoord;
  uniform mat4 modelViewMatrix;
  uniform mat4 projectionMatrix;
  uniform mat4 NormalMatrix;
  uniform mat4 View;
  
  uniform vec4 lightPosition;
  uniform vec4 lightDirection;
  uniform vec3 Eye;
  
  void main(){
      L= (modelViewMatrix * lightPosition).xyz; //Light position in eye coordinates
      E = (modelViewMatrix * vPosition).xyz;    //Vertex position in eye coordinates.
      //Normal position in eye coordinate. Transpose(Inverse(modelViewMatrix) * vNormal.
      N=(NormalMatrix * vNormal).xyz;
      D=lightDirection.xyz;//Light direction
      fTexCoord=vTexCoord;
      gl_Position = projectionMatrix * modelViewMatrix * vPosition;
  }
  </code></pre>
  
  <p><b>Fragment Shader:</b></p>
  
  <pre><code>precision mediump float;
  uniform vec4 lDiffuseColor;
  uniform vec4 lSpecular;
  uniform vec4 lAmbientColor;
  uniform float lShininess;
  
  varying vec3 L,E,N,D;
  const float lExponent=2.0;
  const float lCutoff=0.867;
  vec3 lWeight=vec3(0,0,0);
  
  void main(){
  
      vec3 vtoLS=normalize(L - E);//Vector to light source from vertex.
      float Ks=pow(max(dot(normalize(N),vtoLS),0.0),lShininess);
      vec3 specular=Ks* lSpecular.xyz;
      float diffuseWeight=max(dot(normalize(N), -vtoLS),0.0);
      vec3 diffuse=diffuseWeight * lDiffuseColor.xyz;
  
      if(diffuseWeight &gt;0.0){
          float lEffect= dot(normalize(D),normalize(-vtoLS));
          if(lEffect &gt; lCutoff){
              lEffect= pow(lEffect,Ks);
              vec3 reflection= normalize(reflect(-vtoLS,normalize(N)));
              vec3 vEye=-normalize(E);
              float rdotv=max(dot(reflection,vEye),0.0);
              float specularWeight=pow(rdotv,lShininess);
              lWeight= (lEffect * diffuse.xyz  + lEffect * specular.xyz) + vec3(0.5,0,0);
          }   
      }
      lWeight+=lAmbientColor.xyz;
      gl_FragColor=vec4(lWeight.rgb,1);
  
  }
  </code></pre>
  
  <p>Current Output: <a href="http://sta.sh/012uh5hwwlse" rel="nofollow">http://sta.sh/012uh5hwwlse</a></p>