-
Notifications
You must be signed in to change notification settings - Fork 855
Improve light AABB generation #1574
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from all commits
Commits
Show all changes
22 commits
Select commit
Hold shift + click to select a range
c084cdd
Implement clipping and culling (does not consider view frustum corners)
EvgeniiG a6f00ce
Support orthographic projection
EvgeniiG f8eea29
k_identity -> k_Identity
EvgeniiG ccbb9e1
Turn 'scaleXY' into a scalar
EvgeniiG 1559d1c
Test corners of the view volume
EvgeniiG b8e8c83
Improve the placeholder for the linear depth
EvgeniiG 676eb5a
Fix aspect
EvgeniiG 433e27e
Bugfix
EvgeniiG 8a2458a
Optimize
EvgeniiG 0453c6c
Also store view space Z
EvgeniiG 7aa331c
Optimize orthographic
EvgeniiG 05a222e
Optimize LUT
EvgeniiG 1e90134
Add wave intrinsic support
EvgeniiG 9e4b8c6
Fix group count
EvgeniiG f52d29b
Reduce the kernel count to 1
EvgeniiG 64f50ba
Remove old code
EvgeniiG 1a3e172
Bounds check
EvgeniiG 3e28378
Add a profiling marker
EvgeniiG 06a8d70
Fix lane masks
EvgeniiG a7fcd99
Fix compiler warning
EvgeniiG 71004f0
Remove GPU Pro reference
EvgeniiG 21c2481
No instrinsics on Xbox
EvgeniiG File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -128,8 +128,8 @@ struct SFiniteLightBound | |
public Vector3 boxAxisY; // Scaled by the extents (half-size) | ||
public Vector3 boxAxisZ; // Scaled by the extents (half-size) | ||
public Vector3 center; // Center of the bounds (box) in camera space | ||
public Vector2 scaleXY; // Scale applied to the top of the box to turn it into a truncated pyramid | ||
public float radius; // Circumscribed sphere for the bounds (box) | ||
public float scaleXY; // Scale applied to the top of the box to turn it into a truncated pyramid (X = Y) | ||
public float radius; // Circumscribed sphere for the bounds (box) | ||
}; | ||
|
||
[GenerateHLSL] | ||
|
@@ -564,8 +564,6 @@ public void Allocate() | |
Shader deferredTilePixelShader { get { return defaultResources.shaders.deferredTilePS; } } | ||
|
||
|
||
static int s_GenAABBKernel; | ||
static int s_GenAABBKernel_Oblique; | ||
static int s_GenListPerTileKernel; | ||
static int s_GenListPerTileKernel_Oblique; | ||
static int s_GenListPerVoxelKernel; | ||
|
@@ -782,9 +780,6 @@ void InitializeLightLoop(IBLFilterBSDF[] iBLFilterBSDFArray) | |
m_MaxLightsOnScreen = m_MaxDirectionalLightsOnScreen + m_MaxPunctualLightsOnScreen + m_MaxAreaLightsOnScreen + m_MaxEnvLightsOnScreen; | ||
m_MaxPlanarReflectionOnScreen = lightLoopSettings.maxPlanarReflectionOnScreen; | ||
|
||
s_GenAABBKernel = buildScreenAABBShader.FindKernel("ScreenBoundsAABB"); | ||
s_GenAABBKernel_Oblique = buildScreenAABBShader.FindKernel("ScreenBoundsAABB_Oblique"); | ||
|
||
// Cluster | ||
{ | ||
s_ClearVoxelAtomicKernel = buildPerVoxelLightListShader.FindKernel("ClearAtomic"); | ||
|
@@ -1628,9 +1623,9 @@ void GetLightVolumeDataAndBound(LightCategory lightCategory, GPULightType gpuLig | |
fAltDx *= range; fAltDy *= range; | ||
|
||
// Handle case of pyramid with this select (currently unused) | ||
var altDist = Mathf.Sqrt(fAltDy * fAltDy + (true ? 1.0f : 2.0f) * fAltDx * fAltDx); | ||
bound.radius = altDist > (0.5f * range) ? altDist : (0.5f * range); // will always pick fAltDist | ||
bound.scaleXY = squeeze ? new Vector2(0.01f, 0.01f) : new Vector2(1.0f, 1.0f); | ||
var altDist = Mathf.Sqrt(fAltDy * fAltDy + (true ? 1.0f : 2.0f) * fAltDx * fAltDx); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You did not add this code, but having true? is a bit weird here :D |
||
bound.radius = altDist > (0.5f * range) ? altDist : (0.5f * range); // will always pick fAltDist | ||
bound.scaleXY = squeeze ? 0.01f : 1.0f; | ||
|
||
lightVolumeData.lightAxisX = vx; | ||
lightVolumeData.lightAxisY = vy; | ||
|
@@ -1642,16 +1637,19 @@ void GetLightVolumeDataAndBound(LightCategory lightCategory, GPULightType gpuLig | |
} | ||
else if (gpuLightType == GPULightType.Point) | ||
{ | ||
Vector3 vx = xAxisVS; | ||
Vector3 vy = yAxisVS; | ||
Vector3 vz = zAxisVS; | ||
// Construct a view-space axis-aligned bounding cube around the bounding sphere. | ||
// This allows us to utilize the same polygon clipping technique for all lights. | ||
// Non-axis-aligned vectors may result in a larger screen-space AABB. | ||
Vector3 vx = new Vector3(1, 0, 0); | ||
Vector3 vy = new Vector3(0, 1, 0); | ||
Vector3 vz = new Vector3(0, 0, 1); | ||
|
||
bound.center = positionVS; | ||
bound.boxAxisX = vx * range; | ||
bound.boxAxisY = vy * range; | ||
bound.boxAxisZ = vz * range; | ||
bound.scaleXY.Set(1.0f, 1.0f); | ||
bound.radius = range; | ||
bound.scaleXY = 1.0f; | ||
bound.radius = range; | ||
|
||
// fill up ldata | ||
lightVolumeData.lightAxisX = vx; | ||
|
@@ -1672,7 +1670,7 @@ void GetLightVolumeDataAndBound(LightCategory lightCategory, GPULightType gpuLig | |
bound.boxAxisY = extents.y * yAxisVS; | ||
bound.boxAxisZ = extents.z * zAxisVS; | ||
bound.radius = extents.magnitude; | ||
bound.scaleXY.Set(1.0f, 1.0f); | ||
bound.scaleXY = 1.0f; | ||
|
||
lightVolumeData.lightPos = centerVS; | ||
lightVolumeData.lightAxisX = xAxisVS; | ||
|
@@ -1692,7 +1690,7 @@ void GetLightVolumeDataAndBound(LightCategory lightCategory, GPULightType gpuLig | |
bound.boxAxisY = extents.y * yAxisVS; | ||
bound.boxAxisZ = extents.z * zAxisVS; | ||
bound.radius = extents.magnitude; | ||
bound.scaleXY.Set(1.0f, 1.0f); | ||
bound.scaleXY = 1.0f; | ||
|
||
lightVolumeData.lightPos = centerVS; | ||
lightVolumeData.lightAxisX = xAxisVS; | ||
|
@@ -1712,7 +1710,7 @@ void GetLightVolumeDataAndBound(LightCategory lightCategory, GPULightType gpuLig | |
bound.boxAxisY = extents.y * yAxisVS; | ||
bound.boxAxisZ = extents.z * zAxisVS; | ||
bound.radius = extents.magnitude; | ||
bound.scaleXY.Set(1.0f, 1.0f); | ||
bound.scaleXY = 1.0f; | ||
|
||
lightVolumeData.lightPos = centerVS; | ||
lightVolumeData.lightAxisX = xAxisVS; | ||
|
@@ -1891,8 +1889,8 @@ void GetEnvLightVolumeDataAndBound(HDProbe probe, LightVolumeType lightVolumeTyp | |
bound.boxAxisX = influenceRightVS * influenceExtents.x; | ||
bound.boxAxisY = influenceUpVS * influenceExtents.x; | ||
bound.boxAxisZ = influenceForwardVS * influenceExtents.x; | ||
bound.scaleXY.Set(1.0f, 1.0f); | ||
bound.radius = influenceExtents.x; | ||
bound.scaleXY = 1.0f; | ||
bound.radius = influenceExtents.x; | ||
break; | ||
} | ||
case LightVolumeType.Box: | ||
|
@@ -1901,8 +1899,8 @@ void GetEnvLightVolumeDataAndBound(HDProbe probe, LightVolumeType lightVolumeTyp | |
bound.boxAxisX = influenceExtents.x * influenceRightVS; | ||
bound.boxAxisY = influenceExtents.y * influenceUpVS; | ||
bound.boxAxisZ = influenceExtents.z * influenceForwardVS; | ||
bound.scaleXY.Set(1.0f, 1.0f); | ||
bound.radius = influenceExtents.magnitude; | ||
bound.scaleXY = 1.0f; | ||
bound.radius = influenceExtents.magnitude; | ||
|
||
// The culling system culls pixels that are further | ||
// than a threshold to the box influence extents. | ||
|
@@ -1942,7 +1940,7 @@ void AddBoxVolumeDataAndBound(OrientedBBox obb, LightCategory category, LightFea | |
bound.boxAxisY = obb.extentY * upVS; | ||
bound.boxAxisZ = obb.extentZ * forwardVS; | ||
bound.radius = extents.magnitude; | ||
bound.scaleXY.Set(1.0f, 1.0f); | ||
bound.scaleXY = 1.0f; | ||
|
||
// The culling system culls pixels that are further | ||
// than a threshold to the box influence extents. | ||
|
@@ -2771,19 +2769,27 @@ static void GenerateLightsScreenSpaceAABBs(in BuildGPULightListParameters parame | |
{ | ||
if (parameters.totalLightCount != 0) | ||
{ | ||
var tileAndCluster = resources.tileAndClusterData; | ||
using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.GenerateLightAABBs))) | ||
{ | ||
var tileAndCluster = resources.tileAndClusterData; | ||
|
||
cmd.SetComputeIntParam(parameters.screenSpaceAABBShader, HDShaderIDs.g_isOrthographic, parameters.isOrthographic ? 1 : 0); | ||
|
||
cmd.SetComputeIntParam(parameters.screenSpaceAABBShader, HDShaderIDs.g_isOrthographic, parameters.isOrthographic ? 1 : 0); | ||
// With XR single-pass, we have one set of light bounds per view to iterate over (bounds are in view space for each view) | ||
cmd.SetComputeIntParam(parameters.screenSpaceAABBShader, HDShaderIDs.g_iNrVisibLights, parameters.totalLightCount); | ||
cmd.SetComputeBufferParam(parameters.screenSpaceAABBShader, parameters.screenSpaceAABBKernel, HDShaderIDs.g_data, tileAndCluster.convexBoundsBuffer); | ||
cmd.SetComputeBufferParam(parameters.screenSpaceAABBShader, parameters.screenSpaceAABBKernel, HDShaderIDs.g_vBoundsBuffer, tileAndCluster.AABBBoundsBuffer); | ||
|
||
// With XR single-pass, we have one set of light bounds per view to iterate over (bounds are in view space for each view) | ||
cmd.SetComputeIntParam(parameters.screenSpaceAABBShader, HDShaderIDs.g_iNrVisibLights, parameters.totalLightCount); | ||
cmd.SetComputeBufferParam(parameters.screenSpaceAABBShader, parameters.screenSpaceAABBKernel, HDShaderIDs.g_data, tileAndCluster.convexBoundsBuffer); | ||
cmd.SetComputeBufferParam(parameters.screenSpaceAABBShader, parameters.screenSpaceAABBKernel, HDShaderIDs.g_vBoundsBuffer, tileAndCluster.AABBBoundsBuffer); | ||
cmd.SetComputeMatrixArrayParam(parameters.screenSpaceAABBShader, HDShaderIDs.g_mProjectionArr, parameters.lightListProjHMatrices); | ||
cmd.SetComputeMatrixArrayParam(parameters.screenSpaceAABBShader, HDShaderIDs.g_mInvProjectionArr, parameters.lightListInvProjHMatrices); | ||
|
||
cmd.SetComputeMatrixArrayParam(parameters.screenSpaceAABBShader, HDShaderIDs.g_mProjectionArr, parameters.lightListProjHMatrices); | ||
cmd.SetComputeMatrixArrayParam(parameters.screenSpaceAABBShader, HDShaderIDs.g_mInvProjectionArr, parameters.lightListInvProjHMatrices); | ||
const int threadsPerLight = 4; // Shader: THREADS_PER_LIGHT (4) | ||
const int threadsPerGroup = 64; // Shader: THREADS_PER_GROUP (64) | ||
|
||
cmd.DispatchCompute(parameters.screenSpaceAABBShader, parameters.screenSpaceAABBKernel, (parameters.totalLightCount + 7) / 8, parameters.viewCount, 1); | ||
int groupCount = HDUtils.DivRoundUp(parameters.totalLightCount * threadsPerLight, threadsPerGroup); | ||
|
||
cmd.DispatchCompute(parameters.screenSpaceAABBShader, parameters.screenSpaceAABBKernel, groupCount, parameters.viewCount, 1); | ||
} | ||
} | ||
} | ||
|
||
|
@@ -3067,7 +3073,7 @@ BuildGPULightListParameters PrepareBuildGPULightListParameters(HDCamera hdCamera | |
|
||
// Screen space AABB | ||
parameters.screenSpaceAABBShader = buildScreenAABBShader; | ||
parameters.screenSpaceAABBKernel = isProjectionOblique ? s_GenAABBKernel_Oblique : s_GenAABBKernel; | ||
parameters.screenSpaceAABBKernel = 0; | ||
// camera to screen matrix (and it's inverse) | ||
for (int viewIndex = 0; viewIndex < hdCamera.viewCount; ++viewIndex) | ||
{ | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so I know this is not great but we can't rename it without breaking existing code of users (this is also used by URP).
Here there is not a lot of choice, either we don't rename it, or we do the following.
in common.hlsl:
static const float3x3 k_Identity3x3 = {
(i.e your change).
And in CommonDeprecated.hlsl
we add :
// This is obsolete, don't used, keep for compatiblity.
static const float3x3 k_identity3x3 = k_Identity3x3 ;
this will work and not break existing code.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that this is a fix. I actually couldn't find this constant because it was capitalized in the wrong way.
I can fix URP (or already have). I propose we just add a comment in this file. If someone's code breaks, it is trivial to fix.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
being it a fix or not isn't the problem. The issue is that it will break users custom shader. The proposal is to allow to fix the nomenclature and still not break existing user code (by putting old version as k_identity3x3 )
And yes URP code should be fix in this case as well. You should consider make a separate PR for this change as it isn't related to improve AABB generation and touch a lot of files.