2

I have just finished porting my engine from XNA to SharpDX(DX11).

Everything is going really well and I have conquered most of my issues without having to ask for help until now and I'm really stuck, maybe I just need another set of eye to look over my code idk but here it is.

I'm implementing tile based lighting (point lights only for now), I'm basing my code off the Intel sample because it's not as messy as the ATI one.

So my problem is that the lights move with the camera, I have looked all over the place to find a fix and I have tried everything (am I crazy?).

I just made sure all my normal and light vectors are in view space and normalized (still the same).

I have tried with the inverse View, inverse Projection, a mix of the both and a few other bits from over the net but I can't fix it.

So here is my CPU code:

           Dim viewSpaceLPos As Vector3 = Vector3.Transform(New Vector3(pointlight.PosRad.X, pointlight.PosRad.Y, pointlight.PosRad.Z), Engine.Camera.EyeTransform)

            Dim lightMatrix As Matrix = Matrix.Scaling(pointlight.PosRad.W) * Matrix.Translation(New Vector3(pointlight.PosRad.X, pointlight.PosRad.Y, pointlight.PosRad.Z))

Here is my CS shader code:

[numthreads(GROUP_WIDTH, GROUP_HEIGHT, GROUP_DEPTH)]
void TileLightingCS(uint3 dispatchThreadID : SV_DispatchThreadID,     uint3 GroupID : SV_GroupID, uint3 GroupThreadID : SV_GroupThreadID)
{
int2 globalCoords = dispatchThreadID.xy;

uint groupIndex = GroupThreadID.y * GROUP_WIDTH + GroupThreadID.x;

float minZSample = FrameBufferCamNearFar.x;
float maxZSample = FrameBufferCamNearFar.y;

float2 gbufferDim;

DepthBuffer.GetDimensions(gbufferDim.x, gbufferDim.y);

float2 screenPixelOffset = float2(2.0f, -2.0f) / gbufferDim;
float2 positionScreen = (float2(globalCoords)+0.5f) * screenPixelOffset.xy + float2(-1.0f, 1.0f);

float depthValue = DepthBuffer[globalCoords].r;

float3 positionView = ComputePositionViewFromZ(positionScreen, Projection._43 / (depthValue - Projection._33));

// Avoid shading skybox/background or otherwise invalid pixels
float viewSpaceZ = positionView.z;
bool validPixel = viewSpaceZ >= FrameBufferCamNearFar.x &&  viewSpaceZ <  FrameBufferCamNearFar.y;

[flatten] if (validPixel)
{
    minZSample = min(minZSample, viewSpaceZ);
    maxZSample = max(maxZSample, viewSpaceZ);
}

// How many total lights?
uint totalLights, dummy;
InputBuffer.GetDimensions(totalLights, dummy);

// Initialize shared memory light list and Z bounds
if (groupIndex == 0)
{
    sTileNumLights = 0;
    sMinZ = 0x7F7FFFFF;      // Max float
    sMaxZ = 0;
}

GroupMemoryBarrierWithGroupSync();


if (maxZSample >= minZSample) {
    InterlockedMin(sMinZ, asuint(minZSample));
    InterlockedMax(sMaxZ, asuint(maxZSample));
}

GroupMemoryBarrierWithGroupSync();

float minTileZ = asfloat(sMinZ);
float maxTileZ = asfloat(sMaxZ);

// Work out scale/bias from [0, 1]
float2 tileScale = float2(FrameBufferCamNearFar.zw) * rcp(float(2 * GROUP_WIDTH));
float2 tileBias = tileScale - float2(GroupID.xy);

// Now work out composite projection matrix
// Relevant matrix columns for this tile frusta
float4 c1 = float4(Projection._11 * tileScale.x, 0.0f, tileBias.x, 0.0f);
float4 c2 = float4(0.0f, -Projection._22 * tileScale.y, tileBias.y, 0.0f);
float4 c4 = float4(0.0f, 0.0f, 1.0f, 0.0f);

// Derive frustum planes
float4 frustumPlanes[6];
// Sides
frustumPlanes[0] = c4 - c1;
frustumPlanes[1] = c4 + c1;
frustumPlanes[2] = c4 - c2;
frustumPlanes[3] = c4 + c2;
// Near/far
frustumPlanes[4] = float4(0.0f, 0.0f, 1.0f, -minTileZ);
frustumPlanes[5] = float4(0.0f, 0.0f, -1.0f, maxTileZ);

// Normalize frustum planes (near/far already normalized)
[unroll] for (uint i = 0; i < 4; ++i)
{
    frustumPlanes[i] *= rcp(length(frustumPlanes[i].xyz));
}

// Cull lights for this tile
for (uint lightIndex = groupIndex; lightIndex < totalLights; lightIndex += (GROUP_WIDTH * GROUP_HEIGHT))
{
    PointLight light = InputBuffer[lightIndex];
    float3 lightVS = light.PosRad.xyz;// mul(float4(light.Pos.xyz, 1), View);
                                      // Cull: point light sphere vs tile frustum
    bool inFrustum = true;
    [unroll]
    for (uint i = 0; i < 6; ++i)
    {
        float d = dot(frustumPlanes[i], float4(lightVS, 1.0f));
        inFrustum = inFrustum && (d >= -light.PosRad.w);
    }

    [branch]
    if (inFrustum)
    {
        uint listIndex;
        InterlockedAdd(sTileNumLights, 1, listIndex);
        sTileLightIndices[listIndex] = lightIndex;
    }
}

GroupMemoryBarrierWithGroupSync();

uint numLights = sTileNumLights;

if (all(globalCoords < FrameBufferCamNearFar.zw))
{

    float4 NormalMap = NormalBuffer[globalCoords];
    float3 normal = DecodeNormal(NormalMap);


    if (numLights > 0)
    {
        float3 lit = float3(0.0f, 0.0f, 0.0f);
        for (uint tileLightIndex = 0; tileLightIndex < numLights; ++tileLightIndex)
        {

            PointLight light = InputBuffer[sTileLightIndices[tileLightIndex]];

            float3 lDir = light.PosRad.xyz - positionView;
            lDir = normalize(lDir);
            float3 nl = saturate(dot(lDir, normal));

            lit += ((light.Color.xyz * light.Color.a) * nl) *  0.1f;
        }

        PointLightColor[globalCoords] = float4(lit, 1);
    }
    else
    {

        PointLightColor[globalCoords] = 0;
    }
}

GroupMemoryBarrierWithGroupSync();
}

So I know the culling works because there are lights drawn, they just move with the camera.

Could it be a handedness issue?

Am I setting my CPU light code up right?

Have I messed my spaces up?

What am I missing?

Am I reconstructing my position from depth wrong? (don't think it's this because the culling works)

ps. I write depth out like this:

                VS shader
    float4 viewSpacePos = mul(float4(input.Position,1), WV);
output.Depth=viewSpacePos.z ;

             PS Shader

     -input.Depth.x / FarClip
SurvivalMachine
  • 7,946
  • 15
  • 57
  • 87
  • Well I'm a bit silly sometimes, this was supposed to be on gamedev.stackexchange.com but it seem in my mess of open tabs I dropped it here, can a mod move it over there or do I have to start again? – Justin William Stanley Bryant Oct 10 '15 at 08:32
  • Did you solved your problem? If yes, could you please have a look at my problem http://stackoverflow.com/questions/34837263/lights-not-working-properly-in-helix-sharp-dx . Thanks. – amit Jan 21 '16 at 06:15

0 Answers0