Multiple Point lights in Deferred Rendering

Started by
1 comment, last by MJP 7 years, 6 months ago

This can be a really dumb question but I can't find the correct way to do it.

I have deferred rendering working but with a single light of each(directional, point, spot). Which is a waste because deferred rendering is at its finest when used with many sources of light at the same time.

But when I try to implement it I don't know how to pass the light information of the scene to the shader that processes all the lights, since HLSL doesn't have dynamic arrays.

I read somewhere that setting a Max. number of lights for the array in HLSL would do it. But then, how to avoid looping through the rest of the light array that is not needed.

For example, let's set the max num of lights to 500. This scene in particular uses only 10 point lights. Should I be sending 500 point light data to the shader but with a boolean that confirms if the point light is active or not? Meaning that only 10 would have active = true.

That's how I think it can be done, but I'm not exactly sure if that's a right way to do it.

Isn't it costly to pass 490 useless data to the shader?

And one question regarding rendering pipeline. What part of the hardware would "bottleneck" when passing a large amount of data to the shader? I know processing through the data in the shader would be GPU's work, but what about just passing the information?

Thank you very much.

Advertisement

May have a look at this tutorial:

http://www.catalinzima.com/xna/tutorials/deferred-rendering-in-xna/point-lights/

I think it's one of the best tutorial series to get into deferred rendering. And of course there is lot of space for improvements.

Maybe it's a little bit old but the idea behind still works.

tl;dr: Draw a sphere mesh in the lightpass for every light. You can use instancing here or try it first with single drawcalls.

Then use the depth information and the albedo-color from your model-drawpass to light the scenery.

Only pixel within the mesh will get checked and colored if there are inside of the lightsource.

Just pass a light count as a variable in your constant buffer:

cbuffer LightCBuffer : register(b0)
{
    PointLight PointLights[MaxLights];
    uint NumPointLights;
}
 
float4 PSMain() : SV_Target0
{
    float3 output = 0.0f;
    for(uint i = 0; i < NumPointLights; ++i)
        output += ProcessPointLight(PointLights[i]);
}

The code of "sending" data to the GPU through a constant buffer is almost entirely on the CPU. The expensive part is usually mapping the buffer, which requires the driver to do some work behind the scenes.

This topic is closed to new replies.

Advertisement