Skip to content

Commit

Permalink
Ported MaskVolumes and Dynamic GI to RenderGraph (#27)
Browse files Browse the repository at this point in the history
* Ported MaskVolumes to RenderGraph

* Made MaskVolume light lists work with RenderGraph

* Made ProbeVolumes DynamicGI work with RenderGraph

* Remove accidentially introduced extra space (to avoid merge conflicts in the future)

Co-authored-by: Nicholas Brancaccio <pastasfuture@gmail.com>
  • Loading branch information
2 people authored and pastasfuture committed Oct 18, 2021
1 parent 3066b19 commit 5ee578e
Show file tree
Hide file tree
Showing 7 changed files with 462 additions and 155 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3936,16 +3936,23 @@ static void PushProbeVolumeLightListGlobalParams(in LightLoopGlobalParameters pa
{
Camera camera = param.hdCamera.camera;

if (param.hdCamera.frameSettings.IsEnabled(FrameSettingsField.BigTilePrepass))
cmd.SetGlobalBuffer(HDShaderIDs.g_vBigTileLightList, param.tileAndClusterData.bigTileLightList);

// int useDepthBuffer = 0;
// cmd.SetGlobalInt(HDShaderIDs.g_isLogBaseBufferEnabled, useDepthBuffer);
cmd.SetGlobalBuffer(HDShaderIDs.g_vProbeVolumesLayeredOffsetsBuffer, param.tileAndClusterData.perVoxelOffset);
cmd.SetGlobalBuffer(HDShaderIDs.g_vProbeVolumesLightListGlobal, param.tileAndClusterData.perVoxelLightLists);
DoPushProbeVolumeLightListGlobalParams(
cmd,
param.tileAndClusterData.perVoxelOffset,
param.tileAndClusterData.perVoxelLightLists,
param.hdCamera.frameSettings.IsEnabled(FrameSettingsField.BigTilePrepass) ? param.tileAndClusterData.bigTileLightList : null);
}
}

static void DoPushProbeVolumeLightListGlobalParams(CommandBuffer cmd, ComputeBuffer perVoxelOffset, ComputeBuffer perVoxelLightLists, ComputeBuffer bigTileLightList)
{
cmd.SetGlobalBuffer(HDShaderIDs.g_vProbeVolumesLayeredOffsetsBuffer, perVoxelOffset);
cmd.SetGlobalBuffer(HDShaderIDs.g_vProbeVolumesLightListGlobal, perVoxelLightLists);

if (bigTileLightList != null)
cmd.SetGlobalBuffer(HDShaderIDs.g_vBigTileLightList, bigTileLightList);
}

static void PushMaskVolumeLightListGlobalParams(in LightLoopGlobalParameters param, CommandBuffer cmd)
{
if (!param.hdCamera.frameSettings.IsEnabled(FrameSettingsField.MaskVolume))
Expand All @@ -3955,15 +3962,23 @@ static void PushMaskVolumeLightListGlobalParams(in LightLoopGlobalParameters par
{
Camera camera = param.hdCamera.camera;

if (param.hdCamera.frameSettings.IsEnabled(FrameSettingsField.BigTilePrepass))
cmd.SetGlobalBuffer(HDShaderIDs.g_vBigTileLightList, param.tileAndClusterData.bigTileLightList);

// int useDepthBuffer = 0;
// cmd.SetGlobalInt(HDShaderIDs.g_isLogBaseBufferEnabled, useDepthBuffer);
cmd.SetGlobalBuffer(HDShaderIDs.g_vMaskVolumesLayeredOffsetsBuffer, param.tileAndClusterData.perVoxelOffset);
cmd.SetGlobalBuffer(HDShaderIDs.g_vMaskVolumesLightListGlobal, param.tileAndClusterData.perVoxelLightLists);
DoPushMaskVolumeLightListGlobalParams(
cmd,
param.tileAndClusterData.perVoxelOffset,
param.tileAndClusterData.perVoxelLightLists,
param.hdCamera.frameSettings.IsEnabled(FrameSettingsField.BigTilePrepass) ? param.tileAndClusterData.bigTileLightList : null);
}
}

static void DoPushMaskVolumeLightListGlobalParams(CommandBuffer cmd, ComputeBuffer perVoxelOffset, ComputeBuffer perVoxelLightLists, ComputeBuffer bigTileLightList)
{
cmd.SetGlobalBuffer(HDShaderIDs.g_vMaskVolumesLayeredOffsetsBuffer, perVoxelOffset);
cmd.SetGlobalBuffer(HDShaderIDs.g_vMaskVolumesLightListGlobal, perVoxelLightLists);

if (bigTileLightList != null)
cmd.SetGlobalBuffer(HDShaderIDs.g_vBigTileLightList, bigTileLightList);
}

void BuildGPULightListProbeVolumesCommon(HDCamera hdCamera, CommandBuffer cmd)
{
// Custom probe volume only light list is only needed if we are evaluating probe volumes early, in the GBuffer phase.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -305,41 +305,41 @@ public void ClearAllActive(bool clearAll)
}


internal void DispatchProbePropagation(ScriptableRenderContext renderContext, HDCamera hdCamera, CommandBuffer cmd, ProbeVolumeHandle probeVolume, ProbeDynamicGI giSettings, in ShaderVariablesGlobal shaderGlobals, RTHandle probeVolumeAtlasSHRTHandle)
internal void DispatchProbePropagation(CommandBuffer cmd, ProbeVolumeHandle probeVolume, ProbeDynamicGI giSettings, in ShaderVariablesGlobal shaderGlobals, RenderTargetIdentifier probeVolumeAtlasSHRTHandle)
{
if (hdCamera.camera.cameraType == CameraType.Game || hdCamera.camera.cameraType == CameraType.SceneView)
if (probeVolume.parameters.supportDynamicGI
&& probeVolume.IsDataAssigned()
&& probeVolume.HasNeighbors()
&& probeVolume.GetProbeVolumeEngineDataIndex() >= 0)
{
if (probeVolume.parameters.supportDynamicGI
&& probeVolume.IsDataAssigned()
&& probeVolume.HasNeighbors()
&& probeVolume.GetProbeVolumeEngineDataIndex() >= 0)
{
InitializePropagationBuffers(probeVolume);
InitializePropagationBuffers(probeVolume);

if (giSettings.clear.value || _clearAllActive)
{
ClearRadianceCache(probeVolume);
}

DispatchPropagationHits(cmd, probeVolume, in giSettings);
DispatchPropagationAxes(cmd, probeVolume, in giSettings);
DispatchPropagationCombine(cmd, probeVolume, in giSettings, in shaderGlobals, probeVolumeAtlasSHRTHandle);
probeVolume.propagationBuffers.SwapRadianceCaches();
if (giSettings.clear.value || _clearAllActive)
{
ClearRadianceCache(probeVolume);
}
else

DispatchPropagationHits(cmd, probeVolume, in giSettings);
DispatchPropagationAxes(cmd, probeVolume, in giSettings);
DispatchPropagationCombine(cmd, probeVolume, in giSettings, in shaderGlobals, probeVolumeAtlasSHRTHandle);
probeVolume.propagationBuffers.SwapRadianceCaches();
}
else
{
if (CleanupPropagation(probeVolume))
{
if (CleanupPropagation(probeVolume))
{
// trigger an update so original bake data gets set since Dynamic GI was disabled
probeVolume.SetDataUpdated(true);
}
// trigger an update so original bake data gets set since Dynamic GI was disabled
probeVolume.SetDataUpdated(true);
}
}
}

internal void ClearProbePropagation(ScriptableRenderContext renderContext, HDCamera hdCamera, CommandBuffer cmd, ProbeVolumeHandle probeVolume, ProbeDynamicGI giSettings, in ShaderVariablesGlobal shaderGlobals, RTHandle probeVolumeAtlasSHRTHandle)
internal void ClearProbePropagation(CommandBuffer cmd, ProbeVolumeHandle probeVolume, ProbeDynamicGI giSettings, in ShaderVariablesGlobal shaderGlobals, RenderTargetIdentifier probeVolumeAtlasSHRTHandle)
{
if (hdCamera.camera.cameraType == CameraType.Game || hdCamera.camera.cameraType == CameraType.SceneView)
if (probeVolume.parameters.supportDynamicGI
&& probeVolume.IsDataAssigned()
&& probeVolume.HasNeighbors()
&& probeVolume.GetProbeVolumeEngineDataIndex() >= 0)
{
if (probeVolume.parameters.supportDynamicGI
&& probeVolume.IsDataAssigned()
Expand Down Expand Up @@ -434,7 +434,7 @@ void DispatchPropagationAxes(CommandBuffer cmd, ProbeVolumeHandle probeVolume, i
cmd.DispatchCompute(shader, kernel, dispatchX, 1, 1);
}

void DispatchPropagationCombine(CommandBuffer cmd, ProbeVolumeHandle probeVolume, in ProbeDynamicGI giSettings, in ShaderVariablesGlobal shaderGlobals, RTHandle probeVolumeAtlasSHRTHandle)
void DispatchPropagationCombine(CommandBuffer cmd, ProbeVolumeHandle probeVolume, in ProbeDynamicGI giSettings, in ShaderVariablesGlobal shaderGlobals, RenderTargetIdentifier probeVolumeAtlasSHRTHandle)
{
int numProbes = probeVolume.parameters.resolutionX * probeVolume.parameters.resolutionY * probeVolume.parameters.resolutionZ;
ProbeVolume.ProbeVolumeAtlasKey key = probeVolume.ComputeProbeVolumeAtlasKey();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1035,46 +1035,89 @@ ProbeVolumeList PrepareVisibleProbeVolumeList(HDCamera hdCamera, CommandBuffer i
return probeVolumes;
}

void DispatchProbeVolumeDynamicGI(ScriptableRenderContext renderContext, HDCamera hdCamera, CommandBuffer cmd)
enum ProbeVolumeDynamicGIMode
{
if (!m_SupportProbeVolume) { return; }
None,
Dispatch,
Clear
}

struct ProbeVolumeDynamicGICommonData
{
public ProbeVolumeDynamicGIMode mode;
public List<ProbeVolumeHandle> volumes;
public ProbeDynamicGI giSettings;
public ShaderVariablesGlobal globalCB;
}

class ProbeVolumeDynamicGIPassData
{
public ProbeVolumeDynamicGICommonData commonData;
public TextureHandle probeVolumesAtlas;
}

ProbeVolumeDynamicGICommonData PrepareProbeVolumeDynamicGIData(HDCamera hdCamera)
{
ProbeVolumeDynamicGICommonData data = new ProbeVolumeDynamicGICommonData() { mode = ProbeVolumeDynamicGIMode.None };

if (ShaderConfig.s_ProbeVolumesEvaluationMode == ProbeVolumesEvaluationModes.Disabled)
return data;

if (hdCamera.camera.cameraType != CameraType.Game && hdCamera.camera.cameraType != CameraType.SceneView)
return data;

if (!hdCamera.frameSettings.IsEnabled(FrameSettingsField.ProbeVolume))
return data;

if (!m_SupportProbeVolume)
return data;

data.volumes = ProbeVolumeManager.manager.GetVolumesToRender();
data.giSettings = hdCamera.volumeStack.GetComponent<ProbeDynamicGI>();
data.globalCB = m_ShaderVariablesGlobalCB;

if(hdCamera.frameSettings.IsEnabled(FrameSettingsField.ProbeVolume))
if (hdCamera.frameSettings.IsEnabled(FrameSettingsField.ProbeVolumeDynamicGI))
{
using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.ProbeVolumeDynamicGI)))
data.mode = ProbeVolumeDynamicGIMode.Dispatch;
m_WasProbeVolumeDynamicGIEnabled = true;
}
else if (m_WasProbeVolumeDynamicGIEnabled)
{
data.mode = ProbeVolumeDynamicGIMode.Clear;
m_WasProbeVolumeDynamicGIEnabled = false;
}

return data;
}

static void ExecuteProbeVolumeDynamicGI(CommandBuffer cmd, ProbeVolumeDynamicGICommonData data, RenderTargetIdentifier probeVolumeAtlas)
{
using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.ProbeVolumeDynamicGI)))
{
if (data.mode == ProbeVolumeDynamicGIMode.Dispatch)
{
// Collect all visible finite volume data, and upload it to the GPU.
List<ProbeVolumeHandle> volumes = ProbeVolumeManager.manager.GetVolumesToRender();
var giSettings = hdCamera.volumeStack.GetComponent<ProbeDynamicGI>();
float maxRange = Mathf.Max(giSettings.rangeBehindCamera.value, giSettings.rangeInFrontOfCamera.value);
float maxRange = Mathf.Max(data.giSettings.rangeBehindCamera.value, data.giSettings.rangeInFrontOfCamera.value);

if (hdCamera.frameSettings.IsEnabled(FrameSettingsField.ProbeVolumeDynamicGI))
// Update Probe Volume Data via Dynamic GI Propagation
for (int probeVolumeIndex = 0; probeVolumeIndex < data.volumes.Count; ++probeVolumeIndex)
{
m_WasProbeVolumeDynamicGIEnabled = true;
ProbeVolumeHandle volume = data.volumes[probeVolumeIndex];

// Update Probe Volume Data via Dynamic GI Propagation
for (int probeVolumeIndex = 0; probeVolumeIndex < volumes.Count; ++probeVolumeIndex)
// basic distance check
var obb = volume.GetProbeVolumeEngineDataBoundingBox();
float maxExtent = Mathf.Max(obb.extentX, Mathf.Max(obb.extentY, obb.extentZ));
if (obb.center.magnitude < (maxRange + maxExtent))
{
ProbeVolumeHandle volume = volumes[probeVolumeIndex];

// basic distance check
var obb = volume.GetProbeVolumeEngineDataBoundingBox();
float maxExtent = Mathf.Max(obb.extentX, Mathf.Max(obb.extentY, obb.extentZ));
if (obb.center.magnitude < (maxRange + maxExtent))
{
ProbeVolumeDynamicGI.instance.DispatchProbePropagation(renderContext, hdCamera, cmd, volume, giSettings, in m_ShaderVariablesGlobalCB, m_ProbeVolumeAtlasSHRTHandle);
}
ProbeVolumeDynamicGI.instance.DispatchProbePropagation(cmd, volume, data.giSettings, in data.globalCB, probeVolumeAtlas);
}
}
else if(m_WasProbeVolumeDynamicGIEnabled)
}
else if (data.mode == ProbeVolumeDynamicGIMode.Clear)
{
for (int probeVolumeIndex = 0; probeVolumeIndex < data.volumes.Count; ++probeVolumeIndex)
{
for (int probeVolumeIndex = 0; probeVolumeIndex < volumes.Count; ++probeVolumeIndex)
{
ProbeVolumeHandle volume = volumes[probeVolumeIndex];
ProbeVolumeDynamicGI.instance.ClearProbePropagation(renderContext, hdCamera, cmd, volume, giSettings, in m_ShaderVariablesGlobalCB, m_ProbeVolumeAtlasSHRTHandle);
}

m_WasProbeVolumeDynamicGIEnabled = false;
ProbeVolumeHandle volume = data.volumes[probeVolumeIndex];
ProbeVolumeDynamicGI.instance.ClearProbePropagation(cmd, volume, data.giSettings, in data.globalCB, probeVolumeAtlas);
}
}
}
Expand Down

0 comments on commit 5ee578e

Please sign in to comment.