implement tiled lighting part4
This commit is contained in:
@@ -4,14 +4,14 @@
|
||||
CBUFFER(DispatchParams, CBSLOT_RENDERER_DISPATCHPARAMS)
|
||||
{
|
||||
// Number of groups dispatched. (This parameter is not available as an HLSL system value!)
|
||||
uint3 numThreadGroups;
|
||||
uint padding0; // implicit padding to 16 bytes.
|
||||
uint3 xDispatchParams_numThreadGroups;
|
||||
uint xDispatchParams_value0; // extra value / padding
|
||||
|
||||
// Total number of threads dispatched. (Also not available as an HLSL system value!)
|
||||
// Note: This value may be less than the actual number of threads executed
|
||||
// if the screen size is not evenly divisible by the block size.
|
||||
uint3 numThreads;
|
||||
uint padding1; // implicit padding to 16 bytes.
|
||||
uint3 xDispatchParams_numThreads;
|
||||
uint xDispatchParams_value1; // extra value / padding
|
||||
}
|
||||
|
||||
struct Plane
|
||||
@@ -85,10 +85,7 @@ bool SphereInsideFrustum(Sphere sphere, Frustum frustum, float zNear, float zFar
|
||||
{
|
||||
bool result = true;
|
||||
|
||||
// First check depth
|
||||
// Note: Here, the view vector points in the -Z axis so the
|
||||
// far depth value will be approaching -infinity.
|
||||
if (sphere.c.z - sphere.r > zNear || sphere.c.z + sphere.r < zFar)
|
||||
if (sphere.c.z + sphere.r < zNear || sphere.c.z - sphere.r > zFar)
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ struct Light
|
||||
float4 col;
|
||||
};
|
||||
STRUCTUREDBUFFER(Lights, Light, SBSLOT_LIGHTARRAY);
|
||||
#define lightCount ((uint)g_xColor.x)
|
||||
#define lightCount xDispatchParams_value0
|
||||
|
||||
|
||||
groupshared uint uMinDepth;
|
||||
@@ -40,7 +40,48 @@ void main(ComputeShaderInput IN)
|
||||
uMaxDepth = 0;
|
||||
//o_LightCount = 0;
|
||||
//t_LightCount = 0;
|
||||
GroupFrustum = in_Frustums[IN.groupID.x + (IN.groupID.y * numThreadGroups.x)];
|
||||
|
||||
//// Get frustum from frustum buffer:
|
||||
//GroupFrustum = in_Frustums[IN.groupID.x + (IN.groupID.y * xDispatchParams_numThreadGroups.x)];
|
||||
|
||||
// Calculate frustum in place:
|
||||
{
|
||||
// View space eye position is always at the origin.
|
||||
const float3 eyePos = float3(0, 0, 0);
|
||||
|
||||
// Compute 4 points on the far clipping plane to use as the
|
||||
// frustum vertices.
|
||||
float4 screenSpace[4];
|
||||
// Top left point
|
||||
screenSpace[0] = float4(IN.dispatchThreadID.xy, 1.0f, 1.0f);
|
||||
// Top right point
|
||||
screenSpace[1] = float4(float2(IN.dispatchThreadID.x + BLOCK_SIZE, IN.dispatchThreadID.y), 1.0f, 1.0f);
|
||||
// Bottom left point
|
||||
screenSpace[2] = float4(float2(IN.dispatchThreadID.x, IN.dispatchThreadID.y + BLOCK_SIZE), 1.0f, 1.0f);
|
||||
// Bottom right point
|
||||
screenSpace[3] = float4(float2(IN.dispatchThreadID.x + BLOCK_SIZE, IN.dispatchThreadID.y + BLOCK_SIZE), 1.0f, 1.0f);
|
||||
|
||||
float3 viewSpace[4];
|
||||
// Now convert the screen space points to view space
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
viewSpace[i] = ScreenToView(screenSpace[i]).xyz;
|
||||
}
|
||||
|
||||
// Now build the frustum planes from the view space points
|
||||
Frustum frustum;
|
||||
|
||||
// Left plane
|
||||
frustum.planes[0] = ComputePlane(eyePos, viewSpace[2], viewSpace[0]);
|
||||
// Right plane
|
||||
frustum.planes[1] = ComputePlane(eyePos, viewSpace[1], viewSpace[3]);
|
||||
// Top plane
|
||||
frustum.planes[2] = ComputePlane(eyePos, viewSpace[0], viewSpace[1]);
|
||||
// Bottom plane
|
||||
frustum.planes[3] = ComputePlane(eyePos, viewSpace[3], viewSpace[2]);
|
||||
|
||||
GroupFrustum = frustum;
|
||||
}
|
||||
}
|
||||
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
@@ -53,6 +94,9 @@ void main(ComputeShaderInput IN)
|
||||
float fMinDepth = asfloat(uMinDepth);
|
||||
float fMaxDepth = asfloat(uMaxDepth);
|
||||
|
||||
//fMinDepth = g_xCamera_ZFarP;
|
||||
//fMaxDepth = g_xCamera_ZNearP;
|
||||
|
||||
// Convert depth values to view space.
|
||||
float minDepthVS = ScreenToView(float4(0, 0, fMinDepth, 1)).z;
|
||||
float maxDepthVS = ScreenToView(float4(0, 0, fMaxDepth, 1)).z;
|
||||
@@ -60,7 +104,7 @@ void main(ComputeShaderInput IN)
|
||||
|
||||
// Clipping plane for minimum depth value
|
||||
// (used for testing lights within the bounds of opaque geometry).
|
||||
Plane minPlane = { float3(0, 0, -1), -minDepthVS };
|
||||
Plane minPlane = { float3(0, 0, 1), minDepthVS };
|
||||
|
||||
// Cull lights
|
||||
// Each thread in a group will cull 1 light until all lights have been culled.
|
||||
@@ -80,13 +124,14 @@ void main(ComputeShaderInput IN)
|
||||
//// Add light to light list for transparent geometry.
|
||||
//t_AppendLight(i);
|
||||
|
||||
//if (!SphereInsidePlane(sphere, minPlane))
|
||||
//{
|
||||
// // Add light to light list for opaque geometry.
|
||||
// o_AppendLight(i);
|
||||
//}
|
||||
if (!SphereInsidePlane(sphere, minPlane))
|
||||
{
|
||||
// Add light to light list for opaque geometry.
|
||||
//o_AppendLight(i);
|
||||
|
||||
InterlockedAdd(_counter, 1);
|
||||
}
|
||||
|
||||
InterlockedAdd(_counter, 1);
|
||||
}
|
||||
//}
|
||||
//break;
|
||||
|
||||
@@ -43,10 +43,9 @@ void main(ComputeShaderInput IN)
|
||||
frustum.planes[3] = ComputePlane(eyePos, viewSpace[3], viewSpace[2]);
|
||||
|
||||
// Store the computed frustum in global memory (if our thread ID is in bounds of the grid).
|
||||
if (IN.dispatchThreadID.x < numThreads.x && IN.dispatchThreadID.y < numThreads.y)
|
||||
if (IN.dispatchThreadID.x < xDispatchParams_numThreads.x && IN.dispatchThreadID.y < xDispatchParams_numThreads.y)
|
||||
{
|
||||
uint index = IN.dispatchThreadID.x + (IN.dispatchThreadID.y * numThreads.x);
|
||||
uint index = IN.dispatchThreadID.x + (IN.dispatchThreadID.y * xDispatchParams_numThreads.x);
|
||||
out_Frustums[index] = frustum;
|
||||
}
|
||||
//out_Frustums[0].planes[0].N = float3(1, 0, 1);
|
||||
}
|
||||
+41
-39
@@ -3316,16 +3316,48 @@ Texture2D* wiRenderer::ComputeTiledLightCulling(GRAPHICSTHREAD threadID)
|
||||
|
||||
|
||||
// Calc dispatchparams
|
||||
int _B = 16;
|
||||
UINT _B = 16;
|
||||
DispatchParamsCB dispatchParams;
|
||||
dispatchParams.numThreads[0] = (UINT)ceilf((float)_width / _B);
|
||||
dispatchParams.numThreads[1] = (UINT)ceilf((float)_height / _B);
|
||||
dispatchParams.numThreads[2] = 1;
|
||||
dispatchParams.numThreadGroups[0] = (UINT)ceilf((float)dispatchParams.numThreads[0] / _B);
|
||||
dispatchParams.numThreadGroups[1] = (UINT)ceilf((float)dispatchParams.numThreads[1] / _B);
|
||||
dispatchParams.numThreadGroups[2] = 1;
|
||||
device->UpdateBuffer(constantBuffers[CBTYPE_DISPATCHPARAMS], &dispatchParams, threadID);
|
||||
device->BindConstantBufferCS(constantBuffers[CBTYPE_DISPATCHPARAMS], CB_GETBINDSLOT(DispatchParamsCB), threadID);
|
||||
{
|
||||
dispatchParams.numThreads[0] = (UINT)ceilf(_width / (float)_B);
|
||||
dispatchParams.numThreads[1] = (UINT)ceilf(_height / (float)_B);
|
||||
dispatchParams.numThreads[2] = 1;
|
||||
dispatchParams.numThreadGroups[0] = (UINT)ceilf(dispatchParams.numThreads[0] / (float)_B);
|
||||
dispatchParams.numThreadGroups[1] = (UINT)ceilf(dispatchParams.numThreads[1] / (float)_B);
|
||||
dispatchParams.numThreadGroups[2] = 1;
|
||||
|
||||
// Fill Light Array with lights in the frustum
|
||||
CulledList culledObjects;
|
||||
if (spTree_lights)
|
||||
wiSPTree::getVisible(spTree_lights->root, getCamera()->frustum, culledObjects);
|
||||
static LightArrayType lightArray[1024];
|
||||
ZeroMemory(lightArray, sizeof(lightArray));
|
||||
|
||||
UINT lightCounter = 0;
|
||||
for (Cullable* c : culledObjects)
|
||||
{
|
||||
Light* l = (Light*)c;
|
||||
|
||||
//lightArray[counter].pos = l->translation;
|
||||
XMStoreFloat3(&lightArray[lightCounter].pos, XMVector3TransformCoord(XMLoadFloat3(&l->translation), cam->GetView()));
|
||||
lightArray[lightCounter].radius = l->enerDis.y;
|
||||
lightArray[lightCounter].col = l->color;
|
||||
|
||||
lightCounter++;
|
||||
if (lightCounter == 1024)
|
||||
{
|
||||
assert(0 && "Over 1024 lights are in the frustum!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
device->UpdateBuffer(resourceBuffers[RBTYPE_LIGHTARRAY], lightArray, threadID, (int)(sizeof(LightArrayType)*lightCounter));
|
||||
|
||||
dispatchParams.value0 = lightCounter;
|
||||
|
||||
device->UpdateBuffer(constantBuffers[CBTYPE_DISPATCHPARAMS], &dispatchParams, threadID);
|
||||
device->BindConstantBufferCS(constantBuffers[CBTYPE_DISPATCHPARAMS], CB_GETBINDSLOT(DispatchParamsCB), threadID);
|
||||
}
|
||||
|
||||
|
||||
static GPUBuffer* frustumBuffer = nullptr;
|
||||
if (frustumBuffer == nullptr)
|
||||
@@ -3378,42 +3410,12 @@ Texture2D* wiRenderer::ComputeTiledLightCulling(GRAPHICSTHREAD threadID)
|
||||
}
|
||||
if (uav != nullptr)
|
||||
{
|
||||
// Fill Light Array with lights in the frustum
|
||||
CulledList culledObjects;
|
||||
if (spTree_lights)
|
||||
wiSPTree::getVisible(spTree_lights->root, getCamera()->frustum, culledObjects);
|
||||
|
||||
GetDevice()->EventBegin(L"Light Culling", threadID);
|
||||
|
||||
static LightArrayType lightArray[1024];
|
||||
memset(lightArray, 0, sizeof(lightArray));
|
||||
|
||||
int counter = 0;
|
||||
for (Cullable* c : culledObjects)
|
||||
{
|
||||
Light* l = (Light*)c;
|
||||
|
||||
//lightArray[counter].pos = l->translation;
|
||||
XMStoreFloat3(&lightArray[counter].pos, XMVector3TransformCoord(XMLoadFloat3(&l->translation), cam->GetView()));
|
||||
lightArray[counter].radius = l->enerDis.y;
|
||||
lightArray[counter].col = l->color;
|
||||
|
||||
counter++;
|
||||
if (counter == 1024)
|
||||
{
|
||||
assert(0 && "Over 1024 lights are in the frustum!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
device->UpdateBuffer(resourceBuffers[RBTYPE_LIGHTARRAY], lightArray, threadID, (int)(sizeof(LightArrayType)*counter));
|
||||
device->BindResourceCS(resourceBuffers[RBTYPE_LIGHTARRAY], STRUCTUREDBUFFER_GETBINDSLOT(LightArrayType), threadID);
|
||||
|
||||
device->BindResourceCS(frustumBuffer, SBSLOT_TILEFRUSTUMS, threadID);
|
||||
|
||||
MiscCB cb;
|
||||
cb.mColor.x = (float)counter;
|
||||
device->UpdateBuffer(constantBuffers[CBTYPE_MISC], &cb, threadID);
|
||||
device->BindConstantBufferCS(constantBuffers[CBTYPE_MISC], CB_GETBINDSLOT(MiscCB), threadID);
|
||||
|
||||
Texture2DDesc uav_desc = uav->GetDesc();
|
||||
device->BindCS(computeShaders[CSTYPE_TILEDLIGHTCULLING], threadID);
|
||||
|
||||
@@ -257,8 +257,10 @@ public:
|
||||
};
|
||||
GFX_STRUCT DispatchParamsCB
|
||||
{
|
||||
UINT numThreadGroups[3]; UINT pad0;
|
||||
UINT numThreads[3]; UINT pad1;
|
||||
UINT numThreadGroups[3];
|
||||
UINT value0;
|
||||
UINT numThreads[3];
|
||||
UINT value1;
|
||||
|
||||
CB_SETBINDSLOT(CBSLOT_RENDERER_DISPATCHPARAMS)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user