Skip to content

Commit 608db4a

Browse files
AndrewSaraevUnitypastasfuture
authored andcommitted
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 4d1364c commit 608db4a

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>
@@ -2117,9 +2120,19 @@ internal void ReserveShadowMap(Camera camera, HDShadowManager shadowManager, HDS
21172120
// The idea is to have a lot of resolution when the camera is close to the light OR the screen area is high.
21182121

21192122
// linear normalized distance between the light and camera with max shadow distance
2120-
float distance01 = Mathf.Clamp01(Vector3.Distance(camera.transform.position, visibleLight.GetPosition()) / shadowSettings.maxShadowDistance.value);
2121-
// ease out and invert the curve, give more importance to closer distances
2122-
distance01 = 1.0f - Mathf.Pow(distance01, 2);
2123+
float distance01;
2124+
#if UNITY_EDITOR
2125+
if (ProbeVolume.preparingMixedLights)
2126+
{
2127+
distance01 = 1.0f;
2128+
}
2129+
else
2130+
#endif
2131+
{
2132+
distance01 = Mathf.Clamp01(Vector3.Distance(camera.transform.position, visibleLight.GetPosition()) / shadowSettings.maxShadowDistance.value);
2133+
// ease out and invert the curve, give more importance to closer distances
2134+
distance01 = 1.0f - Mathf.Pow(distance01, 2);
2135+
}
21232136

21242137
// normalized ratio between light range and distance
21252138
float range01 = Mathf.Clamp01(visibleLight.range / Vector3.Distance(camera.transform.position, visibleLight.GetPosition()));
@@ -2787,9 +2800,30 @@ void OnValidate()
27872800
// 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
27882801
// prefab instance. So we delay the check on next update (and before teh LateUpdate logic)
27892802
m_NeedsPrefabInstanceCheck = true;
2803+
2804+
UpdateDynamicGIMixedMode();
27902805
#endif
27912806
}
27922807

2808+
#if UNITY_EDITOR
2809+
internal void UpdateDynamicGIMixedMode()
2810+
{
2811+
var mixed = legacyLight.lightmapBakeType == LightmapBakeType.Mixed;
2812+
if (mixed != m_MixedDynamicGI)
2813+
{
2814+
m_MixedDynamicGI = mixed;
2815+
if (lightEntity.valid)
2816+
HDLightRenderDatabase.instance.EditLightDataAsRef(lightEntity).mixedDynamicGI = mixed;
2817+
2818+
if (!EditorApplication.isPlayingOrWillChangePlaymode)
2819+
{
2820+
EditorUtility.SetDirty(this);
2821+
PrefabUtility.RecordPrefabInstancePropertyModifications(this);
2822+
}
2823+
}
2824+
}
2825+
#endif
2826+
27932827
#region Update functions to patch values in the Light component when we change properties inside HDAdditionalLightData
27942828

27952829
void SetLightIntensityPunctual(float intensity)
@@ -3532,6 +3566,7 @@ internal void UpdateRenderEntity()
35323566
lightRenderData.areaLightShape = m_AreaLightShape;
35333567
lightRenderData.lightLayer = m_LightlayersMask;
35343568
lightRenderData.affectDynamicGI = m_AffectDynamicGI;
3569+
lightRenderData.mixedDynamicGI = m_MixedDynamicGI;
35353570
lightRenderData.fadeDistance = m_FadeDistance;
35363571
lightRenderData.distance = m_Distance;
35373572
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
@@ -1601,8 +1601,13 @@ internal int GetCurrentShadowCount()
16011601

16021602
void LightLoopUpdateCullingParameters(ref ScriptableCullingParameters cullingParams, HDCamera hdCamera)
16031603
{
1604-
var shadowMaxDistance = hdCamera.volumeStack.GetComponent<HDShadowSettings>().maxShadowDistance.value;
1605-
m_ShadowManager.UpdateCullingParameters(ref cullingParams, shadowMaxDistance);
1604+
#if UNITY_EDITOR
1605+
if (!ProbeVolume.preparingMixedLights)
1606+
#endif
1607+
{
1608+
var shadowMaxDistance = hdCamera.volumeStack.GetComponent<HDShadowSettings>().maxShadowDistance.value;
1609+
m_ShadowManager.UpdateCullingParameters(ref cullingParams, shadowMaxDistance);
1610+
}
16061611

16071612
// In HDRP we don't need per object light/probe info so we disable the native code that handles it.
16081613
cullingParams.cullingOptions |= CullingOptions.DisablePerObjectCulling;
@@ -2167,7 +2172,13 @@ bool PrepareLightsForGPU(CommandBuffer cmd, HDCamera hdCamera, CullingResults cu
21672172
}
21682173

21692174
bool dynamicGIEnabled = hdCamera.frameSettings.IsEnabled(FrameSettingsField.ProbeVolumeDynamicGI);
2170-
if (dynamicGIEnabled)
2175+
bool dynamicGINeedsLights =
2176+
#if UNITY_EDITOR
2177+
ProbeVolume.preparingMixedLights ||
2178+
#endif
2179+
hdCamera.frameSettings.probeVolumeDynamicGIMixedLightMode != ProbeVolumeDynamicGIMixedLightMode.MixedOnly;
2180+
2181+
if (dynamicGIEnabled && dynamicGINeedsLights)
21712182
{
21722183
PreprocessDynamicGILights(cmd, hdCamera, cullResults, debugDisplaySettings, aovRequest);
21732184
PrepareDynamicGIGPULightdata(cmd, hdCamera, cullResults);

0 commit comments

Comments
 (0)