Problem 1

I am trying to create a spotlight that instead of giving the circle within the spotlight a simple color, applies a texture to it. However, where the texture is supposed to be is only a black circle: image.

Solution: the position I used for my texture wasnt correct.

old and faulty code:

float4 TexturedSpotlightPixelShader(VertexShaderOutput input, float2 TextureCoordinate : TEXCOORD0) : COLOR0
    //I left out all the other code in the shader, full code is at the bottom of the thread
    color = tex2D(SpotlightTextureSampler, TextureCoordinate); 

better code that solved my 'black problem (but created a new one):

float4 TexturedSpotlightPixelShader(VertexShaderOutput input) : COLOR0
    //I left out all the other code in the shader, full code is at the bottom of the thread
    color = tex2D(SpotlightTextureSampler, input.Position); 

where at that point input.Position was set to the worldPosition in the vertexshader (which turned out was the reason for problem 2)

Problem 2

My spotlight now applies the texture, however the texture is repeated multiple times in miniature, as such: image

Solution: I added these lines in the vertex shader:

input.Position3D.w = 1.0f;
output.Position = mul(viewPosition, Projection);

and by adding/changing these lines in the pixelshader:

float2 TextureCoordinates;
TextureCoordinates.x =  input.Position.x / input.Position.w / 2.0f + 0.5f;
TextureCoordinates.y = -input.Position.y / input.Position.w / 2.0f + 0.5f;
color += tex2D(SpotlightTextureSampler, TextureCoordinates);

however, there was still a third problem.

Problem 3

The third and probably (I hope :P) the last problem, my spotlight now only shows a part of my texture and manually resizing the image (in the image file, not in my code) doesnt change what part of the texture is shown, as such: image

Solution: In my vertexshader I used the 2D positions (viewmatrix multiplied with the projection matrix) where I should have used a viewmatrix not based from my camera but from my spotlights point of view (and a projection matrix also for my spotlight's point of view)

My new code:

float4x4 View2, Projection2;

VertexShaderOutput SimpleVertexShader(VertexShaderInput input)
//left out a lot of code here
output.Position = mul(mul(worldPosition, View2), Projection2);

Full Code

Link to the shader code and the link to the xna/c# code.

  • \$\begingroup\$ What happens if instead of going through the branch you immediately return tex2D(SpotlightTextureSampler, TextureCoordinate);? If you still see a black circle then your texture could be empty or not being sampled correctly. \$\endgroup\$ Aug 14, 2013 at 19:33
  • \$\begingroup\$ @AvengerDr if I do that I get a completely black model, thats why I think the problem lies indeed in the sampler (or texture), but I have no clue here exactly the problem lies in my code or how to solve it \$\endgroup\$
    – Hasse Iona
    Aug 14, 2013 at 19:43
  • 1
    \$\begingroup\$ My assumption is that either the texture is not being sampled correctly as AvengerDr said or your TextureCoordinates are wrong and constantly fetch a black Pixel. \$\endgroup\$
    – Luis W
    Aug 14, 2013 at 21:18
  • 1
    \$\begingroup\$ Try replacing the texture with a 1x1 magenta (or some other highly visible color) to see if it's coming through at all. Also try replacing the TextureCoordinate with a constant like float2(0.5, 0.5) and see if you get the color from the center of your texture. \$\endgroup\$ Aug 14, 2013 at 21:54
  • \$\begingroup\$ @LuisW I tried exchanging the content of the sampler I use for my greyscale with this one, to see if my texture then would somehow show up on the greyscale or something else, as to find out whether the problem might be the TextureCoordinates. To my surprise the greyscaleshader kept working flawlessly, litterally nothing changed. It seems as if the samplers dont do anything or at least if the line Texture = <SpotlightTexture>; does completely nothing. Does maybe the problem lie here: sampler SpotlightTextureSampler = sampler_state? The part after the equation is the same for both samplers. \$\endgroup\$
    – Hasse Iona
    Aug 14, 2013 at 21:58

1 Answer 1


You're using the world position as the texture coordinates. Texture coordinates range from 0 to 1 and then the texture repeats itself, so the result of this is that you'll get a copy of the texture squeezed into every 1 unit along the XY axes in world space. If your world units are centimeters then you'll get a copy of the texture in each square centimeter, for instance.

For a spotlight with a texture, you probably want projective texturing. The code in that tutorial is for D3D11, so it won't directly work in XNA, but you should be able to adapt it. The short version is that you have to transform the world position to a coordinate system aligned with the light and divide by z. This will make the texture scale larger as it gets farther from the light, like the image from a projector.

  • \$\begingroup\$ That about does the trick :) I'm just having one last problem and that is that the texure I am using only shows up partially: docs.google.com/file/d/0BxTJskq131LeeTVwQTI5WTFoWjA/…. I've tried manually resizing the actual image (and then removing and readding it to the project) but that doesnt change anything, even though I reduced the image size to less than half it still shows exactly the same part of the texture. I've updated my shader code in the google document at the bottom of my original post \$\endgroup\$
    – Hasse Iona
    Aug 15, 2013 at 9:08
  • 1
    \$\begingroup\$ @HasseIona Youre projecting the texture using the camera viewfrustrum, but you have to use anotherone to get the effect. In your case you will need to create a frustrum around your spot-lights cone. And by creating a frustrum i mean creating the corresponding view and projection matrices. Look closely at the link nathan posted , it´s all there. \$\endgroup\$
    – Luis W
    Aug 15, 2013 at 11:05
  • \$\begingroup\$ The link is down, but you can still read it via the Wayback Machine: web.archive.org/web/20121105034527/http://www.rastertek.com/… \$\endgroup\$
    – wildpeaks
    Nov 5, 2014 at 13:33

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .