   Pixel Shader Spotlight with HLSL
  Hi, I'm trying to make a spotlight work on a model with a low verticy count but I'm new to HLSL.I've got this:float4x4 worldMatrix;float4x4 worldViewProjectionMatrix;struct VS_INPUT{float3 pos : POSITION;float2 uv : TEXCOORD0;float3 norm : NORMAL;};struct VS_OUTPUT{float4 pos : POSITION;float2 uv : TEXCOORD0;float3 lightDir : TEXCOORD1;float3 norm : TEXCOORD2;};VS_OUTPUT VS(VS_INPUT IN){VS_OUTPUT OUT = (VS_OUTPUT)0;float3 lightPos = float3(0.0f, 0.0f, 5.0f);OUT.pos = mul(float4(IN.pos, 1.0f), worldViewProjectionMatrix);OUT.norm = normalize(mul(IN.norm, worldMatrix));OUT.uv = IN.uv;OUT.lightDir = normalize(mul(float4(IN.pos, 1.0f), worldMatrix).xyz - lightPos);return OUT;}float4 PS(VS_OUTPUT IN) : COLOR{float3 lightDirection = float3(0.0f, 0.0f, 1.0f);float theta = 10.0f;float phi = 30.0f;float f = dot(IN.norm,IN.lightDir);float angle = acos(dot(IN.lightDir,normalize(lightDirection)));if (angle > radians(phi)) f = 0.0f;else if (angle < radians(theta)) f = 1.0f;else f = smoothstep(radians(phi),radians(theta),angle);return float4((float4(0.0f,1.0f,0.0f,1.0f)*f).xyz,1.0f);}technique main{pass{VertexShader = compile vs_2_0 VS();PixelShader = compile ps_2_0 PS();}}...but it doesn't show light if there are no verticies nearby (e.g. straight onto the middle of a face is black.)The variables I have put the code above are examples, Im my application the light is at the same position as the camera and looking the same way.   
  I think your problem is that you are transforming your vertex position and normal into world space, but doing lighting calculations in view space.If that doesn't fix it post your actual code, and add some comments if you need to explain anything. It might make it easier to help.I would I highly recommend looking at this online book. Its got some really clear examples. And even though its for DX10 most of the basic lighting stuff is line for line the same.Here is a few other things to take note ofOUT.norm = normalize(mul(IN.norm, worldMatrix));will give you bad normals if you have non-uniform scaling ( x != y != z ) you want the inverse transpose of the worldviewMatrix.calculate the light direction per pixel (at least re-normalize it). See here for some info on the why you can lose the normalized property while interpolating between to normalized vectors.Here you are setting f with nDotl then immediately writing over it so you lose that part of the equation:float f = dot(IN.norm,IN.lightDir);float angle = acos(dot(IN.lightDir,normalize(lightDirection)));if (angle > radians(phi)) f = 0.0f;else if (angle < radians(theta)) f = 1.0f;else f = smoothstep(radians(phi),radians(theta),angle);also doing the acos is extra work, you should supply your phi and theta as cos(phi) and cos(theta) when you send them to the pixel shader. doing them once per light instead of per pixelfor you PS return if you wrote it asreturn float4( 0.0f, f, 0.0f ,1.0f);it would generate less instructions ( though the compiler likely optimizes to this ) and is more readable.   ;  Thanks for the help. I took a lootk at what you said but it still didn't work.Can you help me start from scratch because I've made my code a bit confusing now, always a bad move.What are the key points I have to do in the vertex shader and the pixel shader to achieve a pixel shaded spotlight?   ;  My vertex shader is really basic for lighting:struct VOUT{  float4 hposition;  float3 vposition; // Position in view space  float3 vnormal;   // Normal in view space}VOUT LightingVS(  float3 position : POSITION0,  float3 normal   : NORMAL0 ){  VOUT vout;  vout.hposition = mul( float4( position, 1.0f ), wvpMatrix );  vout.vposition = mul( float4( position, 1.0f ), wvMatrix  );  vout.normal    = mul( float4( normal,   0.0f ), nrmMatrix ); // nrmMatrix == inverse transpose of wvMatrix}I then do all lighting calculations in the pixel shader.for examples on that check out the spot light section on this page, while it presents the code as vertex shader, the pixel shader is the same code except that you already have the position and normal transformed.   ;  Ok thanks, that makes a bit more sense now.When I pass in the world co-ordinates of the light's position, do I have to change it into view space by multiplying it by the view matrix?(just for future reference, how do you put your code in the scroll box?)   ;  I got my light working with this: float4x4 wvpMatrix;float4x4 wMatrix;float4x4 nrmMatrix;float3 lightDirection;float3 lightPosition;float theta;float phi;sampler2D samp : register(s0);struct VOUT{  float4 hposition : POSITION;  float3 wposition : TEXCOORD0; // Position in view space  float3 wnormal   : TEXCOORD1; // Normal in view space  float2 uv   : TEXCOORD2; // Texture coordinates};VOUT LightingVS(  float3 position : POSITION,  float3 normal   : NORMAL,  float2 uv  : TEXCOORD0 ){  VOUT vout;  vout.hposition = mul( float4( position, 1.0f ), wvpMatrix );  vout.wposition = mul( float4( position, 1.0f ), wMatrix  );  vout.wnormal   = normalize(mul( float4( normal,   0.0f ), nrmMatrix )); // nrmMatrix = inverse transpose of wMatrix  vout.uv = uv;  return vout;}float4 LightingPS(  VOUT IN) : COLOR{  float3 vLight = normalize(lightPosition - IN.wposition);  float NdotL = max(0.0f, dot(IN.wnormal, vLight));  float cosAngle = max(0.0f, dot(-lightDirection, vLight));  float spotAtten = smoothstep(phi, theta, cosAngle);  float4 color = tex2D(samp, IN.uv.xy);  return float4((color*NdotL*spotAtten).xyz, 1.0f);}technique main{pass{VertexShader = compile vs_2_0 LightingVS();PixelShader = compile ps_2_0 LightingPS();}}I'm using this to light a cube and it works fine if the world matrix position is 0,0,0. When the world matrix changes, I update the matricies in my shader but the cube doesn't light up.How can I make the light work on the cube wherever it is in world space?   