Advertisement

Looking For Spotlight Shader Tutorial

Started by March 04, 2005 08:01 PM
12 comments, last by mattm 19 years, 8 months ago
I am looking for a tutorial on how to implement spotlight using programmable shaders. I need to know how to calculate per-vertex lighting in the VS given a spotlight's parameters (origin, falloff, etc.), which is then passed to the PS for per-pixel lighting. Can anyone please point me to a link or post some code samples? Thanks a lot.
if you dont want falloff, a spot light is just testing the dot product of the
light vector with the vector towards the pixel.
and then you could add a penumbra sector around the outside of the cone.
do it that way, i dare ya. :) i just came up with it then, cheeky grin.

do it per pixel, per pixel is way more fun. hehe
stop picking your nose
Advertisement
I got the spotlight working in the vertex shader. The problem now is that per-vertex lighting doesn't look very good when the lit surface is close to the view, as you can see from the screenshot below the edge of the cone is jagged and not round. I guess this is where per-pixel lighting can fix the problem, but I'm not sure how to do it...

put the vector to each vertex as a texture coordinate in the input of the
pixel shader (output of the vertex shader) this will linearly interpolate
along the triangle. you have to normalize it in the pixel shader before you
use it and use this interpolated vector to find the vector to each individual
pixel.
all your lighting code goes from the vertex shader to the pixel shader for more
gpu to be expended.
note to use per pixel lighting with more than one light you have to do a bit of
spacial subdivision to get it running fast enough, but if all you need is a
torch for the main player and maybe a little more lighting then perhaps you
wont need to.

thats just off the top of my head.

your games looking sick sofar btw.

[Edited by - Magnus Wootton on March 5, 2005 10:02:32 PM]
stop picking your nose
Meh, if all you're looking at is a flashlight for the player, a projected texture should sort you out. That's how games like Half-Life do it.

Richard "Superpig" Fine - saving pigs from untimely fates - Microsoft DirectX MVP 2006/2007/2008/2009
"Shaders are not meant to do everything. Of course you can try to use it for everything, but it's like playing football using cabbage." - MickeyMouse

Quote: Original post by superpig
Meh, if all you're looking at is a flashlight for the player, a projected texture should sort you out. That's how games like Half-Life do it.

I'm not sure how that works... I am also working with PS 1.3 and I can't use texture coordinates directly. I'm to go play half life 2 for a while and observe the way it's flash light works, and maybe I'll come out with something...
Advertisement
Quote: Original post by Tybon
Quote: Original post by superpig
Meh, if all you're looking at is a flashlight for the player, a projected texture should sort you out. That's how games like Half-Life do it.

I'm not sure how that works... I am also working with PS 1.3 and I can't use texture coordinates directly. I'm to go play half life 2 for a while and observe the way it's flash light works, and maybe I'll come out with something...
I meant Half-Life 1, actually - I'm not sure how HL2 does it.

Usually, your surfaces have got two parts to them - lighting (either in the form of lightmap textures, or vertex lighting), and the actual surface texture. You multiply the two together to produce the final result, allowing your standard texture set to be used in different lighting conditions.

To do this projective texturing, you'd project a circle onto the geometry, and add it to the value taken from the lightmap/vertlighting before multiplying by the texture. If you're using lightmaps:
ps_1_1tex t0   ; lightmaptex t1   ; flashlight texture, with texture coordinates done projectivelytex t2   ; actual surface textureadd r0, t0, t1     ; calculate total lighting at this point - environment light + flashlightmul r0, r0, r2     ; multiply by texture color


Nice and simple. It gives you a lot of control over the appearance of your flashlight, too - if you want to add dark spots or cracks to simulate a dirty lens, you can easily do that just by messing with the texture a bit.

Richard "Superpig" Fine - saving pigs from untimely fates - Microsoft DirectX MVP 2006/2007/2008/2009
"Shaders are not meant to do everything. Of course you can try to use it for everything, but it's like playing football using cabbage." - MickeyMouse

Quote: Original post by superpig
Usually, your surfaces have got two parts to them - lighting (either in the form of lightmap textures, or vertex lighting), and the actual surface texture. You multiply the two together to produce the final result, allowing your standard texture set to be used in different lighting conditions.

To do this projective texturing, you'd project a circle onto the geometry, and add it to the value taken from the lightmap/vertlighting before multiplying by the texture. If you're using lightmaps:
ps_1_1tex t0   ; lightmaptex t1   ; flashlight texture, with texture coordinates done projectivelytex t2   ; actual surface textureadd r0, t0, t1     ; calculate total lighting at this point - environment light + flashlightmul r0, r0, r2     ; multiply by texture color


Nice and simple. It gives you a lot of control over the appearance of your flashlight, too - if you want to add dark spots or cracks to simulate a dirty lens, you can easily do that just by messing with the texture a bit.

Thanks for the reply. I'm kind of a newb and the part I don't understand is "with texture coordinates done projectively". Currently I use a heightmap for my terrain, and I calculate the vertex lighting in the VS, I pass that value to the PS and it is multipled by the surface texture to get the final color. I don't know how to blend in a flashlight texture. I mean if I do it like the surface texture then there will just be a whole bunch of flashlight circles tiled over the terrain. Please help me with the texture coordinates for the flashlight...
lightmaps are harder than per pixel lighting, but yeh if you dont have 2.0
it makes it difficult... i only use hlsl.

i wouldnt use lightmaps if i were you, too hard.
stop picking your nose
Ok, after going through a few articles on shadow maps, I got the projected spotlight texture working:



This is the per-vertex spotlight with penumbra:



Ideally, if I had PS 2.0, I would do per-pixel spotlight, because I think looks more realistic than the projected texture. But since I only got PS 1.3, I guess I have to stick with projected texture. Now I need to go figure out how to add in a falloff distance and attenuation to the projected texture...

This topic is closed to new replies.

Advertisement