diff --git a/pipeline/glow-extras/pipeline/stages/implementations/DepthPreStage.cc b/pipeline/glow-extras/pipeline/stages/implementations/DepthPreStage.cc index 5a07e7359730d3aebbe0e281fcfa43846bd68927..d37889f285a7df035d9175aaabe17aca47db9c9e 100644 --- a/pipeline/glow-extras/pipeline/stages/implementations/DepthPreStage.cc +++ b/pipeline/glow-extras/pipeline/stages/implementations/DepthPreStage.cc @@ -95,14 +95,12 @@ void glow::pipeline::DepthPreStage::onExecuteStage(RenderContext const& ctx, glo PIPELINE_PROFILE("SSBO resize"); mCachedClusterAmount = newClusterAmount; - - // The worst case for cluster-light intersections is maxLightsPerCluster * clusterAmount - // A quarter of that is still very conservative - auto constexpr maxClusterLoad = .25f; - auto const maxLightIntersections = static_cast((maxLightsPerCluster * mCachedClusterAmount) * maxClusterLoad); - mSsboClusterAabbs->bind().setData(sizeof(ClusterAabb) * mCachedClusterAmount, nullptr, GL_STATIC_DRAW); mSsboClusterVisibilities->bind().setData(sizeof(SsboClusterVisibility) * mCachedClusterAmount, nullptr, GL_STATIC_DRAW); + + // The worst case for cluster-light intersections is maxLightsPerCluster * clusterAmount + // While that amount of load is rare, this buffer costs just 4 byte per entry + auto const maxLightIntersections = static_cast((maxLightsPerCluster * mCachedClusterAmount)); mSsboLightIndexList->bind().setData(sizeof(std140uint) * maxLightIntersections, nullptr, GL_STATIC_DRAW); } @@ -151,7 +149,7 @@ glow::pipeline::DepthPreStage::DepthPreStage() mSsboClusterAabbs = ShaderStorageBuffer::create(); mSsboLightData = ShaderStorageBuffer::create(); mSsboGlobalIndexCount = ShaderStorageBuffer::create(); - mSsboGlobalIndexCount->bind().setData(SsboGlobalIndexCountData{}, GL_STATIC_COPY); + mSsboGlobalIndexCount->bind().setData(SsboGlobalIndexCountData{}, GL_STATIC_DRAW); mComputeClusterAabbs = Program::createFromFile("glow-pipeline/internal/pass/depthpre/clusterAabbAssignment.csh"); mComputeClusterAabbs->setShaderStorageBuffer("sClusterAABBs", mSsboClusterAabbs); diff --git a/pipeline/shader/glow-pipeline/internal/common/globals.hh b/pipeline/shader/glow-pipeline/internal/common/globals.hh index 70f805504b9409cde474254e092412b8a9dfe0b7..faa90fb38a2b05ed0aad0be4730a2cf70b6651ea 100644 --- a/pipeline/shader/glow-pipeline/internal/common/globals.hh +++ b/pipeline/shader/glow-pipeline/internal/common/globals.hh @@ -19,7 +19,7 @@ #define GLOW_PIPELINE_CLUSTER_PIXEL_SIZE_X 120 #define GLOW_PIPELINE_CLUSTER_PIXEL_SIZE_Y 120 #define GLOW_PIPELINE_CLUSTER_AMOUNT_Z 24 -#define GLOW_PIPELINE_MAX_LIGHTS_PER_CLUSTER 20 +#define GLOW_PIPELINE_MAX_LIGHTS_PER_CLUSTER 150 // The local workgroup size of the light assignment compute shader // GLSL: pass/depthPre/clusterLightAssignment.csh diff --git a/pipeline/shader/glow-pipeline/internal/pass/depthpre/clusterLightAssignment.csh b/pipeline/shader/glow-pipeline/internal/pass/depthpre/clusterLightAssignment.csh index 9a887bb102135ab007266656c2138c1c0fc38abd..f4bdd9a8cf57a11506999bdcbf0ff9ca4a081932 100644 --- a/pipeline/shader/glow-pipeline/internal/pass/depthpre/clusterLightAssignment.csh +++ b/pipeline/shader/glow-pipeline/internal/pass/depthpre/clusterLightAssignment.csh @@ -37,8 +37,8 @@ shared vec4 sharedLights[LIGHTS_PER_BATCH]; uniform mat4 uView; bool doesLightIntersectAabb(vec4 lightData, const AABB b){ - const float radius = lightData.w; const vec3 center = vec3(uView * vec4(lightData.xyz, 1)); + const float radius = lightData.w; float sqDist = 0.0; @@ -56,6 +56,15 @@ bool doesLightIntersectAabb(vec4 lightData, const AABB b){ return sqDist <= (radius * radius); } +vec4 getBoundingSphere(PackedLightData light) +{ + // center (xyz) and bounding sphere radius (w) + return vec4( + (light.aSize.xyz + light.bRadius.xyz) * 0.5, + length(light.aSize.xyz - light.bRadius.xyz) * 0.5 + light.aSize.w + light.bRadius.w + ); +} + void main() { // Reset the global index count globalIndexCount = 0; @@ -74,7 +83,7 @@ void main() { // Simple, brute-force variant // for (int i = 0; i < lightCount; ++i) // { - // if (doesLightIntersectAabb(ssboLightData.lights[i].boundingCenterRadius, clusterAabb)) + // if (doesLightIntersectAabb(getBoundingSphere(ssboLightData.lights[i]), clusterAabb)) // { // visibleLightIndices[visibleLightCount] = i; // ++visibleLightCount; @@ -87,14 +96,8 @@ void main() { // Prevent fetching a light out of bounds lightIndex = min(lightIndex, lightCount); - // Load this thread's light into the shared light storage - // Compress it down to center (xyz) and bounding sphere radius (w) - PackedLightData light = ssboLightData.lights[lightIndex]; - sharedLights[gl_LocalInvocationIndex] = - vec4( - (light.aSize.xyz + light.bRadius.xyz) * 0.5, - length(light.aSize.xyz - light.bRadius.xyz) * 0.5 + light.aSize.w + light.bRadius.w - ); + // Load this thread's light into the shared light storage, compressed to the bounding sphere + sharedLights[gl_LocalInvocationIndex] = getBoundingSphere(ssboLightData.lights[lightIndex]); barrier();