[SOLVED] Array'ed effect parameters are not working.

I am finally able to convert my engine over to Monogame after waiting years for VertexBufferBindings to be added so thank you so much for that! I am having problems with my light rendering shader. This of course works as intended in XNA 4.0 but it almost seems like the shader has no data when it’s actually running on the card.

Pausing the code while running lets me peak at the data currently in the parameters and they are correct. I have 1 light enabled and it has a range of 10, a color of blue, and is located at 0,2,0.

At the top of my HLSL file.

The code itself.

The problem I am having is that it appears that all the array entries are actually null/0 even though the debugger says they have the correct information. Light_Enabled always equals false, Light_Range always equals 0 etc. Even if I tell my PS to return Light_Color[0], it returns 0,0,0,0.

I am using MonoGame 3.6 on a GTX 1070 with the latest drivers. Windows DirectX application. PS 5_0, VS 5_0

Just to make sure I wasn’t going crazy, I removed the array and just made it 1 standard light. It works correctly.

This is a MonoGame bug. There’s an open issue for this on GitHub, but no one has looked into it yet.
Issue: https://github.com/MonoGame/MonoGame/issues/5297

It works for me, maybe maxlights has to be predefined.

#define MAXLIGHT 20

float3  PointLightPosition[MAXLIGHT];
float4  PointLightColor[MAXLIGHT];
float   PointLightIntensity[MAXLIGHT];
float3  PointLightDirection[MAXLIGHT];
float   PointLightRadius[MAXLIGHT];

then in the shader…

 float4 diffusePoint = float4(0, 0, 0, 0);
    float4 specularPoint = float4(0, 0, 0, 0);

    for (int i = 0; i < MaxLightsRendered; i++)
        float3 DirectionToLight = PointLightPosition[i] - worldPos;
        float DistanceSq = lengthSquared(DirectionToLight);

        float radius = PointLightRadius[i];

on the C# side of things

private const int MaxLightsGpu = 20;
private static readonly Vector3[] PointLightPosition = new Vector3[MaxLightsGpu];
private static readonly Vector4[] PointLightColor = new Vector4[MaxLightsGpu];
private static readonly float[] PointLightIntensity = new float[MaxLightsGpu];
private static readonly float[] PointLightRadius = new float[MaxLightsGpu];
private static readonly Vector3[] PointLightDirection = new Vector3[MaxLightsGpu];

public static void Initialize(Effect lightingEffect)
    _lightingEffectPointLightPosition = lightingEffect.Parameters["PointLightPosition"];
    _lightingEffectPointLightColor = lightingEffect.Parameters["PointLightColor"];
    _lightingEffectPointLightIntensity = lightingEffect.Parameters["PointLightIntensity"];
    _lightingEffectPointLightDirection = lightingEffect.Parameters["PointLightDirection"];
    _lightingEffectPointLightRadius = lightingEffect.Parameters["PointLightRadius"];
    _lightingEffectMaxLightsRendered = lightingEffect.Parameters["MaxLightsRendered"];

    LightTiles = new int[LightTilesHeight*LightTilesWidth];

and setting the shader params


here is the result (have to click on the image since it’s >500 pixels)

it’s not a new gif, but I’ve verified it still works.

@Jjagg Hmm. Good to know that others are having the same ploblem.

@kosmonautgames No dice for me. I replaced mine with a define and it has the same problem. What platform are you targeting?

What platform are you targeting?


Well crap :wink:

-20 characters required-

how do you pass your lights to the shader?

Count always equals 4

try having a local array and passing the whole array before drawing


private Vector3[] positions = new Vector3[maxlights];


Yes! That got it. That’s how I did it in XNA but Monogame removed the option to send a boolean array, forcing the change. I’ll adopt your style of sending an int for the number of lights to actually draw. Thanks so much!