multiple lights

Started by
4 comments, last by Matt Aufderheide 16 years, 10 months ago
I am setting light position, radius, and colour, as constants in my preRender step. Then, in my shader: // light 0 (c9 = pos, c10 = radius, c11 = rgb) "sub r1.xyz, c9, r0.xyz\n" // vertex to light (v_to_l) "dp3 r1, r1, r1\n" "rsq r2, r1\n" // r2 = 1/dist "rcp r2, r2\n" // r2 = dist "rcp r3, c10.x\n" // r3 = 1/light range "mul r4, r2, r3\n" // r4 = % light range "min r5.x, r4.x, c8.x\n" // clamp r4.x 0->1 "sub r5.xyz, c8.x, r5.x\n" // r5 = 1 - r5.x "mul r6.xyz, r5.xyz, c11.xyz\n" // light 1 (c12 = pos, c13 = radius, c14 = rgb) "sub r1.xyz, c12, r0.xyz\n" // vertex to light (v_to_l) "dp3 r1, r1, r1\n" "rsq r2, r1\n" // r2 = 1/dist "rcp r2, r2\n" // r2 = dist "rcp r3, c13.x\n" // r3 = 1/light range "mul r4, r2, r3\n" // r4 = % light range "min r5.x, r4.x, c8.x\n" // clamp r4.x 0->1 "sub r5.xyz, c8.x, r5.x\n" // r5 = 1 - r5.x "mul r7.xyz, r5.xyz, c14.xyz\n" // light 2 (c15 = pos, c16 = radius, c17 = rgb) "sub r1.xyz, c15, r0.xyz\n" // vertex to light (v_to_l) "dp3 r1, r1, r1\n" "rsq r2, r1\n" // r2 = 1/dist "rcp r2, r2\n" // r2 = dist "rcp r3, c16.x\n" // r3 = 1/light range "mul r4, r2, r3\n" // r4 = % light range "min r5.x, r4.x, c8.x\n" // clamp r4.x 0->1 "sub r5.xyz, c8.x, r5.x\n" // r5 = 1 - r5. "mul r8.xyz, r5.xyz, c17.xyz\n" "add r9.xyz, r7.xyz, r6.xyz\n" // add lights "add r10.xyz, r9.xyz, r8.xyz\n" // add lights "mov oD0.xyz, r10.xyz\n" as you can see - it's a copy and paste for each light, then a final addition at the end into r10. It does enforce a hard-coded limit to the number of lights. Is this a common approach for dealing with multiple lights? Is there a neater way of scaling to multiple lights? (I know I mention directx, but I am asking in a more "general approach" way, so I think this is the correct forum.} thanks!
Advertisement
First off, why are you still using ASM? Please, switch to a high level language! You'll thank yourself for doing so later!

Second, there are a lot of options for doing multiple lights. You can do one light/pass, and compile your shader for just a single light (or multiple light types, but one at a time), or you can make a set of pre-configured combinations of light types and light numbers, OR (and this is the best option!), have your engine automatically determine what is necessary, and dynamically set up and compile the shader as necessary.
Sorry for the assembly, last time I looked at shaders this is how they were written. Is there a high level language that works for both DirectX and OpenGL?

How can I render geometry with one light per pass? If I render a wall with a blue light shining on it, followed by the same geometry with a green light shining on it - it wont mix, the green will overwrite the first pass?

As for dynamically setting up the shader..would you suggest doing that at run-time..or just when you're loading the map and setting things up. I don't want to compile shaders every frame do I?

Thanks!
Quote:Original post by scowak24
Sorry for the assembly, last time I looked at shaders this is how they were written. Is there a high level language that works for both DirectX and OpenGL?

How can I render geometry with one light per pass? If I render a wall with a blue light shining on it, followed by the same geometry with a green light shining on it - it wont mix, the green will overwrite the first pass?

As for dynamically setting up the shader..would you suggest doing that at run-time..or just when you're loading the map and setting things up. I don't want to compile shaders every frame do I?

Thanks!


You can use Cg - it can be compiled for both DX and OGL.

Drawing one light per pass means you're going to use additive blending. You start with black (conceptually - what you're really going to do is render the first light without blending), and you add the contributions for each light, "building up" the image one light at a time.

You definitely don't want to be doing it at run time, no. What I suggested might be a little bit advanced for what you're doing right now, but the idea is that you (in some way) figure out which combinations of lights you're going to be using, and compile the shaders for each of those combinations at load time, so that you minimize your batches by drawing multiple lights at once.

Hope that helps!
Thanks for the help! I can definitely have a number of shaders for different light combinations.
Quote:Original post by scowak24
Sorry for the assembly, last time I looked at shaders this is how they were written. Is there a high level language that works for both DirectX and OpenGL?

How can I render geometry with one light per pass? If I render a wall with a blue light shining on it, followed by the same geometry with a green light shining on it - it wont mix, the green will overwrite the first pass?


No one uses ASM anymore... for Direct X use HLSL and for OpenGl GSLANG and/or (I guess) CG -- they are all very similar in form and function..

Its easy to render with one light per pass.. just make sure you blend each pass additively...there is no special difficulty...this assumes you are using point lights with attenuation.

However if you have multiple lights, its usually better to render a certain number of passes with a set number of lights per pass. For per-pixel lights you cant do more than 2-3 lights in a pass, depending on shader version, and more than 6-8 lights gets slow...use shader LOD

This topic is closed to new replies.

Advertisement