Skip to content

Commit fa93c05

Browse files
Texture-weighted automatic exposure (#165)
* Exposure weighted by texture * miss one in the renaming * Doc update * changelog * doc update * fix issue when disabling override
1 parent b18334b commit fa93c05

File tree

7 files changed

+53
-6
lines changed

7 files changed

+53
-6
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
105105
- Added Light decomposition lighting debugging modes and support in AOV
106106
- Added exposure compensation to Fixed exposure mode
107107
- Added support for rasterized area light shadows in StackLit
108+
- Added support for texture-weighted automatic exposure
108109

109110
### Fixed
110111
- Fix when rescale probe all direction below zero (1219246)

com.unity.render-pipelines.high-definition/Documentation~/Override-Exposure.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ To configure **Automatic Mode**, select the **Metering Mode**. This tells the Ca
6565

6666
![](Images/Override-Exposure3.png)
6767

68+
- **Mask Weighted**: The Camera applies a weight to every pixel in the buffer then uses the weights to measure the exposure. To specify the weighting, this technique uses the Texture set in the **Weight Texture Mask** field. Note that, if you do not provide a Texture, this metering mode is equivalent to **Average**.
69+
70+
6871
Next, set the **Limit Min** and **Limit Max** to define the minimum and maximum exposure values respectively. Move between light and dark areas of your Scene and alter each property until you find the perfect values for your Scene.
6972

7073

com.unity.render-pipelines.high-definition/Editor/PostProcessing/ExposureEditor.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ sealed class ExposureEditor : VolumeComponentEditor
2020
SerializedDataParameter m_AdaptationSpeedDarkToLight;
2121
SerializedDataParameter m_AdaptationSpeedLightToDark;
2222

23+
SerializedDataParameter m_WeightTextureMask;
24+
2325
public override void OnEnable()
2426
{
2527
var o = new PropertyFetcher<Exposure>(serializedObject);
@@ -37,6 +39,8 @@ public override void OnEnable()
3739
m_AdaptationMode = Unpack(o.Find(x => x.adaptationMode));
3840
m_AdaptationSpeedDarkToLight = Unpack(o.Find(x => x.adaptationSpeedDarkToLight));
3941
m_AdaptationSpeedLightToDark = Unpack(o.Find(x => x.adaptationSpeedLightToDark));
42+
43+
m_WeightTextureMask = Unpack(o.Find(x => x.weightTextureMask));
4044
}
4145

4246
public override void OnInspectorGUI()
@@ -58,6 +62,9 @@ public override void OnInspectorGUI()
5862
EditorGUILayout.Space();
5963

6064
PropertyField(m_MeteringMode);
65+
if(m_MeteringMode.value.intValue == (int)MeteringMode.MaskWeighted)
66+
PropertyField(m_WeightTextureMask);
67+
6168
PropertyField(m_LuminanceSource);
6269

6370
if (m_LuminanceSource.value.intValue == (int)LuminanceSource.LightingBuffer)

com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Components/Exposure.cs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,12 @@ public sealed class Exposure : VolumeComponent, IPostProcessComponent
8585
[Tooltip("Sets the speed at which the exposure changes when the Camera moves from a bright area to a dark area.")]
8686
public MinFloatParameter adaptationSpeedLightToDark = new MinFloatParameter(1f, 0.001f);
8787

88+
/// <summary>
89+
/// Sets the texture mask used to weight the pixels in the buffer when computing exposure. Used only with .
90+
/// </summary>
91+
[Tooltip("Sets the texture mask to be used to weight the pixels in the buffer for the sake of computing exposure..")]
92+
public NoInterpTextureParameter weightTextureMask = new NoInterpTextureParameter(null);
93+
8894
/// <summary>
8995
/// Tells if the effect needs to be rendered or not.
9096
/// </summary>
@@ -145,7 +151,16 @@ public enum MeteringMode
145151
/// have the minimum weight, and pixels in between have a progressively lower weight the
146152
/// closer they are to the screen borders.
147153
/// </summary>
148-
CenterWeighted
154+
CenterWeighted,
155+
156+
157+
/// <summary>
158+
/// The Camera applies a weight to every pixel in the buffer and then uses them to measure
159+
/// the exposure. The weighting is specified by the texture provided by the user. Note that if
160+
/// no texture is provided, then this metering mode is equivalent to Average.
161+
/// </summary>
162+
MaskWeighted
163+
149164
}
150165

151166
/// <summary>

com.unity.render-pipelines.high-definition/Runtime/PostProcessing/PostProcessSystem.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -873,6 +873,14 @@ void DoDynamicExposure(CommandBuffer cmd, HDCamera camera, RTHandle colorBuffer)
873873
cmd.SetComputeIntParams(cs, HDShaderIDs._Variants, m_ExposureVariants);
874874
cmd.SetComputeTextureParam(cs, kernel, HDShaderIDs._PreviousExposureTexture, prevExposure);
875875
cmd.SetComputeTextureParam(cs, kernel, HDShaderIDs._SourceTexture, sourceTex);
876+
if (m_Exposure.meteringMode == MeteringMode.MaskWeighted && m_Exposure.weightTextureMask.value != null)
877+
{
878+
cmd.SetComputeTextureParam(cs, kernel, HDShaderIDs._ExposureWeightMask, m_Exposure.weightTextureMask.value);
879+
}
880+
else
881+
{
882+
cmd.SetComputeTextureParam(cs, kernel, HDShaderIDs._ExposureWeightMask, Texture2D.whiteTexture);
883+
}
876884
cmd.SetComputeTextureParam(cs, kernel, HDShaderIDs._OutputTexture, m_TempTexture1024);
877885
cmd.DispatchCompute(cs, kernel, 1024 / 8, 1024 / 8, 1);
878886

com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Shaders/Exposure.compute

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414
TEXTURE2D(_ExposureCurveTexture);
1515
TEXTURE2D(_PreviousExposureTexture);
1616
TEXTURE2D(_InputTexture);
17+
18+
TEXTURE2D(_ExposureWeightMask);
19+
1720
TEXTURE2D_X(_SourceTexture);
1821

1922
RW_TEXTURE2D(float2, _OutputTexture);
@@ -42,6 +45,9 @@ CBUFFER_END
4245
#define ParamAdaptationMode _Variants.z
4346
#define ParamEvaluateMode _Variants.w
4447

48+
#define PREPASS_TEX_SIZE 1024.0
49+
#define PREPASS_TEX_HALF_SIZE 512.0
50+
4551
float WeightSample(uint2 pixel)
4652
{
4753
UNITY_BRANCH
@@ -50,17 +56,23 @@ float WeightSample(uint2 pixel)
5056
case 1u:
5157
{
5258
// Spot metering
53-
const float kRadius = 0.075 * 1024.0;
54-
const float2 kCenter = (512.0).xx;
59+
const float kRadius = 0.075 * PREPASS_TEX_SIZE;
60+
const float2 kCenter = (PREPASS_TEX_HALF_SIZE).xx;
5561
float d = length(kCenter - pixel) - kRadius;
5662
return 1.0 - saturate(d);
5763
}
5864
case 2u:
5965
{
6066
// Center-weighted
61-
const float2 kCenter = (512.0).xx;
62-
return 1.0 - saturate(pow(length(kCenter - pixel) / 512.0, 1.0));
67+
const float2 kCenter = (PREPASS_TEX_HALF_SIZE).xx;
68+
return 1.0 - saturate(pow(length(kCenter - pixel) / PREPASS_TEX_HALF_SIZE, 1.0));
6369
}
70+
case 3u:
71+
{
72+
// Mask weigthing
73+
return SAMPLE_TEXTURE2D_LOD(_ExposureWeightMask, sampler_LinearClamp, pixel * rcp(PREPASS_TEX_SIZE), 0.0).x;
74+
}
75+
6476
default:
6577
{
6678
// Global average
@@ -126,7 +138,7 @@ void KPrePass(uint2 dispatchThreadId : SV_DispatchThreadID)
126138
// For XR, interleave single-pass views in a checkerboard pattern
127139
UNITY_XR_ASSIGN_VIEW_INDEX((dispatchThreadId.x + dispatchThreadId.y) % _XRViewCount)
128140

129-
PositionInputs posInputs = GetPositionInput(float2(dispatchThreadId), 1.0 / 1024.0, uint2(8u, 8u));
141+
PositionInputs posInputs = GetPositionInput(float2(dispatchThreadId), rcp(PREPASS_TEX_SIZE), uint2(8u, 8u));
130142
float2 uv = ClampAndScaleUVForBilinear(posInputs.positionNDC);
131143
float luma;
132144

com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDStringConstants.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -596,6 +596,7 @@ static class HDShaderIDs
596596
public static readonly int _ExposureParams = Shader.PropertyToID("_ExposureParams");
597597
public static readonly int _AdaptationParams = Shader.PropertyToID("_AdaptationParams");
598598
public static readonly int _ExposureCurveTexture = Shader.PropertyToID("_ExposureCurveTexture");
599+
public static readonly int _ExposureWeightMask = Shader.PropertyToID("_ExposureWeightMask");
599600
public static readonly int _Variants = Shader.PropertyToID("_Variants");
600601
public static readonly int _InputTexture = Shader.PropertyToID("_InputTexture");
601602
public static readonly int _OutputTexture = Shader.PropertyToID("_OutputTexture");

0 commit comments

Comments
 (0)