I’m working on a 2D point light system for my game, and I’m passing an HLSL effect to SpriteBatch when I draw. I’ve got the effect working right—I think—but I’m going to run into a problem with it. The problem is, HLSL does not support dynamically sized arrays, and I want to be able to support an arbitrary number of point lights.
Here is the HLSL file:
#if OPENGL
#define SV_POSITION POSITION
#define VS_SHADERMODEL vs_3_0
#define PS_SHADERMODEL ps_3_0
#else
#define VS_SHADERMODEL vs_4_0_level_9_1
#define PS_SHADERMODEL ps_4_0_level_9_1
#endif
texture Texture;
//Arbitrary limit of 4 lights...
float4 lights[4];
sampler TextureSampler = sampler_state{ Texture = <Texture>; };
struct VertexShaderOutput
{
float4 Color : COLOR0;
float2 TextureCoordinate : TEXCOORD0;
};
float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
{
float4 color = tex2D(TextureSampler, input.TextureCoordinate);
//Convert the TextureCoordinate into pixel coordinates
float2 pixelLocation = float2(1280, 720) * input.TextureCoordinate;
//The final light level after calculations are complete
float result = 0;
float currentResult;
for (int i = 0; i < lights.Length; i++)
{
//r and g are the x and y coordinates of the point light
//b is the radius of the light
//a is the opacity or brightness of the light
currentResult = lights[i].b - distance(pixelLocation, float2(lights[i].r, lights[i].g));
currentResult /= lights[i].b;
currentResult *= lights[i].a;
if (currentResult > 0) result += currentResult;
}
//Don't allow light level to go below .2
if (result < .2) result = .2;
return result * color;
}
technique Technique1
{
pass Pass1
{
PixelShader = compile PS_SHADERMODEL PixelShaderFunction();
}
}
I’m pretty new to HLSL, so I apologize if any of that code is laughably bad.
Is there any way I could use this type of point light implementation and allow for an arbitrary or dynamic amount of lights? And is there anything incorrect about the HLSL code?