Skip to content

Commit eb01f25

Browse files
DGI Mixed Lights (#76)
* Mark mixed lights when Probe Volume is baked to filter them out of the dynamic GI light list. * Added mixed lights data to DGI neighborhood and rendering. Using manual baking steps for now. * Update and save mixed lights baked status when lights are processed by the pipeline in the baking mode. * Added frame settings to pick a combination of realtime and mixed lights to use for dynamic GI. * Force shadow rendering regardless of distances when preparing for mixed lights baking. * Restored dynamic GI basic support for all mixed light modes after the light list merge. Now need to restore forced shadowmap rendering while mixed baking is prepared. * Restored after merge: force shadowmap rendering while mixed baking is prepared by dynamic GI. * Make dynamic GI mixed lighting preview show correct expected result for the current indirect scale setting.
1 parent 2159f3a commit eb01f25

File tree

16 files changed

+275
-51
lines changed

16 files changed

+275
-51
lines changed

com.unity.render-pipelines.high-definition/Editor/Lighting/HDLightEditor.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,12 @@ public override void OnInspectorGUI()
8888
hdLightData.UpdateRenderEntity();
8989
}
9090
}
91+
else
92+
{
93+
// Lightmapping mode changes don't trigger GUI change checks so we have to force this.
94+
foreach (var hdLightData in m_AdditionalLightDatas)
95+
hdLightData.UpdateDynamicGIMixedMode();
96+
}
9197

9298
if (m_SerializedHDLight.needUpdateAreaLightEmissiveMeshComponents)
9399
UpdateAreaLightEmissiveMeshComponents();

com.unity.render-pipelines.high-definition/Editor/Lighting/ProbeVolume/ProbeVolumeUI.Drawer.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using UnityEngine.Rendering.HighDefinition;
33
using UnityEditor.Rendering;
44
using UnityEditorInternal;
5+
using UnityEngine.UI;
56

67
// TODO(Nicholas): deduplicate with DensityVolumeUI.Drawer.cs.
78
namespace UnityEditor.Rendering.HighDefinition
@@ -117,6 +118,21 @@ static void Drawer_BakeToolBar(SerializedProbeVolume serialized, Editor owner)
117118
EditorUtility.ClearProgressBar();
118119
}
119120
GUILayout.EndHorizontal();
121+
122+
EditorGUILayout.Space();
123+
124+
ProbeVolume.preparingMixedLights = EditorGUILayout.Toggle(Styles.k_PrepareMixedLightsText, ProbeVolume.preparingMixedLights);
125+
GUI.enabled = ProbeVolume.preparingMixedLights;
126+
127+
if (GUILayout.Button(Styles.k_BakeMixedLightsText))
128+
{
129+
var targets = serialized.GetTargetObjects();
130+
for (int i = 0; i < targets.Length; i++)
131+
{
132+
var probeVolume = (ProbeVolume)targets[i];
133+
probeVolume.CopyDirectLightingToMixed();
134+
}
135+
}
120136
}
121137

122138
static void Drawer_ToolBar(SerializedProbeVolume serialized, Editor owner)

com.unity.render-pipelines.high-definition/Editor/Lighting/ProbeVolume/ProbeVolumeUI.Skin.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ internal static class Styles
1616
internal const string k_BakingHeader = "Baking";
1717
internal const string k_BakeSelectedText = "Bake Selected";
1818
internal const string k_BakeDynamicGIOnlyText = "Bake Dynamic GI Only";
19+
internal const string k_PrepareMixedLightsText = "Prepare Mixed Lights";
20+
internal const string k_BakeMixedLightsText = "Bake Mixed Lights";
1921

2022
internal static readonly GUIContent[] s_Toolbar_Contents = new GUIContent[]
2123
{

com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Settings/FrameSettingsUI.Drawers.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,13 @@ static void Drawer_SectionLightingSettings(SerializedFrameSettings serialized, E
355355
hasMixedValues: serialized.probeVolumeDynamicGIMaxSimulationsPerFrame.hasMultipleDifferentValues,
356356
overrideable: () => hdrpSettings.supportProbeVolume && hdrpSettings.supportProbeVolumeDynamicGI
357357
);
358+
area.AmmendInfo(FrameSettingsField.ProbeVolumeDynamicGIMixedLightMode,
359+
overridedDefaultValue: ProbeVolumeDynamicGIMixedLightMode.Mixed,
360+
customGetter: () => serialized.probeVolumeDynamicGIMixedLightMode.GetEnumValue<ProbeVolumeDynamicGIMixedLightMode>(),
361+
customSetter: v => serialized.probeVolumeDynamicGIMixedLightMode.SetEnumValue((ProbeVolumeDynamicGIMixedLightMode)v),
362+
hasMixedValues: serialized.probeVolumeDynamicGIMixedLightMode.hasMultipleDifferentValues,
363+
overrideable: () => hdrpSettings.supportProbeVolume && hdrpSettings.supportProbeVolumeDynamicGI
364+
);
358365

359366
area.AmmendInfo(FrameSettingsField.Volumetrics, overrideable: () => hdrpSettings.supportVolumetrics);
360367
area.AmmendInfo(FrameSettingsField.ReprojectionForVolumetrics, overrideable: () => hdrpSettings.supportVolumetrics);

com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Settings/SerializedFrameSettings.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ class SerializedFrameSettings
2222
public SerializedProperty maximumLODLevelQualityLevel;
2323
public SerializedProperty probeVolumeDynamicGIPropagationQuality;
2424
public SerializedProperty probeVolumeDynamicGIMaxSimulationsPerFrame;
25+
public SerializedProperty probeVolumeDynamicGIMixedLightMode;
2526
public SerializedProperty materialQuality;
2627

2728
public SerializedObject serializedObject => m_RootData.serializedObject;
@@ -104,6 +105,7 @@ public SerializedFrameSettings(SerializedProperty rootData, SerializedProperty r
104105
maximumLODLevelQualityLevel = rootData.FindPropertyRelative("maximumLODLevelQualityLevel");
105106
probeVolumeDynamicGIPropagationQuality = rootData.FindPropertyRelative("probeVolumeDynamicGIPropagationQuality");
106107
probeVolumeDynamicGIMaxSimulationsPerFrame = rootData.FindPropertyRelative("probeVolumeDynamicGIMaxSimulationsPerFrame");
108+
probeVolumeDynamicGIMixedLightMode = rootData.FindPropertyRelative("probeVolumeDynamicGIMixedLightMode");
107109
materialQuality = rootData.Find((FrameSettings s) => s.materialQuality);
108110
}
109111

com.unity.render-pipelines.high-definition/Runtime/Lighting/Light/HDAdditionalLightData.cs

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1207,6 +1207,9 @@ public bool affectDynamicGI
12071207
}
12081208
}
12091209

1210+
[SerializeField]
1211+
bool m_MixedDynamicGI = false;
1212+
12101213
/// <summary>
12111214
/// Returns a mask of light layers as uint and handle the case of Everything as being 0xFF and not -1
12121215
/// </summary>
@@ -2127,9 +2130,19 @@ internal void ReserveShadowMap(Camera camera, HDShadowManager shadowManager, HDS
21272130
// The idea is to have a lot of resolution when the camera is close to the light OR the screen area is high.
21282131

21292132
// linear normalized distance between the light and camera with max shadow distance
2130-
float distance01 = Mathf.Clamp01(Vector3.Distance(camera.transform.position, visibleLight.GetPosition()) / shadowSettings.maxShadowDistance.value);
2131-
// ease out and invert the curve, give more importance to closer distances
2132-
distance01 = 1.0f - Mathf.Pow(distance01, 2);
2133+
float distance01;
2134+
#if UNITY_EDITOR
2135+
if (ProbeVolume.preparingMixedLights)
2136+
{
2137+
distance01 = 1.0f;
2138+
}
2139+
else
2140+
#endif
2141+
{
2142+
distance01 = Mathf.Clamp01(Vector3.Distance(camera.transform.position, visibleLight.GetPosition()) / shadowSettings.maxShadowDistance.value);
2143+
// ease out and invert the curve, give more importance to closer distances
2144+
distance01 = 1.0f - Mathf.Pow(distance01, 2);
2145+
}
21332146

21342147
// normalized ratio between light range and distance
21352148
float range01 = Mathf.Clamp01(visibleLight.range / Vector3.Distance(camera.transform.position, visibleLight.GetPosition()));
@@ -2800,9 +2813,30 @@ void OnValidate()
28002813
// If modification are due to change on prefab asset, we want to have prefab instances to self-update, but we cannot check in OnValidate if this is part of
28012814
// prefab instance. So we delay the check on next update (and before teh LateUpdate logic)
28022815
m_NeedsPrefabInstanceCheck = true;
2816+
2817+
UpdateDynamicGIMixedMode();
28032818
#endif
28042819
}
28052820

2821+
#if UNITY_EDITOR
2822+
internal void UpdateDynamicGIMixedMode()
2823+
{
2824+
var mixed = legacyLight.lightmapBakeType == LightmapBakeType.Mixed;
2825+
if (mixed != m_MixedDynamicGI)
2826+
{
2827+
m_MixedDynamicGI = mixed;
2828+
if (lightEntity.valid)
2829+
HDLightRenderDatabase.instance.EditLightDataAsRef(lightEntity).mixedDynamicGI = mixed;
2830+
2831+
if (!EditorApplication.isPlayingOrWillChangePlaymode)
2832+
{
2833+
EditorUtility.SetDirty(this);
2834+
PrefabUtility.RecordPrefabInstancePropertyModifications(this);
2835+
}
2836+
}
2837+
}
2838+
#endif
2839+
28062840
#region Update functions to patch values in the Light component when we change properties inside HDAdditionalLightData
28072841

28082842
void SetLightIntensityPunctual(float intensity)
@@ -3545,6 +3579,7 @@ internal void UpdateRenderEntity()
35453579
lightRenderData.areaLightShape = m_AreaLightShape;
35463580
lightRenderData.lightLayer = m_LightlayersMask;
35473581
lightRenderData.affectDynamicGI = m_AffectDynamicGI;
3582+
lightRenderData.mixedDynamicGI = m_MixedDynamicGI;
35483583
lightRenderData.fadeDistance = m_FadeDistance;
35493584
lightRenderData.distance = m_Distance;
35503585
lightRenderData.angularDiameter = m_AngularDiameter;

com.unity.render-pipelines.high-definition/Runtime/Lighting/Light/HDGpuLightsBuilder.Jobs.cs

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ internal struct CreateGpuLightDataJobGlobalConfig
1818
public int invalidScreenSpaceShadowIndex;
1919
public float maxShadowFadeDistance;
2020

21+
#if UNITY_EDITOR
22+
public bool dynamicGIPreparingMixedLights;
23+
#endif
24+
2125
public static CreateGpuLightDataJobGlobalConfig Create(
2226
HDCamera hdCamera,
2327
HDShadowSettings hdShadowSettings)
@@ -27,7 +31,11 @@ public static CreateGpuLightDataJobGlobalConfig Create(
2731
lightLayersEnabled = hdCamera.frameSettings.IsEnabled(FrameSettingsField.LightLayers),
2832
specularGlobalDimmer = hdCamera.frameSettings.specularGlobalDimmer,
2933
maxShadowFadeDistance = hdShadowSettings.maxShadowDistance.value,
30-
invalidScreenSpaceShadowIndex = (int)LightDefinitions.s_InvalidScreenSpaceShadow
34+
invalidScreenSpaceShadowIndex = (int)LightDefinitions.s_InvalidScreenSpaceShadow,
35+
36+
#if UNITY_EDITOR
37+
dynamicGIPreparingMixedLights = ProbeVolume.preparingMixedLights,
38+
#endif
3139
};
3240
}
3341
}
@@ -309,10 +317,20 @@ public static void ConvertLightToGPUFormat(
309317
lightData.affectDynamicGI = lightRenderData.affectDynamicGI ? 1 : 0;
310318

311319
var distanceToCamera = processedEntity.distanceToCamera;
312-
var lightsShadowFadeDistance = lightRenderData.shadowFadeDistance;
320+
float shadowDistanceFade;
321+
#if UNITY_EDITOR
322+
if (globalConfig.dynamicGIPreparingMixedLights)
323+
{
324+
shadowDistanceFade = 1f;
325+
}
326+
else
327+
#endif
328+
{
329+
var lightsShadowFadeDistance = lightRenderData.shadowFadeDistance;
330+
shadowDistanceFade = HDUtils.ComputeLinearDistanceFade(distanceToCamera, Mathf.Min(globalConfig.maxShadowFadeDistance, lightsShadowFadeDistance));
331+
}
313332
var shadowDimmerVal = lightRenderData.shadowDimmer;
314333
var volumetricShadowDimmerVal = lightRenderData.affectVolumetric ? lightRenderData.volumetricShadowDimmer : 0.0f;
315-
float shadowDistanceFade = HDUtils.ComputeLinearDistanceFade(distanceToCamera, Mathf.Min(globalConfig.maxShadowFadeDistance, lightsShadowFadeDistance));
316334
lightData.shadowDimmer = shadowDistanceFade * shadowDimmerVal;
317335
lightData.volumetricShadowDimmer = shadowDistanceFade * volumetricShadowDimmerVal;
318336

com.unity.render-pipelines.high-definition/Runtime/Lighting/Light/HDLightRenderDatabase.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ internal struct HDLightRenderData
2424
public AreaLightShape areaLightShape;
2525
public LightLayerEnum lightLayer;
2626
public bool affectDynamicGI;
27+
public bool mixedDynamicGI;
2728
public float fadeDistance;
2829
public float distance;
2930
public float angularDiameter;

com.unity.render-pipelines.high-definition/Runtime/Lighting/Light/HDProcessedVisibleLightsBuilder.Jobs.cs

Lines changed: 61 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,14 @@ protected struct ProcessVisibleLightJob : IJobParallelFor
4747
public bool enableAreaLights;
4848
[ReadOnly]
4949
public bool onlyDynamicGI;
50+
[ReadOnly]
51+
public bool dynamicGIUseRealtimeLights;
52+
[ReadOnly]
53+
public bool dynamicGIUseMixedLights;
54+
#if UNITY_EDITOR
55+
[ReadOnly]
56+
public bool dynamicGIPreparingMixedLights;
57+
#endif
5058
[ReadOnly]
5159
public bool evaluateShadowStates;
5260
[ReadOnly]
@@ -187,6 +195,9 @@ private HDProcessedVisibleLightsBuilder.ShadowMapFlags EvaluateShadowState(
187195

188196
// If the shadow is too far away, we don't render it
189197
bool isShadowInRange = lightType == HDLightType.Directional || distanceToCamera < shadowFadeDistanceVal;
198+
#if UNITY_EDITOR
199+
isShadowInRange |= dynamicGIPreparingMixedLights;
200+
#endif
190201
if (!isShadowInRange)
191202
return flags;
192203

@@ -250,8 +261,22 @@ public void Execute(int index)
250261

251262
ref HDLightRenderData lightRenderData = ref GetLightData(dataIndex);
252263

253-
if (onlyDynamicGI && !lightRenderData.affectDynamicGI)
254-
return;
264+
if (onlyDynamicGI)
265+
{
266+
if (!lightRenderData.affectDynamicGI)
267+
return;
268+
269+
if (lightRenderData.mixedDynamicGI)
270+
{
271+
if (!dynamicGIUseMixedLights)
272+
return;
273+
}
274+
else
275+
{
276+
if (!dynamicGIUseRealtimeLights)
277+
return;
278+
}
279+
}
255280

256281
if (enableRayTracing && !lightRenderData.includeForRayTracing)
257282
return;
@@ -278,7 +303,17 @@ public void Execute(int index)
278303
if (debugFilterMode != DebugLightFilterMode.None && debugFilterMode.IsEnabledFor(gpuLightType, spotLightShape))
279304
return;
280305

281-
float lightDistanceFade = gpuLightType == GPULightType.Directional ? 1.0f : HDUtils.ComputeLinearDistanceFade(distanceToCamera, lightRenderData.fadeDistance);
306+
float lightDistanceFade;
307+
#if UNITY_EDITOR
308+
if (dynamicGIPreparingMixedLights)
309+
{
310+
lightDistanceFade = 1.0f;
311+
}
312+
else
313+
#endif
314+
{
315+
lightDistanceFade = gpuLightType == GPULightType.Directional ? 1.0f : HDUtils.ComputeLinearDistanceFade(distanceToCamera, lightRenderData.fadeDistance);
316+
}
282317
float volumetricDistanceFade = gpuLightType == GPULightType.Directional ? 1.0f : HDUtils.ComputeLinearDistanceFade(distanceToCamera, lightRenderData.volumetricFadeDistance);
283318

284319
bool contributesToLighting = ((lightRenderData.lightDimmer > 0) && (lightRenderData.affectDiffuse || lightRenderData.affectSpecular)) || ((lightRenderData.affectVolumetric ? lightRenderData.volumetricDimmer : 0.0f) > 0);
@@ -360,6 +395,10 @@ public void StartProcessVisibleLightJob(
360395
maxAreaLightsOnScreen = lightLoopSettings.maxAreaLightsOnScreen,
361396
debugFilterMode = debugDisplaySettings.GetDebugLightFilterMode(),
362397

398+
#if UNITY_EDITOR
399+
dynamicGIPreparingMixedLights = ProbeVolume.preparingMixedLights,
400+
#endif
401+
363402
//render light entities.
364403
lightData = lightEntityCollection.lightData,
365404

@@ -378,7 +417,7 @@ public void StartProcessVisibleLightJob(
378417
sortKeys = m_SortKeys,
379418
shadowLightsDataIndices = m_ShadowLightsDataIndices
380419
};
381-
OverrideProcessVisibleLightJobParameters(ref processVisibleLightJob);
420+
OverrideProcessVisibleLightJobParameters(hdCamera, ref processVisibleLightJob);
382421

383422
m_ProcessVisibleLightJobHandle = processVisibleLightJob.Schedule(m_Size, 32);
384423
}
@@ -391,12 +430,12 @@ public void CompleteProcessVisibleLightJob()
391430
m_ProcessVisibleLightJobHandle.Complete();
392431
}
393432

394-
protected abstract void OverrideProcessVisibleLightJobParameters(ref ProcessVisibleLightJob job);
433+
protected abstract void OverrideProcessVisibleLightJobParameters(HDCamera hdCamera, ref ProcessVisibleLightJob job);
395434
}
396435

397436
internal partial class HDProcessedVisibleLightsRegularBuilder : HDProcessedVisibleLightsBuilder
398437
{
399-
protected override void OverrideProcessVisibleLightJobParameters(ref ProcessVisibleLightJob job)
438+
protected override void OverrideProcessVisibleLightJobParameters(HDCamera hdCamera, ref ProcessVisibleLightJob job)
400439
{
401440
job.onlyDynamicGI = false;
402441
job.alwaysContributeToLightingWhenAffectsDynamicGI = false;
@@ -405,12 +444,26 @@ protected override void OverrideProcessVisibleLightJobParameters(ref ProcessVisi
405444
}
406445

407446
internal partial class HDProcessedVisibleLightsDynamicBuilder : HDProcessedVisibleLightsBuilder
408-
{
409-
protected override void OverrideProcessVisibleLightJobParameters(ref ProcessVisibleLightJob job)
447+
{
448+
protected override void OverrideProcessVisibleLightJobParameters(HDCamera hdCamera, ref ProcessVisibleLightJob job)
410449
{
411450
job.onlyDynamicGI = true;
412451
job.alwaysContributeToLightingWhenAffectsDynamicGI = true;
413452
job.evaluateShadowStates = false;
453+
454+
#if UNITY_EDITOR
455+
if (ProbeVolume.preparingMixedLights)
456+
{
457+
job.dynamicGIUseRealtimeLights = false;
458+
job.dynamicGIUseMixedLights = true;
459+
}
460+
else
461+
#endif
462+
{
463+
var dynamicGIMixedLightMode = hdCamera.frameSettings.probeVolumeDynamicGIMixedLightMode;
464+
job.dynamicGIUseRealtimeLights = dynamicGIMixedLightMode != ProbeVolumeDynamicGIMixedLightMode.MixedOnly;
465+
job.dynamicGIUseMixedLights = dynamicGIMixedLightMode == ProbeVolumeDynamicGIMixedLightMode.ForceRealtime;
466+
}
414467
}
415468
}
416469
}

com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/LightLoop.cs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1624,8 +1624,13 @@ internal int GetCurrentShadowCount()
16241624

16251625
void LightLoopUpdateCullingParameters(ref ScriptableCullingParameters cullingParams, HDCamera hdCamera)
16261626
{
1627-
var shadowMaxDistance = hdCamera.volumeStack.GetComponent<HDShadowSettings>().maxShadowDistance.value;
1628-
m_ShadowManager.UpdateCullingParameters(ref cullingParams, shadowMaxDistance);
1627+
#if UNITY_EDITOR
1628+
if (!ProbeVolume.preparingMixedLights)
1629+
#endif
1630+
{
1631+
var shadowMaxDistance = hdCamera.volumeStack.GetComponent<HDShadowSettings>().maxShadowDistance.value;
1632+
m_ShadowManager.UpdateCullingParameters(ref cullingParams, shadowMaxDistance);
1633+
}
16291634

16301635
// In HDRP we don't need per object light/probe info so we disable the native code that handles it.
16311636
cullingParams.cullingOptions |= CullingOptions.DisablePerObjectCulling;
@@ -2160,7 +2165,13 @@ bool PrepareLightsForGPU(CommandBuffer cmd, HDCamera hdCamera, CullingResults cu
21602165
}
21612166

21622167
bool dynamicGIEnabled = hdCamera.frameSettings.IsEnabled(FrameSettingsField.ProbeVolumeDynamicGI);
2163-
if (dynamicGIEnabled)
2168+
bool dynamicGINeedsLights =
2169+
#if UNITY_EDITOR
2170+
ProbeVolume.preparingMixedLights ||
2171+
#endif
2172+
hdCamera.frameSettings.probeVolumeDynamicGIMixedLightMode != ProbeVolumeDynamicGIMixedLightMode.MixedOnly;
2173+
2174+
if (dynamicGIEnabled && dynamicGINeedsLights)
21642175
{
21652176
PreprocessDynamicGILights(cmd, hdCamera, cullResults, debugDisplaySettings, aovRequest);
21662177
PrepareDynamicGIGPULightdata(cmd, hdCamera, cullResults);

0 commit comments

Comments
 (0)