问题
I'm working on a game engine in C++ and Direct3D11 and I want now to add a variable number lights to the scene. Up to date, I managed to add and render simple lights of a count that was already known and coded in the shader programs.
In shader.fx:
static const int LightsCount= 4;
struct NF3D_LIGHT
{
// Members...
};
cbuffer Light : register(b5)
{
NF3D_LIGHT light[LightsCount];
};
...
// And the pixel shader function:
float4 PS(PS_INPUT input) : SV_Target
{
for(int i = 0; i < LightsCount; i++)
{
// Process each light and return the final pixel colour
}
}
And this works fine. But if I try to:
cbuffer LIGHTS_COUNT : register(b13)
{
int LightsCount;
}
to make the number of lights vary according to what is happening in the game, this does not work. I know I could give LightsCount
a big value right at the beginning of the application and add lights to the array but I find this method complicated, fixed and not efficient.
Does anybody know how to solve this problem? Thank you in advance.
回答1:
The general problem of accessing a variable size array (with runtime defined size) from shader might be solved differently, depending on array size, frequency of data changes and hardware you are targeting.
There are several techniques that comes to mind:
If your array is small, the easiest way is to just pass a constant buffer with a fixed size array and current size as you've suggested.
The way that will work on virtually any hardware is to write data into a texture and Sample or Load it from shader. You can only read primitive types (
float
,float4
, etc.), so you'll need to implement proper indexing into a texture to read out complex objects (struct
s).On Shader Model 5 hardware (and on some SM 4 too) you can use UAVs and StructuredBuffers to read structured data from buffers.
If you have really complex computations that involve arrays, and if target hardware allows you to do so, you might want to move processing to either Compute Shader or even to OpenCL or CUDA kernel.
Considering given problem, which is classic lighting, I would say that 99% of what I've seen use method 1. You don't really have more than a dozen of lights in a scene most of the time anyway.
来源:https://stackoverflow.com/questions/34456099/d3d11-variable-number-of-lights-in-hlsl