Skip to content

Commit 4338bc4

Browse files
Reset ambient probe upon switching to very different skies (#3340)
* Set ambient probe to black when there is a big difference * Changelog * Fix a couple of things * Change name Co-authored-by: sebastienlagarde <sebastien@unity3d.com>
1 parent b648896 commit 4338bc4

File tree

6 files changed

+74
-18
lines changed

6 files changed

+74
-18
lines changed

com.unity.render-pipelines.high-definition/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
1616
- Fixed an exception when opening the color picker in the material UI (case 1307143).
1717
- Fixed lights shadow frustum near and far planes.
1818
- Fixed various issues with non-temporal SSAO and rendergraph.
19+
- Fix screen being over-exposed when changing very different skies.
1920

2021
### Changed
2122
- Removed the material pass probe volumes evaluation mode.

com.unity.render-pipelines.high-definition/Runtime/Sky/HDRISky/HDRISky.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,21 @@ public override int GetHashCode()
169169
return hash;
170170
}
171171

172+
/// <summary>
173+
/// Determines if the SkySettings is significantly divergent from another. This is going to be used to determine whether
174+
/// to reset completely the ambient probe instead of using previous one when waiting for current data upon changes.
175+
/// In addition to the checks done with the base function, this HDRISky override checks whether the cubemap parameter
176+
/// has changed if both settings are HDRISky.
177+
/// </summary>
178+
/// <param name="otherSettings">The settings to compare with.</param>
179+
/// <returns>Whether the settings are deemed very different.</returns>
180+
public override bool SignificantlyDivergesFrom(SkySettings otherSettings)
181+
{
182+
HDRISky otherHdriSkySettings = otherSettings as HDRISky;
183+
184+
return base.SignificantlyDivergesFrom(otherSettings) || hdriSky.value != otherHdriSkySettings.hdriSky.value;
185+
}
186+
172187
/// <summary>
173188
/// Returns HDRISkyRenderer type.
174189
/// </summary>

com.unity.render-pipelines.high-definition/Runtime/Sky/SkyManager.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,11 @@ void AllocateNewRenderingContext(SkyUpdateContext skyContext, int slot, int newH
617617
if (context.renderingContext == null)
618618
context.renderingContext = new SkyRenderingContext(m_Resolution, m_IBLFilterArray.Length, supportConvolution, previousAmbientProbe, name);
619619

620+
// If we detected a big difference with previous settings, then carrying over the previous ambient probe is probably going to lead to unexpected result.
621+
// Instead we at least fallback to a neutral one until async readback has finished.
622+
if (skyContext.settingsHadBigDifferenceWithPrev)
623+
context.renderingContext.ClearAmbientProbe();
624+
620625
skyContext.cachedSkyRenderingContextId = slot;
621626
}
622627

com.unity.render-pipelines.high-definition/Runtime/Sky/SkyRenderer.cs

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -70,24 +70,7 @@ public virtual void PreRenderSky(BuiltinSkyParameters builtinParams) {}
7070
/// <returns>Returns SkySetting exposure.</returns>
7171
protected static float GetSkyIntensity(SkySettings skySettings, DebugDisplaySettings debugSettings)
7272
{
73-
float skyIntensity = 1.0f;
74-
75-
switch (skySettings.skyIntensityMode.value)
76-
{
77-
case SkyIntensityMode.Exposure:
78-
// Note: Here we use EV100 of sky as a multiplier, so it is the opposite of when use with a Camera
79-
// because for sky/light, higher EV mean brighter, but for camera higher EV mean darker scene
80-
skyIntensity *= ColorUtils.ConvertEV100ToExposure(-skySettings.exposure.value);
81-
break;
82-
case SkyIntensityMode.Multiplier:
83-
skyIntensity *= skySettings.multiplier.value;
84-
break;
85-
case SkyIntensityMode.Lux:
86-
skyIntensity *= skySettings.desiredLuxValue.value / skySettings.upperHemisphereLuxValue.value;
87-
break;
88-
}
89-
90-
return skyIntensity;
73+
return skySettings.GetIntensityFromSettings();
9174
}
9275

9376
/// <summary>

com.unity.render-pipelines.high-definition/Runtime/Sky/SkySettings.cs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,51 @@ public static int GetUniqueID(Type type)
217217
return uniqueID;
218218
}
219219

220+
/// <summary>
221+
/// Returns the sky intensity as determined by this SkySetting.
222+
/// </summary>
223+
/// <returns>The sky intensity.</returns>
224+
public float GetIntensityFromSettings()
225+
{
226+
float skyIntensity = 1.0f;
227+
switch (skyIntensityMode.value)
228+
{
229+
case SkyIntensityMode.Exposure:
230+
// Note: Here we use EV100 of sky as a multiplier, so it is the opposite of when use with a Camera
231+
// because for sky/light, higher EV mean brighter, but for camera higher EV mean darker scene
232+
skyIntensity *= ColorUtils.ConvertEV100ToExposure(-exposure.value);
233+
break;
234+
case SkyIntensityMode.Multiplier:
235+
skyIntensity *= multiplier.value;
236+
break;
237+
case SkyIntensityMode.Lux:
238+
skyIntensity *= desiredLuxValue.value / upperHemisphereLuxValue.value;
239+
break;
240+
}
241+
return skyIntensity;
242+
}
243+
244+
/// <summary>
245+
/// Determines if the SkySettings is significantly divergent from another. This is going to be used to determine whether
246+
/// to reset completely the ambient probe instead of using previous one when waiting for current data upon changes.
247+
/// Override this to have a per-sky specific heuristic.
248+
/// </summary>
249+
/// <param name="otherSettings">The settings to compare with.</param>
250+
/// <returns>Whether the settings are deemed very different.</returns>
251+
public virtual bool SignificantlyDivergesFrom(SkySettings otherSettings)
252+
{
253+
if (otherSettings.GetSkyRendererType() != GetSkyRendererType())
254+
return true;
255+
256+
float thisIntensity = GetIntensityFromSettings();
257+
float otherIntensity = otherSettings.GetIntensityFromSettings();
258+
259+
// This is an arbitrary difference threshold. This needs to be re-evaluated in case it is proven problematic
260+
float intensityRatio = thisIntensity > otherIntensity ? (thisIntensity / otherIntensity) : (otherIntensity / thisIntensity);
261+
const float ratioThreshold = 3.0f;
262+
return intensityRatio > ratioThreshold;
263+
}
264+
220265
/// <summary>
221266
/// Returns the class type of the SkyRenderer associated with this Sky Settings.
222267
/// </summary>

com.unity.render-pipelines.high-definition/Runtime/Sky/SkyUpdateContext.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ internal class SkyUpdateContext
1414
public int skyParametersHash = -1;
1515
public float currentUpdateTime = 0.0f;
1616

17+
public bool settingsHadBigDifferenceWithPrev { get; private set; }
18+
1719
public SkySettings skySettings
1820
{
1921
get { return m_SkySettings; }
@@ -28,6 +30,11 @@ public SkySettings skySettings
2830
skyRenderer = null;
2931
}
3032

33+
if (m_SkySettings == null)
34+
settingsHadBigDifferenceWithPrev = true;
35+
else
36+
settingsHadBigDifferenceWithPrev = m_SkySettings.SignificantlyDivergesFrom(value);
37+
3138
if (m_SkySettings == value)
3239
return;
3340

0 commit comments

Comments
 (0)