Fixing Depth culling out of bounds errors
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import Common;
|
||||
import Scene;
|
||||
import Bounding;
|
||||
import DepthCommon;
|
||||
|
||||
groupshared MeshPayload p;
|
||||
groupshared uint head;
|
||||
@@ -10,37 +11,55 @@ groupshared Frustum viewFrustum;
|
||||
groupshared float4x4 modelViewProjection;
|
||||
groupshared bool meshVisible;
|
||||
|
||||
struct DepthData
|
||||
{
|
||||
Texture2D<float> texture;
|
||||
RWStructuredBuffer<float> buffer;
|
||||
}
|
||||
//void writeDebug(uint mipLevel, uint mipOffset, int2 mipDimensions, int2 screenMin, int2 screenMax, int2 origScreenMin, int2 origScreenMax)
|
||||
//{
|
||||
// uint index = 0;
|
||||
// InterlockedAdd(pDepthAttachment.debugHead[0], 1, index);
|
||||
// index = min(index, 10000);
|
||||
// {
|
||||
// pDepthAttachment.debugData[index].mipLevel = mipLevel;
|
||||
// pDepthAttachment.debugData[index].mipOffset = mipOffset;
|
||||
// pDepthAttachment.debugData[index].mipDimensions = mipDimensions;
|
||||
// pDepthAttachment.debugData[index].screenCornerMax = screenMax;
|
||||
// pDepthAttachment.debugData[index].screenCornerMin = screenMin;
|
||||
// pDepthAttachment.debugData[index].origScreenMax = origScreenMax;
|
||||
// pDepthAttachment.debugData[index].origScreenMin = origScreenMin;
|
||||
// }
|
||||
//}
|
||||
|
||||
ParameterBlock<DepthData> pDepthAttachment;
|
||||
|
||||
bool isBoxVisible(AABB bounding)
|
||||
{
|
||||
uint2 mipDimensions = uint2(uint(pViewParams.screenDimensions.x), uint(pViewParams.screenDimensions.y));
|
||||
int2 mipDimensions = uint2(uint(pViewParams.screenDimensions.x), uint(pViewParams.screenDimensions.y));
|
||||
// now we calculate what mip level we need to only sample up to 4 texels covering the entire meshlet
|
||||
uint2 screenCornerMin = mipDimensions;
|
||||
uint2 screenCornerMax = uint2(0, 0);
|
||||
int2 screenCornerMin = mipDimensions;
|
||||
int2 screenCornerMax = uint2(0, 0);
|
||||
// lower values are closer
|
||||
float maxDepth = bounding.projectScreenDepth(modelViewProjection, screenCornerMin, screenCornerMax);
|
||||
uint mipOffset = 0;
|
||||
// uint mipLevel = 0;
|
||||
// int2 origScreenMin = screenCornerMin;
|
||||
// int2 origScreenMax = screenCornerMax;
|
||||
// in theory this wouldnt work if no corner was in screen, as min would be greater that max, however we verified that with view culling
|
||||
while(screenCornerMax.x - screenCornerMin.x > 1 || screenCornerMax.y - screenCornerMin.y > 1)
|
||||
{
|
||||
// mipLevel++;
|
||||
mipOffset += mipDimensions.x * mipDimensions.y;
|
||||
mipDimensions = uint2(mipDimensions.x + 1, mipDimensions.y + 1) / 2;
|
||||
screenCornerMin = uint2(screenCornerMin.x + 1, screenCornerMin.y + 1) / 2;
|
||||
screenCornerMax = uint2(screenCornerMax.x, screenCornerMax.y) / 2;
|
||||
mipDimensions = int2(mipDimensions.x + 1, mipDimensions.y + 1) / 2;
|
||||
screenCornerMin = int2(screenCornerMin.x + 1, screenCornerMin.y + 1) / 2;
|
||||
screenCornerMax = int2(screenCornerMax.x, screenCornerMax.y) / 2;
|
||||
}
|
||||
|
||||
uint i0 = mipOffset + (screenCornerMin.y * mipDimensions.x) + screenCornerMin.x;
|
||||
uint i1 = mipOffset + (screenCornerMin.y * mipDimensions.x) + screenCornerMax.x;
|
||||
uint i2 = mipOffset + (screenCornerMax.y * mipDimensions.x) + screenCornerMin.x;
|
||||
uint i3 = mipOffset + (screenCornerMax.y * mipDimensions.x) + screenCornerMax.x;
|
||||
|
||||
// now we sample 4 texels from the depth at the calculated mip level, this should give us the screen extent of the meshlet
|
||||
float d1 = pDepthAttachment.buffer[mipOffset + (screenCornerMin.y * mipDimensions.x) + screenCornerMin.x];
|
||||
float d2 = pDepthAttachment.buffer[mipOffset + (screenCornerMin.y * mipDimensions.x) + screenCornerMax.x];
|
||||
float d3 = pDepthAttachment.buffer[mipOffset + (screenCornerMax.y * mipDimensions.x) + screenCornerMin.x];
|
||||
float d4 = pDepthAttachment.buffer[mipOffset + (screenCornerMax.y * mipDimensions.x) + screenCornerMax.x];
|
||||
float d1 = pDepthAttachment.buffer[i0];
|
||||
float d2 = pDepthAttachment.buffer[i1];
|
||||
float d3 = pDepthAttachment.buffer[i2];
|
||||
float d4 = pDepthAttachment.buffer[i3];
|
||||
|
||||
// we want to check if the minimum depth (the value farthest away) is smaller than the maximum bounding box depth
|
||||
// otherwise, there is no way for the meshlet to be visible
|
||||
@@ -102,7 +121,7 @@ void taskMain(
|
||||
{
|
||||
#ifdef DEPTH_CULLING
|
||||
// if the meshlet bounding box is behind the cached depth buffer, we skip
|
||||
//if(isBoxVisible(meshlet.bounding))
|
||||
if(isBoxVisible(meshlet.bounding))
|
||||
#endif
|
||||
{
|
||||
uint index;
|
||||
|
||||
Reference in New Issue
Block a user