mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 14:58:03 +02:00
Add a finer culling test to avoid faulty discards
This commit is contained in:
parent
621d62cdf8
commit
4504877ba6
1 changed files with 51 additions and 9 deletions
|
@ -210,6 +210,23 @@ bool reduceSphereToPlane(const glm::vec4& sphere, const glm::vec4& plane, glm::v
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t scanLightVolumeBoxSlice(FrustumGrid& grid, const FrustumGrid::Planes planes[3], int zSlice, int yMin, int yMax, int xMin, int xMax, LightClusters::LightID lightId, const glm::vec4& eyePosRadius,
|
||||||
|
std::vector< std::vector<LightClusters::LightIndex>>& clusterGrid) {
|
||||||
|
glm::ivec3 gridPosToOffset(1, grid.dims.x, grid.dims.x * grid.dims.y);
|
||||||
|
uint32_t numClustersTouched = 0;
|
||||||
|
|
||||||
|
for (auto y = yMin; (y <= yMax); y++) {
|
||||||
|
for (auto x = xMin; (x <= xMax); x++) {
|
||||||
|
auto index = x + gridPosToOffset.y * y + gridPosToOffset.z * zSlice;
|
||||||
|
clusterGrid[index].emplace_back(lightId);
|
||||||
|
numClustersTouched++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return numClustersTouched;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t scanLightVolumeBox(FrustumGrid& grid, const FrustumGrid::Planes planes[3], int zMin, int zMax, int yMin, int yMax, int xMin, int xMax, LightClusters::LightID lightId, const glm::vec4& eyePosRadius,
|
uint32_t scanLightVolumeBox(FrustumGrid& grid, const FrustumGrid::Planes planes[3], int zMin, int zMax, int yMin, int yMax, int xMin, int xMax, LightClusters::LightID lightId, const glm::vec4& eyePosRadius,
|
||||||
std::vector< std::vector<LightClusters::LightIndex>>& clusterGrid) {
|
std::vector< std::vector<LightClusters::LightIndex>>& clusterGrid) {
|
||||||
glm::ivec3 gridPosToOffset(1, grid.dims.x, grid.dims.x * grid.dims.y);
|
glm::ivec3 gridPosToOffset(1, grid.dims.x, grid.dims.x * grid.dims.y);
|
||||||
|
@ -281,7 +298,7 @@ uint32_t scanLightVolumeSphere(FrustumGrid& grid, const FrustumGrid::Planes plan
|
||||||
|
|
||||||
for (; (x <= xs); x++) {
|
for (; (x <= xs); x++) {
|
||||||
auto index = grid.frustumGrid_clusterToIndex(ivec3(x, y, z));
|
auto index = grid.frustumGrid_clusterToIndex(ivec3(x, y, z));
|
||||||
if (index < (int) clusterGrid.size()) {
|
if (index < (int)clusterGrid.size()) {
|
||||||
clusterGrid[index].emplace_back(lightId);
|
clusterGrid[index].emplace_back(lightId);
|
||||||
numClustersTouched++;
|
numClustersTouched++;
|
||||||
} else {
|
} else {
|
||||||
|
@ -301,7 +318,7 @@ uint32_t LightClusters::updateClusters() {
|
||||||
|
|
||||||
_clusterGrid.clear();
|
_clusterGrid.clear();
|
||||||
_clusterGrid.resize(_numClusters, EMPTY_CLUSTER);
|
_clusterGrid.resize(_numClusters, EMPTY_CLUSTER);
|
||||||
uint32_t maxNumIndices = (uint32_t) _clusterContent.size();
|
uint32_t maxNumIndices = (uint32_t)_clusterContent.size();
|
||||||
_clusterContent.clear();
|
_clusterContent.clear();
|
||||||
_clusterContent.resize(maxNumIndices, INVALID_LIGHT);
|
_clusterContent.resize(maxNumIndices, INVALID_LIGHT);
|
||||||
|
|
||||||
|
@ -329,8 +346,9 @@ uint32_t LightClusters::updateClusters() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
float eyeZMin = eyeOri.z + radius;
|
float eyeZMin = eyeOri.z + radius;
|
||||||
|
bool beyondFar = false;
|
||||||
if (eyeZMin < -theFrustumGrid.rangeFar) {
|
if (eyeZMin < -theFrustumGrid.rangeFar) {
|
||||||
continue;
|
beyondFar = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get z slices
|
// Get z slices
|
||||||
|
@ -351,6 +369,16 @@ uint32_t LightClusters::updateClusters() {
|
||||||
zMin = std::max(0, zMin);
|
zMin = std::max(0, zMin);
|
||||||
// zMax = std::min(zMax, theFrustumGrid.dims.z);
|
// zMax = std::min(zMax, theFrustumGrid.dims.z);
|
||||||
|
|
||||||
|
auto xLeftDistance = radius - distanceToPlane(eyeOri, _gridPlanes[0][0]);
|
||||||
|
auto xRightDistance = radius + distanceToPlane(eyeOri, _gridPlanes[0].back());
|
||||||
|
|
||||||
|
auto yBottomDistance = radius - distanceToPlane(eyeOri, _gridPlanes[1][0]);
|
||||||
|
auto yTopDistance = radius + distanceToPlane(eyeOri, _gridPlanes[1].back());
|
||||||
|
|
||||||
|
if ((xLeftDistance < 0.f) || (xRightDistance < 0.f) || (yBottomDistance < 0.f) || (yTopDistance < 0.f)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// find 2D corners of the sphere in grid
|
// find 2D corners of the sphere in grid
|
||||||
int xMin { 0 };
|
int xMin { 0 };
|
||||||
int xMax { theFrustumGrid.dims.x - 1 };
|
int xMax { theFrustumGrid.dims.x - 1 };
|
||||||
|
@ -384,10 +412,16 @@ uint32_t LightClusters::updateClusters() {
|
||||||
glm::vec3 rightDir(eyeOriDirH.x * eyeToTangentCircleCosH - eyeOriDirH.z * eyeToTangentCircleSinH, 0.0f, eyeOriDirH.x * eyeToTangentCircleSinH + eyeOriDirH.z * eyeToTangentCircleCosH);
|
glm::vec3 rightDir(eyeOriDirH.x * eyeToTangentCircleCosH - eyeOriDirH.z * eyeToTangentCircleSinH, 0.0f, eyeOriDirH.x * eyeToTangentCircleSinH + eyeOriDirH.z * eyeToTangentCircleCosH);
|
||||||
|
|
||||||
auto lc = theFrustumGrid.frustumGrid_eyeToClusterDirH(leftDir);
|
auto lc = theFrustumGrid.frustumGrid_eyeToClusterDirH(leftDir);
|
||||||
|
if (lc > xMax) {
|
||||||
|
lc = xMin;
|
||||||
|
}
|
||||||
auto rc = theFrustumGrid.frustumGrid_eyeToClusterDirH(rightDir);
|
auto rc = theFrustumGrid.frustumGrid_eyeToClusterDirH(rightDir);
|
||||||
|
if (rc < 0) {
|
||||||
|
rc = xMax;
|
||||||
|
}
|
||||||
xMin = std::max(xMin, lc);
|
xMin = std::max(xMin, lc);
|
||||||
xMax = std::min(rc, xMax);
|
xMax = std::min(rc, xMax);
|
||||||
|
assert(xMin <= xMax);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((eyeOriLen2V > radius2)) {
|
if ((eyeOriLen2V > radius2)) {
|
||||||
|
@ -408,16 +442,24 @@ uint32_t LightClusters::updateClusters() {
|
||||||
|
|
||||||
auto bc = theFrustumGrid.frustumGrid_eyeToClusterDirV(bottomDir);
|
auto bc = theFrustumGrid.frustumGrid_eyeToClusterDirV(bottomDir);
|
||||||
auto tc = theFrustumGrid.frustumGrid_eyeToClusterDirV(topDir);
|
auto tc = theFrustumGrid.frustumGrid_eyeToClusterDirV(topDir);
|
||||||
|
if (bc > yMax) {
|
||||||
|
bc = yMin;
|
||||||
|
}
|
||||||
|
if (tc < 0) {
|
||||||
|
tc = yMax;
|
||||||
|
}
|
||||||
yMin = std::max(yMin, bc);
|
yMin = std::max(yMin, bc);
|
||||||
yMax =std::min(tc, yMax);
|
yMax =std::min(tc, yMax);
|
||||||
|
assert(yMin <= yMax);
|
||||||
}
|
}
|
||||||
|
|
||||||
// now voxelize
|
// now voxelize
|
||||||
auto& clusterGrid = (isSpot ? clusterGridSpot : clusterGridPoint);
|
auto& clusterGrid = (isSpot ? clusterGridSpot : clusterGridPoint);
|
||||||
|
if (beyondFar) {
|
||||||
|
numClusterTouched += scanLightVolumeBoxSlice(theFrustumGrid, _gridPlanes, zMin, yMin, yMax, xMin, xMax, lightId, glm::vec4(glm::vec3(eyeOri), radius), clusterGrid);
|
||||||
|
} else {
|
||||||
numClusterTouched += scanLightVolumeSphere(theFrustumGrid, _gridPlanes, zMin, zMax, yMin, yMax, xMin, xMax, lightId, glm::vec4(glm::vec3(eyeOri), radius), clusterGrid);
|
numClusterTouched += scanLightVolumeSphere(theFrustumGrid, _gridPlanes, zMin, zMax, yMin, yMax, xMin, xMax, lightId, glm::vec4(glm::vec3(eyeOri), radius), clusterGrid);
|
||||||
// numClusterTouched += scanLightVolumeBox(theFrustumGrid, _gridPlanes, zMin, zMax, yMin, yMax, xMin, xMax, lightId, glm::vec4(glm::vec3(eyeOri), radius), clusterGrid);
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lights have been gathered now reexpress in terms of 2 sequential buffers
|
// Lights have been gathered now reexpress in terms of 2 sequential buffers
|
||||||
|
|
Loading…
Reference in a new issue