-
Notifications
You must be signed in to change notification settings - Fork 857
Binary APV data with runtime data separated from debug data #6196
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
Conversation
…ialization slowdown (affects domain reloads). Store shader data pre-swizzled (priming a future loading PR).
…ebug display checked. Hide PV debug options when they are not available (and the entire panel when none are)
Hi! This comment will help you figure out which jobs to run before merging your PR. The suggestions are dynamic based on what files you have changed. HDRP SRP Core Depending on the scope of your PR, you may need to run more jobs than what has been suggested. Please speak to your lead or a Graphics SDET (#devs-graphics-automation) if you are unsure. |
|
||
static Dictionary<Vector3Int, int> m_CellPosToIndex = new Dictionary<Vector3Int, int>(); | ||
static Dictionary<int, Cell> m_BakedCells = new Dictionary<int, Cell>(); | ||
static Dictionary<int, BakingCell> m_BakedCells = new Dictionary<int, BakingCell>(); |
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.
BakingCell is now used throughout the entire baking process, only converted to a runtime Cell at the very end of the baking process.
com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.cs
Outdated
Show resolved
Hide resolved
asset.cells.Add(cell); | ||
if (!assetsCommitted.Contains(assetPath)) | ||
{ | ||
WritebackModifiedCellsData(asset); |
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.
Because of the way data storage is aliased, dilation now writes directly into the backing storage and we just re-commit that to disk.
} | ||
} | ||
|
||
// Convert baking cells to runtime cells |
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.
We convert all cells of an asset in a single operation since their data is flattened into shared storage.
AssetDatabase.Refresh(); | ||
probeRefVolume.clearAssetsOnVolumeClear = false; | ||
|
||
m_BakingBatch = null; |
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.
Clearing this exposes the fact that we still occasionally have multiple callbacks registered for completion (the second one will encounter this null and bail out with a callstack)
cellSupportDataFilename = System.IO.Path.ChangeExtension(sourceFilename, "CellSupportData.bytes"); | ||
} | ||
|
||
static void WriteBakingCells(ProbeVolumeAsset asset, List<BakingCell> bakingCells) |
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.
Flatten all cells into two byte streams: one for runtime data and one for debug data.
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.
Now there are three byte streams (the essential data, the optional data - aka L2, and the support data - aka debug) as discussed.
startCounts.Add(cellCounts); | ||
} | ||
|
||
// Need to save here because the forced import below discards the changes. |
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.
This feels like a bug to me.. I'll ask around Slack for what would cause this.
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.
(did ask, will log a bug for this separately)
com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeVolumeAssetEditor.cs
Show resolved
Hide resolved
com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeBrickPool.cs
Outdated
Show resolved
Hide resolved
com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeBrickPool.cs
Outdated
Show resolved
Hide resolved
if (parameters.supportsRuntimeDebug) | ||
{ | ||
// Cells / Bricks visualization is not implemented in a runtime compatible way atm. | ||
if(Application.isEditor) | ||
widgetList.Add(subdivContainer); | ||
|
||
widgetList.Add(probeContainer); | ||
} | ||
|
||
if (parameters.supportStreaming) | ||
{ | ||
widgetList.Add(streamingContainer); | ||
} | ||
|
||
m_DebugItems = widgetList.ToArray(); | ||
var panel = DebugManager.instance.GetPanel("Probe Volume", true); | ||
panel.children.Add(m_DebugItems); | ||
if (widgetList.Count > 0) | ||
{ | ||
m_DebugItems = widgetList.ToArray(); | ||
var panel = DebugManager.instance.GetPanel("Probe Volume", true); | ||
panel.children.Add(m_DebugItems); | ||
} |
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.
Hide the options that don't have the required backing data available.
com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolumeAsset.cs
Outdated
Show resolved
Hide resolved
com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolumePerSceneData.cs
Show resolved
Hide resolved
if (assets.TryGetValue(m_CurrentState, out var asset) && asset != null) | ||
{ | ||
refVol.AddPendingAssetLoading(assets[m_CurrentState]); | ||
asset.ResolveCells(); |
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.
The source data needed to resolve is propagated in OnAfterDeserialize.
public void StripSupportData() | ||
{ | ||
foreach (var asset in assets.Values) | ||
asset.cellSupportDataAsset = null; |
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.
Since OnBeforeSerialize reads this is serves as clearing out the use of the support data asset thus omitting it from builds.
// TODO: Arguably we should just destroy the entire component if 'supportProbeVolumes' is disabled. Otherwise previously baked data | ||
// will still be bundled with players and loaded with the scene even though the entire feature is disabled. Discuss this | ||
// before enabling it, though. |
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.
Thoughts?
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.
Not sure as AFAIK you can potentially swap global settings asset while the player is running (not sure why you would, but it could happen)
for (int i = 0; i < probeCount; ++i) | ||
{ | ||
dilatedProbes[i].FromSphericalHarmonicsL2(cell.sh[i]); | ||
dilatedProbes[i].FromSphericalHarmonicsShaderConstants(cell.shBands, cell.shData, i); |
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.
The problem I have with this not dilating the whole 3 bands is that this now makes switching between L1 and L2 at runtime not possible.
Let's assume the data is baked with L1 set as option, then it will be stored as L1 with garbage L2.
Switching then to L2 will require a rebake as otherwise garbage will be read.
I see where you are coming from, but I can also this potentially rising issues and annoyances for users.
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.
Before I go on and look more at the PR we should discuss this as I think is pivotal for the rest.
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.
As discussed, we currently always store all three bands when baking (i.e. ignore current lighting setting for bake). A new toggle should be introduced for controlling how many bands to store / how many bands to bundle with builds. Loading mixed cells already works.
Will look at this in few minutes, also adding @JulienIgnace-Unity as this will be likely relevant for streaming |
|
||
cell.sh = new SphericalHarmonicsL2[numProbes]; | ||
cell.validity = new float[numProbes]; | ||
cell.offsetVectors = new Vector3[0]; // pending PR #6169 |
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.
Reminder here for me/you to remove this comment when we can
com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.cs
Show resolved
Hide resolved
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.
Added some comments here and there in addition to what we discussed via slack already, let's have another pass when that lands!
com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.cs
Show resolved
Hide resolved
com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeBrickPool.cs
Outdated
Show resolved
Hide resolved
com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeBrickPool.cs
Outdated
Show resolved
Hide resolved
com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeBrickPool.cs
Outdated
Show resolved
Hide resolved
|
||
// shData is swizzled for direct runtime upload | ||
// | ||
// L0r0, L0g0, L0b0, L1r0 |
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.
It'd be nice to have a very small function to this PR that moves from a probe index to a SphericalHarmonicsL2 (undoing the swizzling) as I am sure it'll be useful for debug and potentially other use cases.
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.
These exist:
ProbeGIBaking.WriteToShaderCoeffsL0L1/WriteToShaderCoeffsL2/ReadFromShaderCoeffsL0L1/ReadFromShaderCoeffsL2
DilatedProbe.FromSphericalHarmonicsShaderConstants/ToSphericalHarmonicsShaderConstants
com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeReferenceVolume.cs
Show resolved
Hide resolved
com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolumeAsset.cs
Outdated
Show resolved
Hide resolved
com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolumeAsset.cs
Outdated
Show resolved
Hide resolved
com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolumePerSceneData.cs
Show resolved
Hide resolved
// TODO: Arguably we should just destroy the entire component if 'supportProbeVolumes' is disabled. Otherwise previously baked data | ||
// will still be bundled with players and loaded with the scene even though the entire feature is disabled. Discuss this | ||
// before enabling it, though. |
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.
Not sure as AFAIK you can potentially swap global settings asset while the player is running (not sure why you would, but it could happen)
Any ETA on when (or if) this can go be updated? @adrien-de-tocqueville is currently working on baking states and we'd need to do some optimization on having just SH data in a separate asset; this PR looks like could provide one way of doing that so but if we do something else might end up conflicting badly with this :-) Let us know if you need us to take ownership of the PR if you don't have the time! |
… feedback and discussions.
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.
minor comment, also note that the formatting job is failing
#endif | ||
if (!settings.supportRuntimeDebugDisplay) | ||
{ | ||
Debug.Log($"Stripping debug data from Probe Volume in scene '{scene.name}'."); |
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.
do we want to keep that log here ?
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.
I have no strong opinion tbh. I feel like it's somewhat similar to the debug log for shader stripping, in that it's nice to be able to verify in the log that the debug data was indeed stripped.
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.
i guess people assume debug data are stripped so i would remove it, but not very important
com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.cs
Show resolved
Hide resolved
thanks for pointing that out. I meant to launch the apply formatting job but forgot :( |
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.
Test status: Done
Whats tested:
- Compared baked result of classroom scene Master vs PR
- Checked Dilation still works
- Checked that Virtual Offset still works
- Debug modes still display bricks, cells and probes
- Global and local volumes still work
- Baking from lighting tab and APV tab
- Baking with Spherical Harmonics L1 and L2
- Creating baking sets and using them
- Changing memory budget
- Building player to see APV is there
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.
I updated my review. I did quite a few tests but as this feature is already used in production I focused on looking for regressions. Have not found any new issues
# Conflicts: # com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeReferenceVolume.Debug.cs # com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeReferenceVolume.cs
Hey, test are failing for standalone now: |
Argh yeah this is not compatible with old assets, @tlaedre can you please rebake that test and update screenshots if needed? |
I could, if I had any idea whatsoever how that worked. Is there any docs for how to update test screenshots? |
I guess this update should be part of the PR? |
Yes, give me 10 min and I can explain in slack |
# Conflicts: # com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.cs
NOTE: This PR depends on native (git) PR#6458 and will stay in draft until this dependency lands.
Purpose of this PR
This PR addresses a couple of overlapping issues with Probe Volume lighting data storage.
The primary purpose of this PR is to change PV lighting data to use a more performant storage method. The way Unity serialization works, storing large amounts of data (hundreds of MB) in ScriptableObjects adds significant overhead to editor and runtime loading. In a test scene with ~150 MB of baked lighting data, storing the data in ScriptableObjects adds more than 4 seconds of domain reload overhead, whereas storing it in the binary format add no measurable overhead.
(As a more extreme example, having baked data in one of our current production scenes stored as ScriptableObjects adds more than 30 seconds overhead to every domain reload, whereas with the binary method the overhead is negligible).
The second purpose is to separate runtime data from debug data to reduce build size and runtime memory usage. Debug data will be included in builds if the global HDRP settings have the runtime debug shaders checkbox ticked, but otherwise stripped for builds. The Probe Volume debug UI will present options based on which data is available.
Lastly, the probes storage itself is changed in two ways: It no longer always stores three full SH bands but instead stores the format of the actual baked data. The probe coefficients are stored pre-swizzled in the final format they will be uploaded as at runtime (the last bit is up for discussion, it came from a performance investigation that I will open a discussion about separately).
Testing status
Tested manually in test scenes and our production project.
Tested in editor and player builds.
Comments to reviewers
Generally speaking, see comments inline in code.
I suppose one of the more controversial changes here might be the decision to change the swizzled format of the probe data. This originated from the fact that runtime loading of cells is quite slow atm and is an overlapping part of ongoing work investigating loading performance (I will bring this as a discussion to Slack before putting further serious work into it). It's easy enough to undo, but at the very least as things stand now, I think it makes sense to store data as close to the runtime usage as possible.