implement tiled lighting part4

This commit is contained in:
turanszkij
2016-09-27 23:52:50 +02:00
parent 51da72cd26
commit 36c680b355
5 changed files with 106 additions and 61 deletions
+5 -8
View File
@@ -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;
}
+54 -9
View File
@@ -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;
+2 -3
View File
@@ -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
View File
@@ -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);
+4 -2
View File
@@ -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)