mirror of
https://github.com/overte-org/overte.git
synced 2025-08-05 23:09:35 +02:00
Better vizualization, first set of culling improvment
This commit is contained in:
parent
af48d4f0bd
commit
fdba78db6f
5 changed files with 76 additions and 46 deletions
|
@ -123,6 +123,38 @@ ivec3 frustumGrid_eyeToClusterPos(vec3 eyePos) {
|
|||
return ivec3(gridPos);
|
||||
}
|
||||
|
||||
int frustumGrid_eyeToClusterDirH(vec3 eyeDir) {
|
||||
if (eyeDir.z >= 0.0) {
|
||||
return (eyeDir.x > 0 ? frustumGrid.dims.x : -1);
|
||||
}
|
||||
|
||||
float eyeDepth = -eyeDir.z;
|
||||
float nclipDir = eyeDir.x / eyeDepth;
|
||||
float ndcDir = nclipDir * frustumGrid.eyeToGridProj[0][0] - frustumGrid.eyeToGridProj[2][0];
|
||||
float volumeDir = 0.5 * (ndcDir + 1.0);
|
||||
float gridPos = volumeDir * float(frustumGrid.dims.x);
|
||||
|
||||
return int(gridPos);
|
||||
}
|
||||
|
||||
int frustumGrid_eyeToClusterDirV(vec3 eyeDir) {
|
||||
if (eyeDir.z >= 0.0) {
|
||||
return (eyeDir.y > 0 ? frustumGrid.dims.y : -1);
|
||||
}
|
||||
|
||||
float eyeDepth = -eyeDir.z;
|
||||
float nclipDir = eyeDir.y / eyeDepth;
|
||||
float ndcDir = nclipDir * frustumGrid.eyeToGridProj[1][1] - frustumGrid.eyeToGridProj[2][1];
|
||||
float volumeDir = 0.5 * (ndcDir + 1.0);
|
||||
float gridPos = volumeDir * float(frustumGrid.dims.y);
|
||||
|
||||
return int(gridPos);
|
||||
}
|
||||
|
||||
ivec2 frustumGrid_eyeToClusterDir(vec3 eyeDir) {
|
||||
return ivec2(frustumGrid_eyeToClusterDirH(eyeDir), frustumGrid_eyeToClusterDirV(eyeDir));
|
||||
}
|
||||
|
||||
vec4 frustumGrid_eyeToWorld(vec4 eyePos) {
|
||||
return frustumGrid.eyeToWorldMat * eyePos;
|
||||
}
|
||||
|
|
|
@ -124,6 +124,27 @@ void LightClusters::updateLightFrame(const LightStage::Frame& lightFrame, bool p
|
|||
_lightIndicesBuffer._size = _visibleLightIndices.size() * sizeof(int);
|
||||
}
|
||||
|
||||
bool scanLightVolume(FrustumGrid& grid, int zMin, int zMax, int yMin, int yMax, int xMin, int xMax, LightClusters::LightID lightId, const glm::vec4& eyePosRadius,
|
||||
uint32_t& numClustersTouched, int maxNumIndices, std::vector< std::vector<LightClusters::LightID>>& clusterGrid) {
|
||||
glm::ivec3 gridPosToOffset(1, grid.dims.x, grid.dims.x * grid.dims.y);
|
||||
|
||||
bool hasBudget = true;
|
||||
for (auto z = zMin; (z <= zMax) && hasBudget; z++) {
|
||||
for (auto y = yMin; (y <= yMax) && hasBudget; y++) {
|
||||
for (auto x = xMin; (x <= xMax) && hasBudget; x++) {
|
||||
auto index = x + gridPosToOffset.y * y + gridPosToOffset.z * z;
|
||||
clusterGrid[index].emplace_back(lightId);
|
||||
numClustersTouched++;
|
||||
if (numClustersTouched >= maxNumIndices) {
|
||||
hasBudget = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return hasBudget;
|
||||
}
|
||||
|
||||
void LightClusters::updateClusters() {
|
||||
// Clean up last info
|
||||
std::vector< std::vector< LightID > > clusterGrid(_numClusters);
|
||||
|
@ -167,7 +188,8 @@ void LightClusters::updateClusters() {
|
|||
continue;
|
||||
}
|
||||
|
||||
|
||||
// is it a light whose origin is behind the near ?
|
||||
bool behindLight = (eyeOri.z >= -theFrustumGrid.rangeNear);
|
||||
//
|
||||
float eyeOriLen2 = glm::length2(eyeOri);
|
||||
|
||||
|
@ -199,8 +221,6 @@ void LightClusters::updateClusters() {
|
|||
|
||||
float eyeToTangentCircleLenH = sqrt(eyeOriLen2H - radius2);
|
||||
|
||||
float eyeToTangentCircleTanH = radius / eyeToTangentCircleLenH;
|
||||
|
||||
float eyeToTangentCircleCosH = eyeToTangentCircleLenH / eyeOriLenH;
|
||||
|
||||
float eyeToTangentCircleSinH = radius / eyeOriLenH;
|
||||
|
@ -210,15 +230,11 @@ void LightClusters::updateClusters() {
|
|||
glm::vec3 leftDir(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 rc = theFrustumGrid.frustumGrid_eyeToClusterDirH(rightDir);
|
||||
|
||||
glm::vec3 leftPosAtNear = leftDir * theFrustumGrid.rangeNear * 2.0f;
|
||||
glm::vec3 rightPosAtNear = rightDir * theFrustumGrid.rangeNear * 2.0f;
|
||||
|
||||
auto lc = theFrustumGrid.frustumGrid_eyeToClusterPos(leftPosAtNear);
|
||||
auto rc = theFrustumGrid.frustumGrid_eyeToClusterPos(rightPosAtNear);
|
||||
|
||||
xMin = std::max(0, lc.x);
|
||||
xMax = std::max(0, std::min(rc.x, xMax));
|
||||
xMin = std::max(xMin, lc);
|
||||
xMax = std::max(0, std::min(rc, xMax));
|
||||
}
|
||||
|
||||
if ((eyeOriLen2V > radius2)) {
|
||||
|
@ -226,12 +242,8 @@ void LightClusters::updateClusters() {
|
|||
|
||||
auto eyeOriDirV = glm::vec3(eyeOriV) / eyeOriLenV;
|
||||
|
||||
|
||||
|
||||
float eyeToTangentCircleLenV = sqrt(eyeOriLen2V - radius2);
|
||||
|
||||
float eyeToTangentCircleTanV = radius / eyeToTangentCircleLenV;
|
||||
|
||||
float eyeToTangentCircleCosV = eyeToTangentCircleLenV / eyeOriLenV;
|
||||
|
||||
float eyeToTangentCircleSinV = radius / eyeOriLenV;
|
||||
|
@ -241,29 +253,17 @@ void LightClusters::updateClusters() {
|
|||
glm::vec3 bottomDir(0.0f, eyeOriDirV.y * eyeToTangentCircleCosV + eyeOriDirV.z * eyeToTangentCircleSinV, eyeOriDirV.y * -eyeToTangentCircleSinV + eyeOriDirV.z * eyeToTangentCircleCosV);
|
||||
glm::vec3 topDir(0.0f, eyeOriDirV.y * eyeToTangentCircleCosV - eyeOriDirV.z * eyeToTangentCircleSinV, eyeOriDirV.y * eyeToTangentCircleSinV + eyeOriDirV.z * eyeToTangentCircleCosV);
|
||||
|
||||
auto bc = theFrustumGrid.frustumGrid_eyeToClusterDirV(bottomDir);
|
||||
auto tc = theFrustumGrid.frustumGrid_eyeToClusterDirV(topDir);
|
||||
|
||||
glm::vec3 bottomPosAtNear = bottomDir * theFrustumGrid.rangeNear * 2.0f;
|
||||
glm::vec3 topPosAtNear = topDir * theFrustumGrid.rangeNear * 2.0f;
|
||||
|
||||
auto bc = theFrustumGrid.frustumGrid_eyeToClusterPos(bottomPosAtNear);
|
||||
auto tc = theFrustumGrid.frustumGrid_eyeToClusterPos(topPosAtNear);
|
||||
|
||||
yMin = std::max(0, bc.y);
|
||||
yMax = std::max(0, std::min(tc.y, yMax));
|
||||
yMin = std::max(yMin, bc);
|
||||
yMax = std::max(yMin, std::min(tc, yMax));
|
||||
}
|
||||
|
||||
// now voxelize
|
||||
for (auto z = zMin; z <= zMax; z++) {
|
||||
for (auto y = yMin; y <= yMax; y++) {
|
||||
for (auto x = xMin; x <= xMax; x++) {
|
||||
auto index = x + gridPosToOffset.y * y + gridPosToOffset.z * z;
|
||||
clusterGrid[index].emplace_back(lightId);
|
||||
numClusterTouched++;
|
||||
}
|
||||
}
|
||||
}
|
||||
bool hasBudget = scanLightVolume(theFrustumGrid, zMin, zMax, yMin, yMax, xMin, xMax, lightId, glm::vec4(glm::vec3(eyeOri), radius), numClusterTouched, maxNumIndices, clusterGrid);
|
||||
|
||||
if (numClusterTouched >= maxNumIndices) {
|
||||
if (!hasBudget) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -486,6 +486,7 @@ void DebugLightClusters::run(const render::SceneContextPointer& sceneContext, co
|
|||
}
|
||||
|
||||
if (doDrawContent) {
|
||||
|
||||
// bind the one gpu::Pipeline we need
|
||||
batch.setPipeline(getDrawClusterContentPipeline());
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@ public:
|
|||
|
||||
LightStagePointer _lightStage;
|
||||
|
||||
|
||||
|
||||
|
||||
gpu::StructBuffer<FrustumGrid> _frustumGridBuffer;
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<@include gpu / Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
|
@ -12,17 +12,15 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
<@include gpu/Transform.slh@>
|
||||
<@include gpu / Transform.slh@>
|
||||
<$declareStandardTransform()$>
|
||||
|
||||
<@include LightClusterGrid.slh@>
|
||||
|
||||
<@include gpu/Color.slh@>
|
||||
<@include gpu / Color.slh@>
|
||||
<$declareColorWheel()$>
|
||||
|
||||
|
||||
|
||||
|
||||
out vec4 varColor;
|
||||
|
||||
|
||||
|
|
|
@ -53,16 +53,15 @@ void main(void) {
|
|||
);
|
||||
vec4 pos = UNIT_BOX[UNIT_BOX_LINE_INDICES[gl_VertexID]];
|
||||
|
||||
ivec3 dims = frustumGrid.dims.xyz;
|
||||
|
||||
ivec3 summedDims = ivec3(dims.x * dims.y, dims.x, 1);
|
||||
ivec2 cluster = clusterGrid_getCluster(gl_InstanceID);
|
||||
int numLights = cluster.x;
|
||||
|
||||
int layer = gl_InstanceID / summedDims.x;
|
||||
int offsetInLayer = gl_InstanceID % summedDims.x;
|
||||
ivec3 clusterPos = ivec3(offsetInLayer % summedDims.y, offsetInLayer / summedDims.y, layer);
|
||||
ivec3 clusterPos = clusterGrid_indexToCluster(gl_InstanceID);
|
||||
|
||||
|
||||
vec3 eyePos = frustumGrid_clusterPosToEye(clusterPos, vec3(0.05) + 0.9 * pos.xyz);
|
||||
float boxScale = 1.0;
|
||||
vec3 eyePos = frustumGrid_clusterPosToEye(clusterPos, vec3(1.0 - boxScale) * 0.5 + boxScale * pos.xyz);
|
||||
vec4 worldPos = frustumGrid_eyeToWorld(vec4(eyePos.xyz, 1.0));
|
||||
|
||||
|
||||
|
@ -70,5 +69,5 @@ void main(void) {
|
|||
TransformCamera cam = getTransformCamera();
|
||||
<$transformWorldToClipPos(cam, worldPos, gl_Position)$>
|
||||
|
||||
varColor = vec4(colorWheel(fract(float(gl_InstanceID) / float(frustumGrid_numClusters()))), 0.9);
|
||||
varColor = vec4(colorWheel(fract(float(gl_InstanceID) / float(frustumGrid_numClusters()))), (numLights > 0 ? 0.9 : 0.0));
|
||||
}
|
Loading…
Reference in a new issue