Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,54 @@ partial class ProbeGIBaking
{
static List<MeshRenderer> addedOccluders;

private static void AddOccluders()
static void ApplyVirtualOffsets(Vector3[] positions, out Vector3[] offsets)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Simplify calling code by getting valid offsets output regardless of whether VO is enabled or not.

{
var voSettings = m_BakingSettings.virtualOffsetSettings;
if (!voSettings.useVirtualOffset)
{
offsets = null;
return;
}

var queriesHitBackBefore = Physics.queriesHitBackfaces;
try
{
Physics.queriesHitBackfaces = true;

AddOccluders();
ApplyVirtualOffsetsSingleThreaded(positions, out offsets, voSettings);
}
finally
{
Physics.queriesHitBackfaces = queriesHitBackBefore;
CleanupOccluders();
}
}

static void ApplyVirtualOffsetsSingleThreaded(Vector3[] positions, out Vector3[] offsets, VirtualOffsetSettings voSettings)
Copy link
Contributor Author

@tlaedre tlaedre Oct 28, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This and ApplyVirtualOffsets above are kinda stop-gap changes as the current approach is very slow in complex scenes.

There's a separate PR coming that moves this work into bursted jobs while also fixing some offsetting bugs (currently probes are actually pushed inside geometry in certain circumstances), so I've separated them as much as possible.

{
offsets = new Vector3[positions.Length];
for (int i = 0; i < positions.Length; ++i)
{
int subdivLevel = 0;
m_BakingBatch.uniqueBrickSubdiv.TryGetValue(positions[i], out subdivLevel);
float brickSize = ProbeReferenceVolume.CellSize(subdivLevel);
float searchDistance = (brickSize * m_BakingProfile.minBrickSize) / ProbeBrickPool.kBrickCellCount;

float scaleForSearchDist = voSettings.searchMultiplier;
Vector3 pushedPosition = PushPositionOutOfGeometry(positions[i], scaleForSearchDist * searchDistance, voSettings.outOfGeoOffset);

offsets[i] = pushedPosition - positions[i];
positions[i] = pushedPosition;
}
}

static void AddOccluders()
{
addedOccluders = new List<MeshRenderer>();
for (int sceneIndex = 0; sceneIndex < UnityEngine.SceneManagement.SceneManager.sceneCount; ++sceneIndex)
for (int sceneIndex = 0; sceneIndex < SceneManagement.SceneManager.sceneCount; ++sceneIndex)
{
UnityEngine.SceneManagement.Scene scene = UnityEngine.SceneManagement.SceneManager.GetSceneAt(sceneIndex);
SceneManagement.Scene scene = SceneManagement.SceneManager.GetSceneAt(sceneIndex);
if (!scene.isLoaded)
continue;

Expand All @@ -27,20 +69,26 @@ private static void AddOccluders()
MeshRenderer[] renderComponents = gameObject.GetComponentsInChildren<MeshRenderer>();
foreach (MeshRenderer mr in renderComponents)
{
if (!mr.gameObject.GetComponent<MeshCollider>() && (GameObjectUtility.GetStaticEditorFlags(mr.gameObject).HasFlag(StaticEditorFlags.ContributeGI)))
if ((GameObjectUtility.GetStaticEditorFlags(mr.gameObject) & StaticEditorFlags.ContributeGI) != 0 && !mr.gameObject.TryGetComponent<MeshCollider>(out _))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed to remove dual allocations from boxing.

{
var meshCollider = mr.gameObject.AddComponent<MeshCollider>();
meshCollider.hideFlags |= (HideFlags.DontSaveInEditor | HideFlags.DontSaveInBuild);
meshCollider.hideFlags |= HideFlags.DontSaveInEditor | HideFlags.DontSaveInBuild;
addedOccluders.Add(mr);
}
}
}
}

var autoSimState = Physics.autoSimulation;
Physics.autoSimulation = false;
Physics.Simulate(0.1f);
Physics.autoSimulation = autoSimState;
try
{
Physics.autoSimulation = false;
Physics.Simulate(0.1f);
}
finally
{
Physics.autoSimulation = autoSimState;
}
}

private static void CleanupOccluders()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class BakingBatch
public Dictionary<int, List<Scene>> cellIndex2SceneReferences = new Dictionary<int, List<Scene>>();
public List<BakingCell> cells = new List<BakingCell>();
public Dictionary<Vector3, int> uniquePositions = new Dictionary<Vector3, int>();
public Vector3[] virtualOffsets;
// Allow to get a mapping to subdiv level with the unique positions. It stores the minimum subdiv level found for a given position.
// Can be probably done cleaner.
public Dictionary<Vector3, int> uniqueBrickSubdiv = new Dictionary<Vector3, int>();
Expand Down Expand Up @@ -213,9 +214,6 @@ static void OnBakeStarted()

SetBakingContext(perSceneDataList);

if (m_BakingSettings.virtualOffsetSettings.useVirtualOffset)
AddOccluders();

RunPlacement();
}

Expand Down Expand Up @@ -473,6 +471,8 @@ static void OnAdditionalProbesBakeCompleted()
onAdditionalProbesBakeCompletedCalled = true;

var dilationSettings = m_BakingSettings.dilationSettings;
var virtualOffsets = m_BakingBatch.virtualOffsets;

// Fetch results of all cells
for (int c = 0; c < numCells; ++c)
{
Expand All @@ -488,12 +488,16 @@ static void OnAdditionalProbesBakeCompleted()

cell.sh = new SphericalHarmonicsL2[numProbes];
cell.validity = new float[numProbes];
cell.offsetVectors = new Vector3[0]; // pending PR #6169
cell.offsetVectors = new Vector3[virtualOffsets != null ? numProbes : 0];
cell.minSubdiv = probeRefVolume.GetMaxSubdivision();

for (int i = 0; i < numProbes; ++i)
{
int j = cell.probeIndices[i];

if (virtualOffsets != null)
cell.offsetVectors[i] = virtualOffsets[j];

SphericalHarmonicsL2 shv = sh[j];

int brickIdx = i / 64;
Expand Down Expand Up @@ -1082,24 +1086,9 @@ public static void ApplySubdivisionResults(ProbeSubdivisionResult results, Matri
m_BakingBatch.cellIndex2SceneReferences[cell.index] = results.scenesPerCells[cellPos].ToList();
}


// Move positions before sending them
// Virtually offset positions before passing them to lightmapper
var positions = m_BakingBatch.uniquePositions.Keys.ToArray();
VirtualOffsetSettings voSettings = m_BakingSettings.virtualOffsetSettings;
if (voSettings.useVirtualOffset)
{
for (int i = 0; i < positions.Length; ++i)
{
int subdivLevel = 0;
m_BakingBatch.uniqueBrickSubdiv.TryGetValue(positions[i], out subdivLevel);
float brickSize = ProbeReferenceVolume.CellSize(subdivLevel);
float searchDistance = (brickSize * m_BakingProfile.minBrickSize) / ProbeBrickPool.kBrickCellCount;

float scaleForSearchDist = voSettings.searchMultiplier;
positions[i] = PushPositionOutOfGeometry(positions[i], scaleForSearchDist * searchDistance, voSettings.outOfGeoOffset);
}
CleanupOccluders();
}
ApplyVirtualOffsets(positions, out m_BakingBatch.virtualOffsets);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This call adds occluders, calculates (and returns) offsets, and cleans up occluders if virtual offset is enabled.


UnityEditor.Experimental.Lightmapping.SetAdditionalBakedProbes(m_BakingBatch.index, positions);
}
Expand Down
Loading