From cb91e7bcfb0d1dc696d2737ba3419d376b915284 Mon Sep 17 00:00:00 2001 From: FrancescoC-Unity Date: Fri, 17 Apr 2020 09:47:02 +0200 Subject: [PATCH 1/6] Exposure weighted by texture --- .../Editor/PostProcessing/ExposureEditor.cs | 7 ++++++ .../PostProcessing/Components/Exposure.cs | 17 +++++++++++++- .../PostProcessing/PostProcessSystem.cs | 8 +++++++ .../PostProcessing/Shaders/Exposure.compute | 22 ++++++++++++++----- .../RenderPipeline/HDStringConstants.cs | 1 + 5 files changed, 49 insertions(+), 6 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Editor/PostProcessing/ExposureEditor.cs b/com.unity.render-pipelines.high-definition/Editor/PostProcessing/ExposureEditor.cs index 783223d4d49..a08652ed5d8 100644 --- a/com.unity.render-pipelines.high-definition/Editor/PostProcessing/ExposureEditor.cs +++ b/com.unity.render-pipelines.high-definition/Editor/PostProcessing/ExposureEditor.cs @@ -20,6 +20,8 @@ sealed class ExposureEditor : VolumeComponentEditor SerializedDataParameter m_AdaptationSpeedDarkToLight; SerializedDataParameter m_AdaptationSpeedLightToDark; + SerializedDataParameter m_WeightTextureMask; + public override void OnEnable() { var o = new PropertyFetcher(serializedObject); @@ -37,6 +39,8 @@ public override void OnEnable() m_AdaptationMode = Unpack(o.Find(x => x.adaptationMode)); m_AdaptationSpeedDarkToLight = Unpack(o.Find(x => x.adaptationSpeedDarkToLight)); m_AdaptationSpeedLightToDark = Unpack(o.Find(x => x.adaptationSpeedLightToDark)); + + m_WeightTextureMask = Unpack(o.Find(x => x.weightTextureMask)); } public override void OnInspectorGUI() @@ -58,6 +62,9 @@ public override void OnInspectorGUI() EditorGUILayout.Space(); PropertyField(m_MeteringMode); + if(m_MeteringMode.value.intValue == (int)MeteringMode.MaskWeighted) + PropertyField(m_WeightTextureMask); + PropertyField(m_LuminanceSource); if (m_LuminanceSource.value.intValue == (int)LuminanceSource.LightingBuffer) diff --git a/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Components/Exposure.cs b/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Components/Exposure.cs index 0fcba3505b1..0007c9c6076 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Components/Exposure.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Components/Exposure.cs @@ -85,6 +85,12 @@ public sealed class Exposure : VolumeComponent, IPostProcessComponent [Tooltip("Sets the speed at which the exposure changes when the Camera moves from a bright area to a dark area.")] public MinFloatParameter adaptationSpeedLightToDark = new MinFloatParameter(1f, 0.001f); + /// + /// Sets the texture mask used to weight the pixels in the buffer when computing exposure. Used only with . + /// + [Tooltip("Sets the texture mask to be used to weight the pixels in the buffer for the sake of computing exposure..")] + public NoInterpTextureParameter weightTextureMask = new NoInterpTextureParameter(null); + /// /// Tells if the effect needs to be rendered or not. /// @@ -145,7 +151,16 @@ public enum MeteringMode /// have the minimum weight, and pixels in between have a progressively lower weight the /// closer they are to the screen borders. /// - CenterWeighted + CenterWeighted, + + + /// + /// The Camera applies a weight to every pixel in the buffer and then uses them to measure + /// the exposure. The weighting is specified by the texture provided by the user. Note that if + /// no texture is provided, then this metering mode is equivalent to Average. + /// + MaskWeighted + } /// diff --git a/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/PostProcessSystem.cs b/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/PostProcessSystem.cs index a10c15aba26..0a25c38805c 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/PostProcessSystem.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/PostProcessSystem.cs @@ -873,6 +873,14 @@ void DoDynamicExposure(CommandBuffer cmd, HDCamera camera, RTHandle colorBuffer) cmd.SetComputeIntParams(cs, HDShaderIDs._Variants, m_ExposureVariants); cmd.SetComputeTextureParam(cs, kernel, HDShaderIDs._PreviousExposureTexture, prevExposure); cmd.SetComputeTextureParam(cs, kernel, HDShaderIDs._SourceTexture, sourceTex); + if (m_Exposure.meteringMode == MeteringMode.MaskWeighting && m_Exposure.weightTextureMask != null) + { + cmd.SetComputeTextureParam(cs, kernel, HDShaderIDs._ExposureWeightMask, m_Exposure.weightTextureMask.value); + } + else + { + cmd.SetComputeTextureParam(cs, kernel, HDShaderIDs._ExposureWeightMask, Texture2D.whiteTexture); + } cmd.SetComputeTextureParam(cs, kernel, HDShaderIDs._OutputTexture, m_TempTexture1024); cmd.DispatchCompute(cs, kernel, 1024 / 8, 1024 / 8, 1); diff --git a/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Shaders/Exposure.compute b/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Shaders/Exposure.compute index 8d413e4c841..24bb51c8249 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Shaders/Exposure.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Shaders/Exposure.compute @@ -14,6 +14,9 @@ TEXTURE2D(_ExposureCurveTexture); TEXTURE2D(_PreviousExposureTexture); TEXTURE2D(_InputTexture); + +TEXTURE2D(_ExposureWeightMask); + TEXTURE2D_X(_SourceTexture); RW_TEXTURE2D(float2, _OutputTexture); @@ -42,6 +45,9 @@ CBUFFER_END #define ParamAdaptationMode _Variants.z #define ParamEvaluateMode _Variants.w +#define PREPASS_TEX_SIZE 1024.0 +#define PREPASS_TEX_HALF_SIZE 512.0 + float WeightSample(uint2 pixel) { UNITY_BRANCH @@ -50,17 +56,23 @@ float WeightSample(uint2 pixel) case 1u: { // Spot metering - const float kRadius = 0.075 * 1024.0; - const float2 kCenter = (512.0).xx; + const float kRadius = 0.075 * PREPASS_TEX_SIZE; + const float2 kCenter = (PREPASS_TEX_HALF_SIZE).xx; float d = length(kCenter - pixel) - kRadius; return 1.0 - saturate(d); } case 2u: { // Center-weighted - const float2 kCenter = (512.0).xx; - return 1.0 - saturate(pow(length(kCenter - pixel) / 512.0, 1.0)); + const float2 kCenter = (PREPASS_TEX_HALF_SIZE).xx; + return 1.0 - saturate(pow(length(kCenter - pixel) / PREPASS_TEX_HALF_SIZE, 1.0)); } + case 3u: + { + // Mask weigthing + return SAMPLE_TEXTURE2D_LOD(_ExposureWeightMask, sampler_LinearClamp, pixel * rcp(PREPASS_TEX_SIZE), 0.0).x; + } + default: { // Global average @@ -126,7 +138,7 @@ void KPrePass(uint2 dispatchThreadId : SV_DispatchThreadID) // For XR, interleave single-pass views in a checkerboard pattern UNITY_XR_ASSIGN_VIEW_INDEX((dispatchThreadId.x + dispatchThreadId.y) % _XRViewCount) - PositionInputs posInputs = GetPositionInput(float2(dispatchThreadId), 1.0 / 1024.0, uint2(8u, 8u)); + PositionInputs posInputs = GetPositionInput(float2(dispatchThreadId), rcp(PREPASS_TEX_SIZE), uint2(8u, 8u)); float2 uv = ClampAndScaleUVForBilinear(posInputs.positionNDC); float luma; diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDStringConstants.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDStringConstants.cs index cc02abb2680..17cf3ef9900 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDStringConstants.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDStringConstants.cs @@ -596,6 +596,7 @@ static class HDShaderIDs public static readonly int _ExposureParams = Shader.PropertyToID("_ExposureParams"); public static readonly int _AdaptationParams = Shader.PropertyToID("_AdaptationParams"); public static readonly int _ExposureCurveTexture = Shader.PropertyToID("_ExposureCurveTexture"); + public static readonly int _ExposureWeightMask = Shader.PropertyToID("_ExposureWeightMask"); public static readonly int _Variants = Shader.PropertyToID("_Variants"); public static readonly int _InputTexture = Shader.PropertyToID("_InputTexture"); public static readonly int _OutputTexture = Shader.PropertyToID("_OutputTexture"); From f27ca7db44e168970a0b64afa4b10fa0c25f0e03 Mon Sep 17 00:00:00 2001 From: FrancescoC-Unity Date: Fri, 17 Apr 2020 09:54:38 +0200 Subject: [PATCH 2/6] miss one in the renaming --- .../Runtime/PostProcessing/PostProcessSystem.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/PostProcessSystem.cs b/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/PostProcessSystem.cs index 0a25c38805c..1157e796131 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/PostProcessSystem.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/PostProcessSystem.cs @@ -873,7 +873,7 @@ void DoDynamicExposure(CommandBuffer cmd, HDCamera camera, RTHandle colorBuffer) cmd.SetComputeIntParams(cs, HDShaderIDs._Variants, m_ExposureVariants); cmd.SetComputeTextureParam(cs, kernel, HDShaderIDs._PreviousExposureTexture, prevExposure); cmd.SetComputeTextureParam(cs, kernel, HDShaderIDs._SourceTexture, sourceTex); - if (m_Exposure.meteringMode == MeteringMode.MaskWeighting && m_Exposure.weightTextureMask != null) + if (m_Exposure.meteringMode == MeteringMode.MaskWeighted && m_Exposure.weightTextureMask != null) { cmd.SetComputeTextureParam(cs, kernel, HDShaderIDs._ExposureWeightMask, m_Exposure.weightTextureMask.value); } From 3280227d58f82c555a14c7ac40a3770b7b19382d Mon Sep 17 00:00:00 2001 From: FrancescoC-Unity Date: Fri, 17 Apr 2020 11:25:07 +0200 Subject: [PATCH 3/6] Doc update --- .../Documentation~/Override-Exposure.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/com.unity.render-pipelines.high-definition/Documentation~/Override-Exposure.md b/com.unity.render-pipelines.high-definition/Documentation~/Override-Exposure.md index 18b7f293bef..358e8429517 100644 --- a/com.unity.render-pipelines.high-definition/Documentation~/Override-Exposure.md +++ b/com.unity.render-pipelines.high-definition/Documentation~/Override-Exposure.md @@ -65,6 +65,10 @@ To configure **Automatic Mode**, select the **Metering Mode**. This tells the Ca ![](Images/Override-Exposure3.png) +- **Mask Weighted**: The Camera applies a weight to every pixel in the buffer and then uses them to measure the exposure. The weighting is specified by the texture provided in the **Weight Texture Mask** field. Note that if no texture is provided, then this metering mode is equivalent to Average. + + + 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. From b885ea5b508c5431b50f1750ba3a7c882031c22a Mon Sep 17 00:00:00 2001 From: FrancescoC-Unity Date: Fri, 17 Apr 2020 11:28:02 +0200 Subject: [PATCH 4/6] changelog --- com.unity.render-pipelines.high-definition/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/com.unity.render-pipelines.high-definition/CHANGELOG.md b/com.unity.render-pipelines.high-definition/CHANGELOG.md index ee5b4177476..bf9197b48a4 100644 --- a/com.unity.render-pipelines.high-definition/CHANGELOG.md +++ b/com.unity.render-pipelines.high-definition/CHANGELOG.md @@ -105,6 +105,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Added Light decomposition lighting debugging modes and support in AOV - Added exposure compensation to Fixed exposure mode - Added support for rasterized area light shadows in StackLit +- Added support for texture-weighted automatic exposure ### Fixed - Fix when rescale probe all direction below zero (1219246) From 70715762f175d7a724b52dcddf31df6588a69c67 Mon Sep 17 00:00:00 2001 From: FrancescoC-Unity Date: Fri, 17 Apr 2020 14:37:28 +0200 Subject: [PATCH 5/6] doc update --- .../Documentation~/Override-Exposure.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Documentation~/Override-Exposure.md b/com.unity.render-pipelines.high-definition/Documentation~/Override-Exposure.md index 358e8429517..475caf675b9 100644 --- a/com.unity.render-pipelines.high-definition/Documentation~/Override-Exposure.md +++ b/com.unity.render-pipelines.high-definition/Documentation~/Override-Exposure.md @@ -65,9 +65,8 @@ To configure **Automatic Mode**, select the **Metering Mode**. This tells the Ca ![](Images/Override-Exposure3.png) -- **Mask Weighted**: The Camera applies a weight to every pixel in the buffer and then uses them to measure the exposure. The weighting is specified by the texture provided in the **Weight Texture Mask** field. Note that if no texture is provided, then this metering mode is equivalent to Average. - - +- **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**. + 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. From 8f4441f7f1a58ebc8b1489dba13fba35f0ece8a2 Mon Sep 17 00:00:00 2001 From: FrancescoC-Unity Date: Fri, 17 Apr 2020 16:51:20 +0200 Subject: [PATCH 6/6] fix issue when disabling override --- .../Runtime/PostProcessing/PostProcessSystem.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/PostProcessSystem.cs b/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/PostProcessSystem.cs index 1157e796131..ff6bf2c1ac7 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/PostProcessSystem.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/PostProcessSystem.cs @@ -873,7 +873,7 @@ void DoDynamicExposure(CommandBuffer cmd, HDCamera camera, RTHandle colorBuffer) cmd.SetComputeIntParams(cs, HDShaderIDs._Variants, m_ExposureVariants); cmd.SetComputeTextureParam(cs, kernel, HDShaderIDs._PreviousExposureTexture, prevExposure); cmd.SetComputeTextureParam(cs, kernel, HDShaderIDs._SourceTexture, sourceTex); - if (m_Exposure.meteringMode == MeteringMode.MaskWeighted && m_Exposure.weightTextureMask != null) + if (m_Exposure.meteringMode == MeteringMode.MaskWeighted && m_Exposure.weightTextureMask.value != null) { cmd.SetComputeTextureParam(cs, kernel, HDShaderIDs._ExposureWeightMask, m_Exposure.weightTextureMask.value); }