summaryrefslogtreecommitdiff
path: root/UnityEngine.PostProcessing
diff options
context:
space:
mode:
authorchai <215380520@qq.com>2024-03-13 11:00:58 +0800
committerchai <215380520@qq.com>2024-03-13 11:00:58 +0800
commit6ce8b9e22fc13be34b442c7b6af48b42cd44275a (patch)
treeb38119d2acf0a982cb67e381f146924b9bfc3b3f /UnityEngine.PostProcessing
+init
Diffstat (limited to 'UnityEngine.PostProcessing')
-rw-r--r--UnityEngine.PostProcessing/AmbientOcclusionComponent.cs160
-rw-r--r--UnityEngine.PostProcessing/AmbientOcclusionModel.cs78
-rw-r--r--UnityEngine.PostProcessing/AntialiasingModel.cs222
-rw-r--r--UnityEngine.PostProcessing/BloomComponent.cs106
-rw-r--r--UnityEngine.PostProcessing/BloomModel.cs117
-rw-r--r--UnityEngine.PostProcessing/BuiltinDebugViewsComponent.cs223
-rw-r--r--UnityEngine.PostProcessing/BuiltinDebugViewsModel.cs131
-rw-r--r--UnityEngine.PostProcessing/ChromaticAberrationComponent.cs53
-rw-r--r--UnityEngine.PostProcessing/ChromaticAberrationModel.cs49
-rw-r--r--UnityEngine.PostProcessing/ColorGradingComponent.cs341
-rw-r--r--UnityEngine.PostProcessing/ColorGradingCurve.cs64
-rw-r--r--UnityEngine.PostProcessing/ColorGradingModel.cs319
-rw-r--r--UnityEngine.PostProcessing/DepthOfFieldComponent.cs141
-rw-r--r--UnityEngine.PostProcessing/DepthOfFieldModel.cs71
-rw-r--r--UnityEngine.PostProcessing/DitheringComponent.cs51
-rw-r--r--UnityEngine.PostProcessing/DitheringModel.cs35
-rw-r--r--UnityEngine.PostProcessing/EyeAdaptationComponent.cs168
-rw-r--r--UnityEngine.PostProcessing/EyeAdaptationModel.cs97
-rw-r--r--UnityEngine.PostProcessing/FogComponent.cs67
-rw-r--r--UnityEngine.PostProcessing/FogModel.cs44
-rw-r--r--UnityEngine.PostProcessing/FxaaComponent.cs24
-rw-r--r--UnityEngine.PostProcessing/GetSetAttribute.cs13
-rw-r--r--UnityEngine.PostProcessing/GrainComponent.cs52
-rw-r--r--UnityEngine.PostProcessing/GrainModel.cs59
-rw-r--r--UnityEngine.PostProcessing/GraphicsUtils.cs115
-rw-r--r--UnityEngine.PostProcessing/MaterialFactory.cs43
-rw-r--r--UnityEngine.PostProcessing/MinAttribute.cs11
-rw-r--r--UnityEngine.PostProcessing/MotionBlurComponent.cs421
-rw-r--r--UnityEngine.PostProcessing/MotionBlurModel.cs55
-rw-r--r--UnityEngine.PostProcessing/PostProcessingBehaviour.cs405
-rw-r--r--UnityEngine.PostProcessing/PostProcessingComponent.cs17
-rw-r--r--UnityEngine.PostProcessing/PostProcessingComponentBase.cs23
-rw-r--r--UnityEngine.PostProcessing/PostProcessingComponentCommandBuffer.cs12
-rw-r--r--UnityEngine.PostProcessing/PostProcessingComponentRenderTexture.cs8
-rw-r--r--UnityEngine.PostProcessing/PostProcessingContext.cs39
-rw-r--r--UnityEngine.PostProcessing/PostProcessingModel.cs33
-rw-r--r--UnityEngine.PostProcessing/PostProcessingProfile.cs34
-rw-r--r--UnityEngine.PostProcessing/RenderTextureFactory.cs57
-rw-r--r--UnityEngine.PostProcessing/ScreenSpaceReflectionComponent.cs217
-rw-r--r--UnityEngine.PostProcessing/ScreenSpaceReflectionModel.cs141
-rw-r--r--UnityEngine.PostProcessing/TaaComponent.cs176
-rw-r--r--UnityEngine.PostProcessing/TrackballAttribute.cs11
-rw-r--r--UnityEngine.PostProcessing/TrackballGroupAttribute.cs5
-rw-r--r--UnityEngine.PostProcessing/UserLutComponent.cs35
-rw-r--r--UnityEngine.PostProcessing/UserLutModel.cs49
-rw-r--r--UnityEngine.PostProcessing/VignetteComponent.cs38
-rw-r--r--UnityEngine.PostProcessing/VignetteModel.cs87
47 files changed, 4717 insertions, 0 deletions
diff --git a/UnityEngine.PostProcessing/AmbientOcclusionComponent.cs b/UnityEngine.PostProcessing/AmbientOcclusionComponent.cs
new file mode 100644
index 0000000..d1dbda2
--- /dev/null
+++ b/UnityEngine.PostProcessing/AmbientOcclusionComponent.cs
@@ -0,0 +1,160 @@
+using UnityEngine.Rendering;
+
+namespace UnityEngine.PostProcessing;
+
+public sealed class AmbientOcclusionComponent : PostProcessingComponentCommandBuffer<AmbientOcclusionModel>
+{
+ private static class Uniforms
+ {
+ internal static readonly int _Intensity = Shader.PropertyToID("_Intensity");
+
+ internal static readonly int _Radius = Shader.PropertyToID("_Radius");
+
+ internal static readonly int _FogParams = Shader.PropertyToID("_FogParams");
+
+ internal static readonly int _Downsample = Shader.PropertyToID("_Downsample");
+
+ internal static readonly int _SampleCount = Shader.PropertyToID("_SampleCount");
+
+ internal static readonly int _OcclusionTexture1 = Shader.PropertyToID("_OcclusionTexture1");
+
+ internal static readonly int _OcclusionTexture2 = Shader.PropertyToID("_OcclusionTexture2");
+
+ internal static readonly int _OcclusionTexture = Shader.PropertyToID("_OcclusionTexture");
+
+ internal static readonly int _MainTex = Shader.PropertyToID("_MainTex");
+
+ internal static readonly int _TempRT = Shader.PropertyToID("_TempRT");
+ }
+
+ private enum OcclusionSource
+ {
+ DepthTexture,
+ DepthNormalsTexture,
+ GBuffer
+ }
+
+ private const string k_BlitShaderString = "Hidden/Post FX/Blit";
+
+ private const string k_ShaderString = "Hidden/Post FX/Ambient Occlusion";
+
+ private readonly RenderTargetIdentifier[] m_MRT = new RenderTargetIdentifier[2]
+ {
+ BuiltinRenderTextureType.GBuffer0,
+ BuiltinRenderTextureType.CameraTarget
+ };
+
+ private OcclusionSource occlusionSource
+ {
+ get
+ {
+ if (context.isGBufferAvailable && !base.model.settings.forceForwardCompatibility)
+ {
+ return OcclusionSource.GBuffer;
+ }
+ if (base.model.settings.highPrecision && (!context.isGBufferAvailable || base.model.settings.forceForwardCompatibility))
+ {
+ return OcclusionSource.DepthTexture;
+ }
+ return OcclusionSource.DepthNormalsTexture;
+ }
+ }
+
+ private bool ambientOnlySupported => context.isHdr && base.model.settings.ambientOnly && context.isGBufferAvailable && !base.model.settings.forceForwardCompatibility;
+
+ public override bool active => base.model.enabled && base.model.settings.intensity > 0f && !context.interrupted;
+
+ public override DepthTextureMode GetCameraFlags()
+ {
+ DepthTextureMode depthTextureMode = DepthTextureMode.None;
+ if (occlusionSource == OcclusionSource.DepthTexture)
+ {
+ depthTextureMode |= DepthTextureMode.Depth;
+ }
+ if (occlusionSource != OcclusionSource.GBuffer)
+ {
+ depthTextureMode |= DepthTextureMode.DepthNormals;
+ }
+ return depthTextureMode;
+ }
+
+ public override string GetName()
+ {
+ return "Ambient Occlusion";
+ }
+
+ public override CameraEvent GetCameraEvent()
+ {
+ return (!ambientOnlySupported || context.profile.debugViews.IsModeActive(BuiltinDebugViewsModel.Mode.AmbientOcclusion)) ? CameraEvent.BeforeImageEffectsOpaque : CameraEvent.BeforeReflections;
+ }
+
+ public override void PopulateCommandBuffer(CommandBuffer cb)
+ {
+ AmbientOcclusionModel.Settings settings = base.model.settings;
+ Material mat = context.materialFactory.Get("Hidden/Post FX/Blit");
+ Material material = context.materialFactory.Get("Hidden/Post FX/Ambient Occlusion");
+ material.shaderKeywords = null;
+ material.SetFloat(Uniforms._Intensity, settings.intensity);
+ material.SetFloat(Uniforms._Radius, settings.radius);
+ material.SetFloat(Uniforms._Downsample, (!settings.downsampling) ? 1f : 0.5f);
+ material.SetInt(Uniforms._SampleCount, (int)settings.sampleCount);
+ if (!context.isGBufferAvailable && RenderSettings.fog)
+ {
+ material.SetVector(Uniforms._FogParams, new Vector3(RenderSettings.fogDensity, RenderSettings.fogStartDistance, RenderSettings.fogEndDistance));
+ switch (RenderSettings.fogMode)
+ {
+ case FogMode.Linear:
+ material.EnableKeyword("FOG_LINEAR");
+ break;
+ case FogMode.Exponential:
+ material.EnableKeyword("FOG_EXP");
+ break;
+ case FogMode.ExponentialSquared:
+ material.EnableKeyword("FOG_EXP2");
+ break;
+ }
+ }
+ else
+ {
+ material.EnableKeyword("FOG_OFF");
+ }
+ int width = context.width;
+ int height = context.height;
+ int num = ((!settings.downsampling) ? 1 : 2);
+ int occlusionTexture = Uniforms._OcclusionTexture1;
+ cb.GetTemporaryRT(occlusionTexture, width / num, height / num, 0, FilterMode.Bilinear, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);
+ cb.Blit(null, occlusionTexture, material, (int)occlusionSource);
+ int occlusionTexture2 = Uniforms._OcclusionTexture2;
+ cb.GetTemporaryRT(occlusionTexture2, width, height, 0, FilterMode.Bilinear, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);
+ cb.SetGlobalTexture(Uniforms._MainTex, occlusionTexture);
+ cb.Blit(occlusionTexture, occlusionTexture2, material, (occlusionSource != OcclusionSource.GBuffer) ? 3 : 4);
+ cb.ReleaseTemporaryRT(occlusionTexture);
+ occlusionTexture = Uniforms._OcclusionTexture;
+ cb.GetTemporaryRT(occlusionTexture, width, height, 0, FilterMode.Bilinear, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);
+ cb.SetGlobalTexture(Uniforms._MainTex, occlusionTexture2);
+ cb.Blit(occlusionTexture2, occlusionTexture, material, 5);
+ cb.ReleaseTemporaryRT(occlusionTexture2);
+ if (context.profile.debugViews.IsModeActive(BuiltinDebugViewsModel.Mode.AmbientOcclusion))
+ {
+ cb.SetGlobalTexture(Uniforms._MainTex, occlusionTexture);
+ cb.Blit(occlusionTexture, BuiltinRenderTextureType.CameraTarget, material, 8);
+ context.Interrupt();
+ }
+ else if (ambientOnlySupported)
+ {
+ cb.SetRenderTarget(m_MRT, BuiltinRenderTextureType.CameraTarget);
+ cb.DrawMesh(GraphicsUtils.quad, Matrix4x4.identity, material, 0, 7);
+ }
+ else
+ {
+ RenderTextureFormat format = ((!context.isHdr) ? RenderTextureFormat.Default : RenderTextureFormat.DefaultHDR);
+ int tempRT = Uniforms._TempRT;
+ cb.GetTemporaryRT(tempRT, context.width, context.height, 0, FilterMode.Bilinear, format);
+ cb.Blit(BuiltinRenderTextureType.CameraTarget, tempRT, mat, 0);
+ cb.SetGlobalTexture(Uniforms._MainTex, tempRT);
+ cb.Blit(tempRT, BuiltinRenderTextureType.CameraTarget, material, 6);
+ cb.ReleaseTemporaryRT(tempRT);
+ }
+ cb.ReleaseTemporaryRT(occlusionTexture);
+ }
+}
diff --git a/UnityEngine.PostProcessing/AmbientOcclusionModel.cs b/UnityEngine.PostProcessing/AmbientOcclusionModel.cs
new file mode 100644
index 0000000..c8fa258
--- /dev/null
+++ b/UnityEngine.PostProcessing/AmbientOcclusionModel.cs
@@ -0,0 +1,78 @@
+using System;
+
+namespace UnityEngine.PostProcessing;
+
+[Serializable]
+public class AmbientOcclusionModel : PostProcessingModel
+{
+ public enum SampleCount
+ {
+ Lowest = 3,
+ Low = 6,
+ Medium = 10,
+ High = 16
+ }
+
+ [Serializable]
+ public struct Settings
+ {
+ [Range(0f, 4f)]
+ [Tooltip("Degree of darkness produced by the effect.")]
+ public float intensity;
+
+ [Min(0.0001f)]
+ [Tooltip("Radius of sample points, which affects extent of darkened areas.")]
+ public float radius;
+
+ [Tooltip("Number of sample points, which affects quality and performance.")]
+ public SampleCount sampleCount;
+
+ [Tooltip("Halves the resolution of the effect to increase performance at the cost of visual quality.")]
+ public bool downsampling;
+
+ [Tooltip("Forces compatibility with Forward rendered objects when working with the Deferred rendering path.")]
+ public bool forceForwardCompatibility;
+
+ [Tooltip("Enables the ambient-only mode in that the effect only affects ambient lighting. This mode is only available with the Deferred rendering path and HDR rendering.")]
+ public bool ambientOnly;
+
+ [Tooltip("Toggles the use of a higher precision depth texture with the forward rendering path (may impact performances). Has no effect with the deferred rendering path.")]
+ public bool highPrecision;
+
+ public static Settings defaultSettings
+ {
+ get
+ {
+ Settings result = default(Settings);
+ result.intensity = 1f;
+ result.radius = 0.3f;
+ result.sampleCount = SampleCount.Medium;
+ result.downsampling = true;
+ result.forceForwardCompatibility = false;
+ result.ambientOnly = false;
+ result.highPrecision = false;
+ return result;
+ }
+ }
+ }
+
+ [SerializeField]
+ private Settings m_Settings = Settings.defaultSettings;
+
+ public Settings settings
+ {
+ get
+ {
+ return m_Settings;
+ }
+ set
+ {
+ m_Settings = value;
+ }
+ }
+
+ public override void Reset()
+ {
+ m_Settings = Settings.defaultSettings;
+ }
+}
diff --git a/UnityEngine.PostProcessing/AntialiasingModel.cs b/UnityEngine.PostProcessing/AntialiasingModel.cs
new file mode 100644
index 0000000..d5bda1d
--- /dev/null
+++ b/UnityEngine.PostProcessing/AntialiasingModel.cs
@@ -0,0 +1,222 @@
+using System;
+
+namespace UnityEngine.PostProcessing;
+
+[Serializable]
+public class AntialiasingModel : PostProcessingModel
+{
+ public enum Method
+ {
+ Fxaa,
+ Taa
+ }
+
+ public enum FxaaPreset
+ {
+ ExtremePerformance,
+ Performance,
+ Default,
+ Quality,
+ ExtremeQuality
+ }
+
+ [Serializable]
+ public struct FxaaQualitySettings
+ {
+ [Tooltip("The amount of desired sub-pixel aliasing removal. Effects the sharpeness of the output.")]
+ [Range(0f, 1f)]
+ public float subpixelAliasingRemovalAmount;
+
+ [Tooltip("The minimum amount of local contrast required to qualify a region as containing an edge.")]
+ [Range(0.063f, 0.333f)]
+ public float edgeDetectionThreshold;
+
+ [Tooltip("Local contrast adaptation value to disallow the algorithm from executing on the darker regions.")]
+ [Range(0f, 0.0833f)]
+ public float minimumRequiredLuminance;
+
+ public static FxaaQualitySettings[] presets = new FxaaQualitySettings[5]
+ {
+ new FxaaQualitySettings
+ {
+ subpixelAliasingRemovalAmount = 0f,
+ edgeDetectionThreshold = 0.333f,
+ minimumRequiredLuminance = 0.0833f
+ },
+ new FxaaQualitySettings
+ {
+ subpixelAliasingRemovalAmount = 0.25f,
+ edgeDetectionThreshold = 0.25f,
+ minimumRequiredLuminance = 0.0833f
+ },
+ new FxaaQualitySettings
+ {
+ subpixelAliasingRemovalAmount = 0.75f,
+ edgeDetectionThreshold = 0.166f,
+ minimumRequiredLuminance = 0.0833f
+ },
+ new FxaaQualitySettings
+ {
+ subpixelAliasingRemovalAmount = 1f,
+ edgeDetectionThreshold = 0.125f,
+ minimumRequiredLuminance = 0.0625f
+ },
+ new FxaaQualitySettings
+ {
+ subpixelAliasingRemovalAmount = 1f,
+ edgeDetectionThreshold = 0.063f,
+ minimumRequiredLuminance = 0.0312f
+ }
+ };
+ }
+
+ [Serializable]
+ public struct FxaaConsoleSettings
+ {
+ [Tooltip("The amount of spread applied to the sampling coordinates while sampling for subpixel information.")]
+ [Range(0.33f, 0.5f)]
+ public float subpixelSpreadAmount;
+
+ [Tooltip("This value dictates how sharp the edges in the image are kept; a higher value implies sharper edges.")]
+ [Range(2f, 8f)]
+ public float edgeSharpnessAmount;
+
+ [Tooltip("The minimum amount of local contrast required to qualify a region as containing an edge.")]
+ [Range(0.125f, 0.25f)]
+ public float edgeDetectionThreshold;
+
+ [Tooltip("Local contrast adaptation value to disallow the algorithm from executing on the darker regions.")]
+ [Range(0.04f, 0.06f)]
+ public float minimumRequiredLuminance;
+
+ public static FxaaConsoleSettings[] presets = new FxaaConsoleSettings[5]
+ {
+ new FxaaConsoleSettings
+ {
+ subpixelSpreadAmount = 0.33f,
+ edgeSharpnessAmount = 8f,
+ edgeDetectionThreshold = 0.25f,
+ minimumRequiredLuminance = 0.06f
+ },
+ new FxaaConsoleSettings
+ {
+ subpixelSpreadAmount = 0.33f,
+ edgeSharpnessAmount = 8f,
+ edgeDetectionThreshold = 0.125f,
+ minimumRequiredLuminance = 0.06f
+ },
+ new FxaaConsoleSettings
+ {
+ subpixelSpreadAmount = 0.5f,
+ edgeSharpnessAmount = 8f,
+ edgeDetectionThreshold = 0.125f,
+ minimumRequiredLuminance = 0.05f
+ },
+ new FxaaConsoleSettings
+ {
+ subpixelSpreadAmount = 0.5f,
+ edgeSharpnessAmount = 4f,
+ edgeDetectionThreshold = 0.125f,
+ minimumRequiredLuminance = 0.04f
+ },
+ new FxaaConsoleSettings
+ {
+ subpixelSpreadAmount = 0.5f,
+ edgeSharpnessAmount = 2f,
+ edgeDetectionThreshold = 0.125f,
+ minimumRequiredLuminance = 0.04f
+ }
+ };
+ }
+
+ [Serializable]
+ public struct FxaaSettings
+ {
+ public FxaaPreset preset;
+
+ public static FxaaSettings defaultSettings
+ {
+ get
+ {
+ FxaaSettings result = default(FxaaSettings);
+ result.preset = FxaaPreset.Default;
+ return result;
+ }
+ }
+ }
+
+ [Serializable]
+ public struct TaaSettings
+ {
+ [Tooltip("The diameter (in texels) inside which jitter samples are spread. Smaller values result in crisper but more aliased output, while larger values result in more stable but blurrier output.")]
+ [Range(0.1f, 1f)]
+ public float jitterSpread;
+
+ [Tooltip("Controls the amount of sharpening applied to the color buffer.")]
+ [Range(0f, 3f)]
+ public float sharpen;
+
+ [Tooltip("The blend coefficient for a stationary fragment. Controls the percentage of history sample blended into the final color.")]
+ [Range(0f, 0.99f)]
+ public float stationaryBlending;
+
+ [Tooltip("The blend coefficient for a fragment with significant motion. Controls the percentage of history sample blended into the final color.")]
+ [Range(0f, 0.99f)]
+ public float motionBlending;
+
+ public static TaaSettings defaultSettings
+ {
+ get
+ {
+ TaaSettings result = default(TaaSettings);
+ result.jitterSpread = 0.75f;
+ result.sharpen = 0.3f;
+ result.stationaryBlending = 0.95f;
+ result.motionBlending = 0.85f;
+ return result;
+ }
+ }
+ }
+
+ [Serializable]
+ public struct Settings
+ {
+ public Method method;
+
+ public FxaaSettings fxaaSettings;
+
+ public TaaSettings taaSettings;
+
+ public static Settings defaultSettings
+ {
+ get
+ {
+ Settings result = default(Settings);
+ result.method = Method.Fxaa;
+ result.fxaaSettings = FxaaSettings.defaultSettings;
+ result.taaSettings = TaaSettings.defaultSettings;
+ return result;
+ }
+ }
+ }
+
+ [SerializeField]
+ private Settings m_Settings = Settings.defaultSettings;
+
+ public Settings settings
+ {
+ get
+ {
+ return m_Settings;
+ }
+ set
+ {
+ m_Settings = value;
+ }
+ }
+
+ public override void Reset()
+ {
+ m_Settings = Settings.defaultSettings;
+ }
+}
diff --git a/UnityEngine.PostProcessing/BloomComponent.cs b/UnityEngine.PostProcessing/BloomComponent.cs
new file mode 100644
index 0000000..aeec498
--- /dev/null
+++ b/UnityEngine.PostProcessing/BloomComponent.cs
@@ -0,0 +1,106 @@
+namespace UnityEngine.PostProcessing;
+
+public sealed class BloomComponent : PostProcessingComponentRenderTexture<BloomModel>
+{
+ private static class Uniforms
+ {
+ internal static readonly int _AutoExposure = Shader.PropertyToID("_AutoExposure");
+
+ internal static readonly int _Threshold = Shader.PropertyToID("_Threshold");
+
+ internal static readonly int _Curve = Shader.PropertyToID("_Curve");
+
+ internal static readonly int _PrefilterOffs = Shader.PropertyToID("_PrefilterOffs");
+
+ internal static readonly int _SampleScale = Shader.PropertyToID("_SampleScale");
+
+ internal static readonly int _BaseTex = Shader.PropertyToID("_BaseTex");
+
+ internal static readonly int _BloomTex = Shader.PropertyToID("_BloomTex");
+
+ internal static readonly int _Bloom_Settings = Shader.PropertyToID("_Bloom_Settings");
+
+ internal static readonly int _Bloom_DirtTex = Shader.PropertyToID("_Bloom_DirtTex");
+
+ internal static readonly int _Bloom_DirtIntensity = Shader.PropertyToID("_Bloom_DirtIntensity");
+ }
+
+ private const int k_MaxPyramidBlurLevel = 16;
+
+ private readonly RenderTexture[] m_BlurBuffer1 = new RenderTexture[16];
+
+ private readonly RenderTexture[] m_BlurBuffer2 = new RenderTexture[16];
+
+ public override bool active => base.model.enabled && base.model.settings.bloom.intensity > 0f && !context.interrupted;
+
+ public void Prepare(RenderTexture source, Material uberMaterial, Texture autoExposure)
+ {
+ BloomModel.BloomSettings bloom = base.model.settings.bloom;
+ BloomModel.LensDirtSettings lensDirt = base.model.settings.lensDirt;
+ Material material = context.materialFactory.Get("Hidden/Post FX/Bloom");
+ material.shaderKeywords = null;
+ material.SetTexture(Uniforms._AutoExposure, autoExposure);
+ int width = context.width / 2;
+ int num = context.height / 2;
+ RenderTextureFormat format = ((!Application.isMobilePlatform) ? RenderTextureFormat.DefaultHDR : RenderTextureFormat.Default);
+ float num2 = Mathf.Log(num, 2f) + bloom.radius - 8f;
+ int num3 = (int)num2;
+ int num4 = Mathf.Clamp(num3, 1, 16);
+ float thresholdLinear = bloom.thresholdLinear;
+ material.SetFloat(Uniforms._Threshold, thresholdLinear);
+ float num5 = thresholdLinear * bloom.softKnee + 1E-05f;
+ material.SetVector(value: new Vector3(thresholdLinear - num5, num5 * 2f, 0.25f / num5), nameID: Uniforms._Curve);
+ material.SetFloat(Uniforms._PrefilterOffs, (!bloom.antiFlicker) ? 0f : (-0.5f));
+ float num6 = 0.5f + num2 - (float)num3;
+ material.SetFloat(Uniforms._SampleScale, num6);
+ if (bloom.antiFlicker)
+ {
+ material.EnableKeyword("ANTI_FLICKER");
+ }
+ RenderTexture renderTexture = context.renderTextureFactory.Get(width, num, 0, format);
+ Graphics.Blit(source, renderTexture, material, 0);
+ RenderTexture renderTexture2 = renderTexture;
+ for (int i = 0; i < num4; i++)
+ {
+ m_BlurBuffer1[i] = context.renderTextureFactory.Get(renderTexture2.width / 2, renderTexture2.height / 2, 0, format);
+ int pass = ((i == 0) ? 1 : 2);
+ Graphics.Blit(renderTexture2, m_BlurBuffer1[i], material, pass);
+ renderTexture2 = m_BlurBuffer1[i];
+ }
+ for (int num7 = num4 - 2; num7 >= 0; num7--)
+ {
+ RenderTexture renderTexture3 = m_BlurBuffer1[num7];
+ material.SetTexture(Uniforms._BaseTex, renderTexture3);
+ m_BlurBuffer2[num7] = context.renderTextureFactory.Get(renderTexture3.width, renderTexture3.height, 0, format);
+ Graphics.Blit(renderTexture2, m_BlurBuffer2[num7], material, 3);
+ renderTexture2 = m_BlurBuffer2[num7];
+ }
+ RenderTexture renderTexture4 = renderTexture2;
+ for (int j = 0; j < 16; j++)
+ {
+ if (m_BlurBuffer1[j] != null)
+ {
+ context.renderTextureFactory.Release(m_BlurBuffer1[j]);
+ }
+ if (m_BlurBuffer2[j] != null && m_BlurBuffer2[j] != renderTexture4)
+ {
+ context.renderTextureFactory.Release(m_BlurBuffer2[j]);
+ }
+ m_BlurBuffer1[j] = null;
+ m_BlurBuffer2[j] = null;
+ }
+ context.renderTextureFactory.Release(renderTexture);
+ uberMaterial.SetTexture(Uniforms._BloomTex, renderTexture4);
+ uberMaterial.SetVector(Uniforms._Bloom_Settings, new Vector2(num6, bloom.intensity));
+ if (lensDirt.intensity > 0f && lensDirt.texture != null)
+ {
+ uberMaterial.SetTexture(Uniforms._Bloom_DirtTex, lensDirt.texture);
+ uberMaterial.SetFloat(Uniforms._Bloom_DirtIntensity, lensDirt.intensity);
+ uberMaterial.EnableKeyword("BLOOM_LENS_DIRT");
+ }
+ else
+ {
+ uberMaterial.EnableKeyword("BLOOM");
+ }
+ }
+}
diff --git a/UnityEngine.PostProcessing/BloomModel.cs b/UnityEngine.PostProcessing/BloomModel.cs
new file mode 100644
index 0000000..0569d62
--- /dev/null
+++ b/UnityEngine.PostProcessing/BloomModel.cs
@@ -0,0 +1,117 @@
+using System;
+
+namespace UnityEngine.PostProcessing;
+
+[Serializable]
+public class BloomModel : PostProcessingModel
+{
+ [Serializable]
+ public struct BloomSettings
+ {
+ [Min(0f)]
+ [Tooltip("Strength of the bloom filter.")]
+ public float intensity;
+
+ [Min(0f)]
+ [Tooltip("Filters out pixels under this level of brightness.")]
+ public float threshold;
+
+ [Range(0f, 1f)]
+ [Tooltip("Makes transition between under/over-threshold gradual (0 = hard threshold, 1 = soft threshold).")]
+ public float softKnee;
+
+ [Range(1f, 7f)]
+ [Tooltip("Changes extent of veiling effects in a screen resolution-independent fashion.")]
+ public float radius;
+
+ [Tooltip("Reduces flashing noise with an additional filter.")]
+ public bool antiFlicker;
+
+ public float thresholdLinear
+ {
+ get
+ {
+ return Mathf.GammaToLinearSpace(threshold);
+ }
+ set
+ {
+ threshold = Mathf.LinearToGammaSpace(value);
+ }
+ }
+
+ public static BloomSettings defaultSettings
+ {
+ get
+ {
+ BloomSettings result = default(BloomSettings);
+ result.intensity = 0.5f;
+ result.threshold = 1.1f;
+ result.softKnee = 0.5f;
+ result.radius = 4f;
+ result.antiFlicker = false;
+ return result;
+ }
+ }
+ }
+
+ [Serializable]
+ public struct LensDirtSettings
+ {
+ [Tooltip("Dirtiness texture to add smudges or dust to the lens.")]
+ public Texture texture;
+
+ [Min(0f)]
+ [Tooltip("Amount of lens dirtiness.")]
+ public float intensity;
+
+ public static LensDirtSettings defaultSettings
+ {
+ get
+ {
+ LensDirtSettings result = default(LensDirtSettings);
+ result.texture = null;
+ result.intensity = 3f;
+ return result;
+ }
+ }
+ }
+
+ [Serializable]
+ public struct Settings
+ {
+ public BloomSettings bloom;
+
+ public LensDirtSettings lensDirt;
+
+ public static Settings defaultSettings
+ {
+ get
+ {
+ Settings result = default(Settings);
+ result.bloom = BloomSettings.defaultSettings;
+ result.lensDirt = LensDirtSettings.defaultSettings;
+ return result;
+ }
+ }
+ }
+
+ [SerializeField]
+ private Settings m_Settings = Settings.defaultSettings;
+
+ public Settings settings
+ {
+ get
+ {
+ return m_Settings;
+ }
+ set
+ {
+ m_Settings = value;
+ }
+ }
+
+ public override void Reset()
+ {
+ m_Settings = Settings.defaultSettings;
+ }
+}
diff --git a/UnityEngine.PostProcessing/BuiltinDebugViewsComponent.cs b/UnityEngine.PostProcessing/BuiltinDebugViewsComponent.cs
new file mode 100644
index 0000000..a1a6d44
--- /dev/null
+++ b/UnityEngine.PostProcessing/BuiltinDebugViewsComponent.cs
@@ -0,0 +1,223 @@
+using System.Collections.Generic;
+using UnityEngine.Rendering;
+
+namespace UnityEngine.PostProcessing;
+
+public sealed class BuiltinDebugViewsComponent : PostProcessingComponentCommandBuffer<BuiltinDebugViewsModel>
+{
+ private static class Uniforms
+ {
+ internal static readonly int _DepthScale = Shader.PropertyToID("_DepthScale");
+
+ internal static readonly int _TempRT = Shader.PropertyToID("_TempRT");
+
+ internal static readonly int _Opacity = Shader.PropertyToID("_Opacity");
+
+ internal static readonly int _MainTex = Shader.PropertyToID("_MainTex");
+
+ internal static readonly int _TempRT2 = Shader.PropertyToID("_TempRT2");
+
+ internal static readonly int _Amplitude = Shader.PropertyToID("_Amplitude");
+
+ internal static readonly int _Scale = Shader.PropertyToID("_Scale");
+ }
+
+ private enum Pass
+ {
+ Depth,
+ Normals,
+ MovecOpacity,
+ MovecImaging,
+ MovecArrows
+ }
+
+ private class ArrowArray
+ {
+ public Mesh mesh { get; private set; }
+
+ public int columnCount { get; private set; }
+
+ public int rowCount { get; private set; }
+
+ public void BuildMesh(int columns, int rows)
+ {
+ Vector3[] array = new Vector3[6]
+ {
+ new Vector3(0f, 0f, 0f),
+ new Vector3(0f, 1f, 0f),
+ new Vector3(0f, 1f, 0f),
+ new Vector3(-1f, 1f, 0f),
+ new Vector3(0f, 1f, 0f),
+ new Vector3(1f, 1f, 0f)
+ };
+ int num = 6 * columns * rows;
+ List<Vector3> list = new List<Vector3>(num);
+ List<Vector2> list2 = new List<Vector2>(num);
+ for (int i = 0; i < rows; i++)
+ {
+ for (int j = 0; j < columns; j++)
+ {
+ Vector2 item = new Vector2((0.5f + (float)j) / (float)columns, (0.5f + (float)i) / (float)rows);
+ for (int k = 0; k < 6; k++)
+ {
+ list.Add(array[k]);
+ list2.Add(item);
+ }
+ }
+ }
+ int[] array2 = new int[num];
+ for (int l = 0; l < num; l++)
+ {
+ array2[l] = l;
+ }
+ mesh = new Mesh
+ {
+ hideFlags = HideFlags.DontSave
+ };
+ mesh.SetVertices(list);
+ mesh.SetUVs(0, list2);
+ mesh.SetIndices(array2, MeshTopology.Lines, 0);
+ mesh.UploadMeshData(markNoLogerReadable: true);
+ columnCount = columns;
+ rowCount = rows;
+ }
+
+ public void Release()
+ {
+ GraphicsUtils.Destroy(mesh);
+ mesh = null;
+ }
+ }
+
+ private const string k_ShaderString = "Hidden/Post FX/Builtin Debug Views";
+
+ private ArrowArray m_Arrows;
+
+ public override bool active => base.model.IsModeActive(BuiltinDebugViewsModel.Mode.Depth) || base.model.IsModeActive(BuiltinDebugViewsModel.Mode.Normals) || base.model.IsModeActive(BuiltinDebugViewsModel.Mode.MotionVectors);
+
+ public override DepthTextureMode GetCameraFlags()
+ {
+ BuiltinDebugViewsModel.Mode mode = base.model.settings.mode;
+ DepthTextureMode depthTextureMode = DepthTextureMode.None;
+ switch (mode)
+ {
+ case BuiltinDebugViewsModel.Mode.Normals:
+ depthTextureMode |= DepthTextureMode.DepthNormals;
+ break;
+ case BuiltinDebugViewsModel.Mode.MotionVectors:
+ depthTextureMode |= DepthTextureMode.Depth | DepthTextureMode.MotionVectors;
+ break;
+ case BuiltinDebugViewsModel.Mode.Depth:
+ depthTextureMode |= DepthTextureMode.Depth;
+ break;
+ }
+ return depthTextureMode;
+ }
+
+ public override CameraEvent GetCameraEvent()
+ {
+ return (base.model.settings.mode != BuiltinDebugViewsModel.Mode.MotionVectors) ? CameraEvent.BeforeImageEffectsOpaque : CameraEvent.BeforeImageEffects;
+ }
+
+ public override string GetName()
+ {
+ return "Builtin Debug Views";
+ }
+
+ public override void PopulateCommandBuffer(CommandBuffer cb)
+ {
+ BuiltinDebugViewsModel.Settings settings = base.model.settings;
+ Material material = context.materialFactory.Get("Hidden/Post FX/Builtin Debug Views");
+ material.shaderKeywords = null;
+ if (context.isGBufferAvailable)
+ {
+ material.EnableKeyword("SOURCE_GBUFFER");
+ }
+ switch (settings.mode)
+ {
+ case BuiltinDebugViewsModel.Mode.Depth:
+ DepthPass(cb);
+ break;
+ case BuiltinDebugViewsModel.Mode.Normals:
+ DepthNormalsPass(cb);
+ break;
+ case BuiltinDebugViewsModel.Mode.MotionVectors:
+ MotionVectorsPass(cb);
+ break;
+ }
+ context.Interrupt();
+ }
+
+ private void DepthPass(CommandBuffer cb)
+ {
+ Material mat = context.materialFactory.Get("Hidden/Post FX/Builtin Debug Views");
+ BuiltinDebugViewsModel.DepthSettings depth = base.model.settings.depth;
+ cb.SetGlobalFloat(Uniforms._DepthScale, 1f / depth.scale);
+ cb.Blit(null, BuiltinRenderTextureType.CameraTarget, mat, 0);
+ }
+
+ private void DepthNormalsPass(CommandBuffer cb)
+ {
+ Material mat = context.materialFactory.Get("Hidden/Post FX/Builtin Debug Views");
+ cb.Blit(null, BuiltinRenderTextureType.CameraTarget, mat, 1);
+ }
+
+ private void MotionVectorsPass(CommandBuffer cb)
+ {
+ Material material = context.materialFactory.Get("Hidden/Post FX/Builtin Debug Views");
+ BuiltinDebugViewsModel.MotionVectorsSettings motionVectors = base.model.settings.motionVectors;
+ int num = Uniforms._TempRT;
+ cb.GetTemporaryRT(num, context.width, context.height, 0, FilterMode.Bilinear);
+ cb.SetGlobalFloat(Uniforms._Opacity, motionVectors.sourceOpacity);
+ cb.SetGlobalTexture(Uniforms._MainTex, BuiltinRenderTextureType.CameraTarget);
+ cb.Blit(BuiltinRenderTextureType.CameraTarget, num, material, 2);
+ if (motionVectors.motionImageOpacity > 0f && motionVectors.motionImageAmplitude > 0f)
+ {
+ int tempRT = Uniforms._TempRT2;
+ cb.GetTemporaryRT(tempRT, context.width, context.height, 0, FilterMode.Bilinear);
+ cb.SetGlobalFloat(Uniforms._Opacity, motionVectors.motionImageOpacity);
+ cb.SetGlobalFloat(Uniforms._Amplitude, motionVectors.motionImageAmplitude);
+ cb.SetGlobalTexture(Uniforms._MainTex, num);
+ cb.Blit(num, tempRT, material, 3);
+ cb.ReleaseTemporaryRT(num);
+ num = tempRT;
+ }
+ if (motionVectors.motionVectorsOpacity > 0f && motionVectors.motionVectorsAmplitude > 0f)
+ {
+ PrepareArrows();
+ float num2 = 1f / (float)motionVectors.motionVectorsResolution;
+ float x = num2 * (float)context.height / (float)context.width;
+ cb.SetGlobalVector(Uniforms._Scale, new Vector2(x, num2));
+ cb.SetGlobalFloat(Uniforms._Opacity, motionVectors.motionVectorsOpacity);
+ cb.SetGlobalFloat(Uniforms._Amplitude, motionVectors.motionVectorsAmplitude);
+ cb.DrawMesh(m_Arrows.mesh, Matrix4x4.identity, material, 0, 4);
+ }
+ cb.SetGlobalTexture(Uniforms._MainTex, num);
+ cb.Blit(num, BuiltinRenderTextureType.CameraTarget);
+ cb.ReleaseTemporaryRT(num);
+ }
+
+ private void PrepareArrows()
+ {
+ int motionVectorsResolution = base.model.settings.motionVectors.motionVectorsResolution;
+ int num = motionVectorsResolution * Screen.width / Screen.height;
+ if (m_Arrows == null)
+ {
+ m_Arrows = new ArrowArray();
+ }
+ if (m_Arrows.columnCount != num || m_Arrows.rowCount != motionVectorsResolution)
+ {
+ m_Arrows.Release();
+ m_Arrows.BuildMesh(num, motionVectorsResolution);
+ }
+ }
+
+ public override void OnDisable()
+ {
+ if (m_Arrows != null)
+ {
+ m_Arrows.Release();
+ }
+ m_Arrows = null;
+ }
+}
diff --git a/UnityEngine.PostProcessing/BuiltinDebugViewsModel.cs b/UnityEngine.PostProcessing/BuiltinDebugViewsModel.cs
new file mode 100644
index 0000000..7a6f53c
--- /dev/null
+++ b/UnityEngine.PostProcessing/BuiltinDebugViewsModel.cs
@@ -0,0 +1,131 @@
+using System;
+
+namespace UnityEngine.PostProcessing;
+
+[Serializable]
+public class BuiltinDebugViewsModel : PostProcessingModel
+{
+ [Serializable]
+ public struct DepthSettings
+ {
+ [Range(0f, 1f)]
+ [Tooltip("Scales the camera far plane before displaying the depth map.")]
+ public float scale;
+
+ public static DepthSettings defaultSettings
+ {
+ get
+ {
+ DepthSettings result = default(DepthSettings);
+ result.scale = 1f;
+ return result;
+ }
+ }
+ }
+
+ [Serializable]
+ public struct MotionVectorsSettings
+ {
+ [Range(0f, 1f)]
+ [Tooltip("Opacity of the source render.")]
+ public float sourceOpacity;
+
+ [Range(0f, 1f)]
+ [Tooltip("Opacity of the per-pixel motion vector colors.")]
+ public float motionImageOpacity;
+
+ [Min(0f)]
+ [Tooltip("Because motion vectors are mainly very small vectors, you can use this setting to make them more visible.")]
+ public float motionImageAmplitude;
+
+ [Range(0f, 1f)]
+ [Tooltip("Opacity for the motion vector arrows.")]
+ public float motionVectorsOpacity;
+
+ [Range(8f, 64f)]
+ [Tooltip("The arrow density on screen.")]
+ public int motionVectorsResolution;
+
+ [Min(0f)]
+ [Tooltip("Tweaks the arrows length.")]
+ public float motionVectorsAmplitude;
+
+ public static MotionVectorsSettings defaultSettings
+ {
+ get
+ {
+ MotionVectorsSettings result = default(MotionVectorsSettings);
+ result.sourceOpacity = 1f;
+ result.motionImageOpacity = 0f;
+ result.motionImageAmplitude = 16f;
+ result.motionVectorsOpacity = 1f;
+ result.motionVectorsResolution = 24;
+ result.motionVectorsAmplitude = 64f;
+ return result;
+ }
+ }
+ }
+
+ public enum Mode
+ {
+ None,
+ Depth,
+ Normals,
+ MotionVectors,
+ AmbientOcclusion,
+ EyeAdaptation,
+ FocusPlane,
+ PreGradingLog,
+ LogLut,
+ UserLut
+ }
+
+ [Serializable]
+ public struct Settings
+ {
+ public Mode mode;
+
+ public DepthSettings depth;
+
+ public MotionVectorsSettings motionVectors;
+
+ public static Settings defaultSettings
+ {
+ get
+ {
+ Settings result = default(Settings);
+ result.mode = Mode.None;
+ result.depth = DepthSettings.defaultSettings;
+ result.motionVectors = MotionVectorsSettings.defaultSettings;
+ return result;
+ }
+ }
+ }
+
+ [SerializeField]
+ private Settings m_Settings = Settings.defaultSettings;
+
+ public Settings settings
+ {
+ get
+ {
+ return m_Settings;
+ }
+ set
+ {
+ m_Settings = value;
+ }
+ }
+
+ public bool willInterrupt => !IsModeActive(Mode.None) && !IsModeActive(Mode.EyeAdaptation) && !IsModeActive(Mode.PreGradingLog) && !IsModeActive(Mode.LogLut) && !IsModeActive(Mode.UserLut);
+
+ public override void Reset()
+ {
+ settings = Settings.defaultSettings;
+ }
+
+ public bool IsModeActive(Mode mode)
+ {
+ return m_Settings.mode == mode;
+ }
+}
diff --git a/UnityEngine.PostProcessing/ChromaticAberrationComponent.cs b/UnityEngine.PostProcessing/ChromaticAberrationComponent.cs
new file mode 100644
index 0000000..1e5b82a
--- /dev/null
+++ b/UnityEngine.PostProcessing/ChromaticAberrationComponent.cs
@@ -0,0 +1,53 @@
+namespace UnityEngine.PostProcessing;
+
+public sealed class ChromaticAberrationComponent : PostProcessingComponentRenderTexture<ChromaticAberrationModel>
+{
+ private static class Uniforms
+ {
+ internal static readonly int _ChromaticAberration_Amount = Shader.PropertyToID("_ChromaticAberration_Amount");
+
+ internal static readonly int _ChromaticAberration_Spectrum = Shader.PropertyToID("_ChromaticAberration_Spectrum");
+ }
+
+ private Texture2D m_SpectrumLut;
+
+ public override bool active => base.model.enabled && base.model.settings.intensity > 0f && !context.interrupted;
+
+ public override void OnDisable()
+ {
+ GraphicsUtils.Destroy(m_SpectrumLut);
+ m_SpectrumLut = null;
+ }
+
+ public override void Prepare(Material uberMaterial)
+ {
+ ChromaticAberrationModel.Settings settings = base.model.settings;
+ Texture2D texture2D = settings.spectralTexture;
+ if (texture2D == null)
+ {
+ if (m_SpectrumLut == null)
+ {
+ m_SpectrumLut = new Texture2D(3, 1, TextureFormat.RGB24, mipmap: false)
+ {
+ name = "Chromatic Aberration Spectrum Lookup",
+ filterMode = FilterMode.Bilinear,
+ wrapMode = TextureWrapMode.Clamp,
+ anisoLevel = 0,
+ hideFlags = HideFlags.DontSave
+ };
+ Color[] pixels = new Color[3]
+ {
+ new Color(1f, 0f, 0f),
+ new Color(0f, 1f, 0f),
+ new Color(0f, 0f, 1f)
+ };
+ m_SpectrumLut.SetPixels(pixels);
+ m_SpectrumLut.Apply();
+ }
+ texture2D = m_SpectrumLut;
+ }
+ uberMaterial.EnableKeyword("CHROMATIC_ABERRATION");
+ uberMaterial.SetFloat(Uniforms._ChromaticAberration_Amount, settings.intensity * 0.03f);
+ uberMaterial.SetTexture(Uniforms._ChromaticAberration_Spectrum, texture2D);
+ }
+}
diff --git a/UnityEngine.PostProcessing/ChromaticAberrationModel.cs b/UnityEngine.PostProcessing/ChromaticAberrationModel.cs
new file mode 100644
index 0000000..a648f9f
--- /dev/null
+++ b/UnityEngine.PostProcessing/ChromaticAberrationModel.cs
@@ -0,0 +1,49 @@
+using System;
+
+namespace UnityEngine.PostProcessing;
+
+[Serializable]
+public class ChromaticAberrationModel : PostProcessingModel
+{
+ [Serializable]
+ public struct Settings
+ {
+ [Tooltip("Shift the hue of chromatic aberrations.")]
+ public Texture2D spectralTexture;
+
+ [Range(0f, 1f)]
+ [Tooltip("Amount of tangential distortion.")]
+ public float intensity;
+
+ public static Settings defaultSettings
+ {
+ get
+ {
+ Settings result = default(Settings);
+ result.spectralTexture = null;
+ result.intensity = 0.1f;
+ return result;
+ }
+ }
+ }
+
+ [SerializeField]
+ private Settings m_Settings = Settings.defaultSettings;
+
+ public Settings settings
+ {
+ get
+ {
+ return m_Settings;
+ }
+ set
+ {
+ m_Settings = value;
+ }
+ }
+
+ public override void Reset()
+ {
+ m_Settings = Settings.defaultSettings;
+ }
+}
diff --git a/UnityEngine.PostProcessing/ColorGradingComponent.cs b/UnityEngine.PostProcessing/ColorGradingComponent.cs
new file mode 100644
index 0000000..7d7c65a
--- /dev/null
+++ b/UnityEngine.PostProcessing/ColorGradingComponent.cs
@@ -0,0 +1,341 @@
+namespace UnityEngine.PostProcessing;
+
+public sealed class ColorGradingComponent : PostProcessingComponentRenderTexture<ColorGradingModel>
+{
+ private static class Uniforms
+ {
+ internal static readonly int _LutParams = Shader.PropertyToID("_LutParams");
+
+ internal static readonly int _NeutralTonemapperParams1 = Shader.PropertyToID("_NeutralTonemapperParams1");
+
+ internal static readonly int _NeutralTonemapperParams2 = Shader.PropertyToID("_NeutralTonemapperParams2");
+
+ internal static readonly int _HueShift = Shader.PropertyToID("_HueShift");
+
+ internal static readonly int _Saturation = Shader.PropertyToID("_Saturation");
+
+ internal static readonly int _Contrast = Shader.PropertyToID("_Contrast");
+
+ internal static readonly int _Balance = Shader.PropertyToID("_Balance");
+
+ internal static readonly int _Lift = Shader.PropertyToID("_Lift");
+
+ internal static readonly int _InvGamma = Shader.PropertyToID("_InvGamma");
+
+ internal static readonly int _Gain = Shader.PropertyToID("_Gain");
+
+ internal static readonly int _Slope = Shader.PropertyToID("_Slope");
+
+ internal static readonly int _Power = Shader.PropertyToID("_Power");
+
+ internal static readonly int _Offset = Shader.PropertyToID("_Offset");
+
+ internal static readonly int _ChannelMixerRed = Shader.PropertyToID("_ChannelMixerRed");
+
+ internal static readonly int _ChannelMixerGreen = Shader.PropertyToID("_ChannelMixerGreen");
+
+ internal static readonly int _ChannelMixerBlue = Shader.PropertyToID("_ChannelMixerBlue");
+
+ internal static readonly int _Curves = Shader.PropertyToID("_Curves");
+
+ internal static readonly int _LogLut = Shader.PropertyToID("_LogLut");
+
+ internal static readonly int _LogLut_Params = Shader.PropertyToID("_LogLut_Params");
+
+ internal static readonly int _ExposureEV = Shader.PropertyToID("_ExposureEV");
+ }
+
+ private const int k_InternalLogLutSize = 32;
+
+ private const int k_CurvePrecision = 128;
+
+ private const float k_CurveStep = 1f / 128f;
+
+ private Texture2D m_GradingCurves;
+
+ private Color[] m_pixels = new Color[256];
+
+ public override bool active => base.model.enabled && !context.interrupted;
+
+ private float StandardIlluminantY(float x)
+ {
+ return 2.87f * x - 3f * x * x - 0.27509508f;
+ }
+
+ private Vector3 CIExyToLMS(float x, float y)
+ {
+ float num = 1f;
+ float num2 = num * x / y;
+ float num3 = num * (1f - x - y) / y;
+ float x2 = 0.7328f * num2 + 0.4296f * num - 0.1624f * num3;
+ float y2 = -0.7036f * num2 + 1.6975f * num + 0.0061f * num3;
+ float z = 0.003f * num2 + 0.0136f * num + 0.9834f * num3;
+ return new Vector3(x2, y2, z);
+ }
+
+ private Vector3 CalculateColorBalance(float temperature, float tint)
+ {
+ float num = temperature / 55f;
+ float num2 = tint / 55f;
+ float x = 0.31271f - num * ((!(num < 0f)) ? 0.05f : 0.1f);
+ float y = StandardIlluminantY(x) + num2 * 0.05f;
+ Vector3 vector = new Vector3(0.949237f, 1.03542f, 1.08728f);
+ Vector3 vector2 = CIExyToLMS(x, y);
+ return new Vector3(vector.x / vector2.x, vector.y / vector2.y, vector.z / vector2.z);
+ }
+
+ private static Color NormalizeColor(Color c)
+ {
+ float num = (c.r + c.g + c.b) / 3f;
+ if (Mathf.Approximately(num, 0f))
+ {
+ return new Color(1f, 1f, 1f, c.a);
+ }
+ Color result = default(Color);
+ result.r = c.r / num;
+ result.g = c.g / num;
+ result.b = c.b / num;
+ result.a = c.a;
+ return result;
+ }
+
+ private static Vector3 ClampVector(Vector3 v, float min, float max)
+ {
+ return new Vector3(Mathf.Clamp(v.x, min, max), Mathf.Clamp(v.y, min, max), Mathf.Clamp(v.z, min, max));
+ }
+
+ public static Vector3 GetLiftValue(Color lift)
+ {
+ Color color = NormalizeColor(lift);
+ float num = (color.r + color.g + color.b) / 3f;
+ float x = (color.r - num) * 0.1f + lift.a;
+ float y = (color.g - num) * 0.1f + lift.a;
+ float z = (color.b - num) * 0.1f + lift.a;
+ return ClampVector(new Vector3(x, y, z), -1f, 1f);
+ }
+
+ public static Vector3 GetGammaValue(Color gamma)
+ {
+ Color color = NormalizeColor(gamma);
+ float num = (color.r + color.g + color.b) / 3f;
+ gamma.a *= ((!(gamma.a < 0f)) ? 5f : 0.8f);
+ float b = Mathf.Pow(2f, (color.r - num) * 0.5f) + gamma.a;
+ float b2 = Mathf.Pow(2f, (color.g - num) * 0.5f) + gamma.a;
+ float b3 = Mathf.Pow(2f, (color.b - num) * 0.5f) + gamma.a;
+ float x = 1f / Mathf.Max(0.01f, b);
+ float y = 1f / Mathf.Max(0.01f, b2);
+ float z = 1f / Mathf.Max(0.01f, b3);
+ return ClampVector(new Vector3(x, y, z), 0f, 5f);
+ }
+
+ public static Vector3 GetGainValue(Color gain)
+ {
+ Color color = NormalizeColor(gain);
+ float num = (color.r + color.g + color.b) / 3f;
+ gain.a *= ((!(gain.a > 0f)) ? 1f : 3f);
+ float x = Mathf.Pow(2f, (color.r - num) * 0.5f) + gain.a;
+ float y = Mathf.Pow(2f, (color.g - num) * 0.5f) + gain.a;
+ float z = Mathf.Pow(2f, (color.b - num) * 0.5f) + gain.a;
+ return ClampVector(new Vector3(x, y, z), 0f, 4f);
+ }
+
+ public static void CalculateLiftGammaGain(Color lift, Color gamma, Color gain, out Vector3 outLift, out Vector3 outGamma, out Vector3 outGain)
+ {
+ outLift = GetLiftValue(lift);
+ outGamma = GetGammaValue(gamma);
+ outGain = GetGainValue(gain);
+ }
+
+ public static Vector3 GetSlopeValue(Color slope)
+ {
+ Color color = NormalizeColor(slope);
+ float num = (color.r + color.g + color.b) / 3f;
+ slope.a *= 0.5f;
+ float x = (color.r - num) * 0.1f + slope.a + 1f;
+ float y = (color.g - num) * 0.1f + slope.a + 1f;
+ float z = (color.b - num) * 0.1f + slope.a + 1f;
+ return ClampVector(new Vector3(x, y, z), 0f, 2f);
+ }
+
+ public static Vector3 GetPowerValue(Color power)
+ {
+ Color color = NormalizeColor(power);
+ float num = (color.r + color.g + color.b) / 3f;
+ power.a *= 0.5f;
+ float b = (color.r - num) * 0.1f + power.a + 1f;
+ float b2 = (color.g - num) * 0.1f + power.a + 1f;
+ float b3 = (color.b - num) * 0.1f + power.a + 1f;
+ float x = 1f / Mathf.Max(0.01f, b);
+ float y = 1f / Mathf.Max(0.01f, b2);
+ float z = 1f / Mathf.Max(0.01f, b3);
+ return ClampVector(new Vector3(x, y, z), 0.5f, 2.5f);
+ }
+
+ public static Vector3 GetOffsetValue(Color offset)
+ {
+ Color color = NormalizeColor(offset);
+ float num = (color.r + color.g + color.b) / 3f;
+ offset.a *= 0.5f;
+ float x = (color.r - num) * 0.05f + offset.a;
+ float y = (color.g - num) * 0.05f + offset.a;
+ float z = (color.b - num) * 0.05f + offset.a;
+ return ClampVector(new Vector3(x, y, z), -0.8f, 0.8f);
+ }
+
+ public static void CalculateSlopePowerOffset(Color slope, Color power, Color offset, out Vector3 outSlope, out Vector3 outPower, out Vector3 outOffset)
+ {
+ outSlope = GetSlopeValue(slope);
+ outPower = GetPowerValue(power);
+ outOffset = GetOffsetValue(offset);
+ }
+
+ private TextureFormat GetCurveFormat()
+ {
+ if (SystemInfo.SupportsTextureFormat(TextureFormat.RGBAHalf))
+ {
+ return TextureFormat.RGBAHalf;
+ }
+ return TextureFormat.RGBA32;
+ }
+
+ private Texture2D GetCurveTexture()
+ {
+ if (m_GradingCurves == null)
+ {
+ m_GradingCurves = new Texture2D(128, 2, GetCurveFormat(), mipmap: false, linear: true)
+ {
+ name = "Internal Curves Texture",
+ hideFlags = HideFlags.DontSave,
+ anisoLevel = 0,
+ wrapMode = TextureWrapMode.Clamp,
+ filterMode = FilterMode.Bilinear
+ };
+ }
+ ColorGradingModel.CurvesSettings curves = base.model.settings.curves;
+ curves.hueVShue.Cache();
+ curves.hueVSsat.Cache();
+ for (int i = 0; i < 128; i++)
+ {
+ float t = (float)i * (1f / 128f);
+ float r = curves.hueVShue.Evaluate(t);
+ float g = curves.hueVSsat.Evaluate(t);
+ float b = curves.satVSsat.Evaluate(t);
+ float a = curves.lumVSsat.Evaluate(t);
+ ref Color reference = ref m_pixels[i];
+ reference = new Color(r, g, b, a);
+ float a2 = curves.master.Evaluate(t);
+ float r2 = curves.red.Evaluate(t);
+ float g2 = curves.green.Evaluate(t);
+ float b2 = curves.blue.Evaluate(t);
+ ref Color reference2 = ref m_pixels[i + 128];
+ reference2 = new Color(r2, g2, b2, a2);
+ }
+ m_GradingCurves.SetPixels(m_pixels);
+ m_GradingCurves.Apply(updateMipmaps: false, makeNoLongerReadable: false);
+ return m_GradingCurves;
+ }
+
+ private bool IsLogLutValid(RenderTexture lut)
+ {
+ return lut != null && lut.IsCreated() && lut.height == 32;
+ }
+
+ private RenderTextureFormat GetLutFormat()
+ {
+ if (SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.ARGBHalf))
+ {
+ return RenderTextureFormat.ARGBHalf;
+ }
+ return RenderTextureFormat.ARGB32;
+ }
+
+ private void GenerateLut()
+ {
+ ColorGradingModel.Settings settings = base.model.settings;
+ if (!IsLogLutValid(base.model.bakedLut))
+ {
+ GraphicsUtils.Destroy(base.model.bakedLut);
+ base.model.bakedLut = new RenderTexture(1024, 32, 0, GetLutFormat())
+ {
+ name = "Color Grading Log LUT",
+ hideFlags = HideFlags.DontSave,
+ filterMode = FilterMode.Bilinear,
+ wrapMode = TextureWrapMode.Clamp,
+ anisoLevel = 0
+ };
+ }
+ Material material = context.materialFactory.Get("Hidden/Post FX/Lut Generator");
+ material.SetVector(Uniforms._LutParams, new Vector4(32f, 0.00048828125f, 1f / 64f, 1.032258f));
+ material.shaderKeywords = null;
+ ColorGradingModel.TonemappingSettings tonemapping = settings.tonemapping;
+ switch (tonemapping.tonemapper)
+ {
+ case ColorGradingModel.Tonemapper.Neutral:
+ {
+ material.EnableKeyword("TONEMAPPING_NEUTRAL");
+ float num = tonemapping.neutralBlackIn * 20f + 1f;
+ float num2 = tonemapping.neutralBlackOut * 10f + 1f;
+ float num3 = tonemapping.neutralWhiteIn / 20f;
+ float num4 = 1f - tonemapping.neutralWhiteOut / 20f;
+ float t = num / num2;
+ float t2 = num3 / num4;
+ float y = Mathf.Max(0f, Mathf.LerpUnclamped(0.57f, 0.37f, t));
+ float z = Mathf.LerpUnclamped(0.01f, 0.24f, t2);
+ float w = Mathf.Max(0f, Mathf.LerpUnclamped(0.02f, 0.2f, t));
+ material.SetVector(Uniforms._NeutralTonemapperParams1, new Vector4(0.2f, y, z, w));
+ material.SetVector(Uniforms._NeutralTonemapperParams2, new Vector4(0.02f, 0.3f, tonemapping.neutralWhiteLevel, tonemapping.neutralWhiteClip / 10f));
+ break;
+ }
+ case ColorGradingModel.Tonemapper.ACES:
+ material.EnableKeyword("TONEMAPPING_FILMIC");
+ break;
+ }
+ material.SetFloat(Uniforms._HueShift, settings.basic.hueShift / 360f);
+ material.SetFloat(Uniforms._Saturation, settings.basic.saturation);
+ material.SetFloat(Uniforms._Contrast, settings.basic.contrast);
+ material.SetVector(Uniforms._Balance, CalculateColorBalance(settings.basic.temperature, settings.basic.tint));
+ CalculateLiftGammaGain(settings.colorWheels.linear.lift, settings.colorWheels.linear.gamma, settings.colorWheels.linear.gain, out var outLift, out var outGamma, out var outGain);
+ material.SetVector(Uniforms._Lift, outLift);
+ material.SetVector(Uniforms._InvGamma, outGamma);
+ material.SetVector(Uniforms._Gain, outGain);
+ CalculateSlopePowerOffset(settings.colorWheels.log.slope, settings.colorWheels.log.power, settings.colorWheels.log.offset, out var outSlope, out var outPower, out var outOffset);
+ material.SetVector(Uniforms._Slope, outSlope);
+ material.SetVector(Uniforms._Power, outPower);
+ material.SetVector(Uniforms._Offset, outOffset);
+ material.SetVector(Uniforms._ChannelMixerRed, settings.channelMixer.red);
+ material.SetVector(Uniforms._ChannelMixerGreen, settings.channelMixer.green);
+ material.SetVector(Uniforms._ChannelMixerBlue, settings.channelMixer.blue);
+ material.SetTexture(Uniforms._Curves, GetCurveTexture());
+ Graphics.Blit(null, base.model.bakedLut, material, 0);
+ }
+
+ public override void Prepare(Material uberMaterial)
+ {
+ if (base.model.isDirty || !IsLogLutValid(base.model.bakedLut))
+ {
+ GenerateLut();
+ base.model.isDirty = false;
+ }
+ uberMaterial.EnableKeyword((!context.profile.debugViews.IsModeActive(BuiltinDebugViewsModel.Mode.PreGradingLog)) ? "COLOR_GRADING" : "COLOR_GRADING_LOG_VIEW");
+ RenderTexture bakedLut = base.model.bakedLut;
+ uberMaterial.SetTexture(Uniforms._LogLut, bakedLut);
+ uberMaterial.SetVector(Uniforms._LogLut_Params, new Vector3(1f / (float)bakedLut.width, 1f / (float)bakedLut.height, (float)bakedLut.height - 1f));
+ float value = Mathf.Exp(base.model.settings.basic.postExposure * 0.6931472f);
+ uberMaterial.SetFloat(Uniforms._ExposureEV, value);
+ }
+
+ public void OnGUI()
+ {
+ RenderTexture bakedLut = base.model.bakedLut;
+ Rect position = new Rect(context.viewport.x * (float)Screen.width + 8f, 8f, bakedLut.width, bakedLut.height);
+ GUI.DrawTexture(position, bakedLut);
+ }
+
+ public override void OnDisable()
+ {
+ GraphicsUtils.Destroy(m_GradingCurves);
+ GraphicsUtils.Destroy(base.model.bakedLut);
+ m_GradingCurves = null;
+ base.model.bakedLut = null;
+ }
+}
diff --git a/UnityEngine.PostProcessing/ColorGradingCurve.cs b/UnityEngine.PostProcessing/ColorGradingCurve.cs
new file mode 100644
index 0000000..49ea13a
--- /dev/null
+++ b/UnityEngine.PostProcessing/ColorGradingCurve.cs
@@ -0,0 +1,64 @@
+using System;
+
+namespace UnityEngine.PostProcessing;
+
+[Serializable]
+public sealed class ColorGradingCurve
+{
+ public AnimationCurve curve;
+
+ [SerializeField]
+ private bool m_Loop;
+
+ [SerializeField]
+ private float m_ZeroValue;
+
+ [SerializeField]
+ private float m_Range;
+
+ private AnimationCurve m_InternalLoopingCurve;
+
+ public ColorGradingCurve(AnimationCurve curve, float zeroValue, bool loop, Vector2 bounds)
+ {
+ this.curve = curve;
+ m_ZeroValue = zeroValue;
+ m_Loop = loop;
+ m_Range = bounds.magnitude;
+ }
+
+ public void Cache()
+ {
+ if (!m_Loop)
+ {
+ return;
+ }
+ int length = curve.length;
+ if (length >= 2)
+ {
+ if (m_InternalLoopingCurve == null)
+ {
+ m_InternalLoopingCurve = new AnimationCurve();
+ }
+ Keyframe key = curve[length - 1];
+ key.time -= m_Range;
+ Keyframe key2 = curve[0];
+ key2.time += m_Range;
+ m_InternalLoopingCurve.keys = curve.keys;
+ m_InternalLoopingCurve.AddKey(key);
+ m_InternalLoopingCurve.AddKey(key2);
+ }
+ }
+
+ public float Evaluate(float t)
+ {
+ if (curve.length == 0)
+ {
+ return m_ZeroValue;
+ }
+ if (!m_Loop || curve.length == 1)
+ {
+ return curve.Evaluate(t);
+ }
+ return m_InternalLoopingCurve.Evaluate(t);
+ }
+}
diff --git a/UnityEngine.PostProcessing/ColorGradingModel.cs b/UnityEngine.PostProcessing/ColorGradingModel.cs
new file mode 100644
index 0000000..5d5a45b
--- /dev/null
+++ b/UnityEngine.PostProcessing/ColorGradingModel.cs
@@ -0,0 +1,319 @@
+using System;
+
+namespace UnityEngine.PostProcessing;
+
+[Serializable]
+public class ColorGradingModel : PostProcessingModel
+{
+ public enum Tonemapper
+ {
+ None,
+ ACES,
+ Neutral
+ }
+
+ [Serializable]
+ public struct TonemappingSettings
+ {
+ [Tooltip("Tonemapping algorithm to use at the end of the color grading process. Use \"Neutral\" if you need a customizable tonemapper or \"Filmic\" to give a standard filmic look to your scenes.")]
+ public Tonemapper tonemapper;
+
+ [Range(-0.1f, 0.1f)]
+ public float neutralBlackIn;
+
+ [Range(1f, 20f)]
+ public float neutralWhiteIn;
+
+ [Range(-0.09f, 0.1f)]
+ public float neutralBlackOut;
+
+ [Range(1f, 19f)]
+ public float neutralWhiteOut;
+
+ [Range(0.1f, 20f)]
+ public float neutralWhiteLevel;
+
+ [Range(1f, 10f)]
+ public float neutralWhiteClip;
+
+ public static TonemappingSettings defaultSettings
+ {
+ get
+ {
+ TonemappingSettings result = default(TonemappingSettings);
+ result.tonemapper = Tonemapper.Neutral;
+ result.neutralBlackIn = 0.02f;
+ result.neutralWhiteIn = 10f;
+ result.neutralBlackOut = 0f;
+ result.neutralWhiteOut = 10f;
+ result.neutralWhiteLevel = 5.3f;
+ result.neutralWhiteClip = 10f;
+ return result;
+ }
+ }
+ }
+
+ [Serializable]
+ public struct BasicSettings
+ {
+ [Tooltip("Adjusts the overall exposure of the scene in EV units. This is applied after HDR effect and right before tonemapping so it won't affect previous effects in the chain.")]
+ public float postExposure;
+
+ [Range(-100f, 100f)]
+ [Tooltip("Sets the white balance to a custom color temperature.")]
+ public float temperature;
+
+ [Range(-100f, 100f)]
+ [Tooltip("Sets the white balance to compensate for a green or magenta tint.")]
+ public float tint;
+
+ [Range(-180f, 180f)]
+ [Tooltip("Shift the hue of all colors.")]
+ public float hueShift;
+
+ [Range(0f, 2f)]
+ [Tooltip("Pushes the intensity of all colors.")]
+ public float saturation;
+
+ [Range(0f, 2f)]
+ [Tooltip("Expands or shrinks the overall range of tonal values.")]
+ public float contrast;
+
+ public static BasicSettings defaultSettings
+ {
+ get
+ {
+ BasicSettings result = default(BasicSettings);
+ result.postExposure = 0f;
+ result.temperature = 0f;
+ result.tint = 0f;
+ result.hueShift = 0f;
+ result.saturation = 1f;
+ result.contrast = 1f;
+ return result;
+ }
+ }
+ }
+
+ [Serializable]
+ public struct ChannelMixerSettings
+ {
+ public Vector3 red;
+
+ public Vector3 green;
+
+ public Vector3 blue;
+
+ [HideInInspector]
+ public int currentEditingChannel;
+
+ public static ChannelMixerSettings defaultSettings
+ {
+ get
+ {
+ ChannelMixerSettings result = default(ChannelMixerSettings);
+ result.red = new Vector3(1f, 0f, 0f);
+ result.green = new Vector3(0f, 1f, 0f);
+ result.blue = new Vector3(0f, 0f, 1f);
+ result.currentEditingChannel = 0;
+ return result;
+ }
+ }
+ }
+
+ [Serializable]
+ public struct LogWheelsSettings
+ {
+ [Trackball("GetSlopeValue")]
+ public Color slope;
+
+ [Trackball("GetPowerValue")]
+ public Color power;
+
+ [Trackball("GetOffsetValue")]
+ public Color offset;
+
+ public static LogWheelsSettings defaultSettings
+ {
+ get
+ {
+ LogWheelsSettings result = default(LogWheelsSettings);
+ result.slope = Color.clear;
+ result.power = Color.clear;
+ result.offset = Color.clear;
+ return result;
+ }
+ }
+ }
+
+ [Serializable]
+ public struct LinearWheelsSettings
+ {
+ [Trackball("GetLiftValue")]
+ public Color lift;
+
+ [Trackball("GetGammaValue")]
+ public Color gamma;
+
+ [Trackball("GetGainValue")]
+ public Color gain;
+
+ public static LinearWheelsSettings defaultSettings
+ {
+ get
+ {
+ LinearWheelsSettings result = default(LinearWheelsSettings);
+ result.lift = Color.clear;
+ result.gamma = Color.clear;
+ result.gain = Color.clear;
+ return result;
+ }
+ }
+ }
+
+ public enum ColorWheelMode
+ {
+ Linear,
+ Log
+ }
+
+ [Serializable]
+ public struct ColorWheelsSettings
+ {
+ public ColorWheelMode mode;
+
+ [TrackballGroup]
+ public LogWheelsSettings log;
+
+ [TrackballGroup]
+ public LinearWheelsSettings linear;
+
+ public static ColorWheelsSettings defaultSettings
+ {
+ get
+ {
+ ColorWheelsSettings result = default(ColorWheelsSettings);
+ result.mode = ColorWheelMode.Log;
+ result.log = LogWheelsSettings.defaultSettings;
+ result.linear = LinearWheelsSettings.defaultSettings;
+ return result;
+ }
+ }
+ }
+
+ [Serializable]
+ public struct CurvesSettings
+ {
+ public ColorGradingCurve master;
+
+ public ColorGradingCurve red;
+
+ public ColorGradingCurve green;
+
+ public ColorGradingCurve blue;
+
+ public ColorGradingCurve hueVShue;
+
+ public ColorGradingCurve hueVSsat;
+
+ public ColorGradingCurve satVSsat;
+
+ public ColorGradingCurve lumVSsat;
+
+ [HideInInspector]
+ public int e_CurrentEditingCurve;
+
+ [HideInInspector]
+ public bool e_CurveY;
+
+ [HideInInspector]
+ public bool e_CurveR;
+
+ [HideInInspector]
+ public bool e_CurveG;
+
+ [HideInInspector]
+ public bool e_CurveB;
+
+ public static CurvesSettings defaultSettings
+ {
+ get
+ {
+ CurvesSettings result = default(CurvesSettings);
+ result.master = new ColorGradingCurve(new AnimationCurve(new Keyframe(0f, 0f, 1f, 1f), new Keyframe(1f, 1f, 1f, 1f)), 0f, loop: false, new Vector2(0f, 1f));
+ result.red = new ColorGradingCurve(new AnimationCurve(new Keyframe(0f, 0f, 1f, 1f), new Keyframe(1f, 1f, 1f, 1f)), 0f, loop: false, new Vector2(0f, 1f));
+ result.green = new ColorGradingCurve(new AnimationCurve(new Keyframe(0f, 0f, 1f, 1f), new Keyframe(1f, 1f, 1f, 1f)), 0f, loop: false, new Vector2(0f, 1f));
+ result.blue = new ColorGradingCurve(new AnimationCurve(new Keyframe(0f, 0f, 1f, 1f), new Keyframe(1f, 1f, 1f, 1f)), 0f, loop: false, new Vector2(0f, 1f));
+ result.hueVShue = new ColorGradingCurve(new AnimationCurve(), 0.5f, loop: true, new Vector2(0f, 1f));
+ result.hueVSsat = new ColorGradingCurve(new AnimationCurve(), 0.5f, loop: true, new Vector2(0f, 1f));
+ result.satVSsat = new ColorGradingCurve(new AnimationCurve(), 0.5f, loop: false, new Vector2(0f, 1f));
+ result.lumVSsat = new ColorGradingCurve(new AnimationCurve(), 0.5f, loop: false, new Vector2(0f, 1f));
+ result.e_CurrentEditingCurve = 0;
+ result.e_CurveY = true;
+ result.e_CurveR = false;
+ result.e_CurveG = false;
+ result.e_CurveB = false;
+ return result;
+ }
+ }
+ }
+
+ [Serializable]
+ public struct Settings
+ {
+ public TonemappingSettings tonemapping;
+
+ public BasicSettings basic;
+
+ public ChannelMixerSettings channelMixer;
+
+ public ColorWheelsSettings colorWheels;
+
+ public CurvesSettings curves;
+
+ public static Settings defaultSettings
+ {
+ get
+ {
+ Settings result = default(Settings);
+ result.tonemapping = TonemappingSettings.defaultSettings;
+ result.basic = BasicSettings.defaultSettings;
+ result.channelMixer = ChannelMixerSettings.defaultSettings;
+ result.colorWheels = ColorWheelsSettings.defaultSettings;
+ result.curves = CurvesSettings.defaultSettings;
+ return result;
+ }
+ }
+ }
+
+ [SerializeField]
+ private Settings m_Settings = Settings.defaultSettings;
+
+ public Settings settings
+ {
+ get
+ {
+ return m_Settings;
+ }
+ set
+ {
+ m_Settings = value;
+ OnValidate();
+ }
+ }
+
+ public bool isDirty { get; internal set; }
+
+ public RenderTexture bakedLut { get; internal set; }
+
+ public override void Reset()
+ {
+ m_Settings = Settings.defaultSettings;
+ OnValidate();
+ }
+
+ public override void OnValidate()
+ {
+ isDirty = true;
+ }
+}
diff --git a/UnityEngine.PostProcessing/DepthOfFieldComponent.cs b/UnityEngine.PostProcessing/DepthOfFieldComponent.cs
new file mode 100644
index 0000000..a57657c
--- /dev/null
+++ b/UnityEngine.PostProcessing/DepthOfFieldComponent.cs
@@ -0,0 +1,141 @@
+using System;
+
+namespace UnityEngine.PostProcessing;
+
+public sealed class DepthOfFieldComponent : PostProcessingComponentRenderTexture<DepthOfFieldModel>
+{
+ private static class Uniforms
+ {
+ internal static readonly int _DepthOfFieldTex = Shader.PropertyToID("_DepthOfFieldTex");
+
+ internal static readonly int _DepthOfFieldCoCTex = Shader.PropertyToID("_DepthOfFieldCoCTex");
+
+ internal static readonly int _Distance = Shader.PropertyToID("_Distance");
+
+ internal static readonly int _LensCoeff = Shader.PropertyToID("_LensCoeff");
+
+ internal static readonly int _MaxCoC = Shader.PropertyToID("_MaxCoC");
+
+ internal static readonly int _RcpMaxCoC = Shader.PropertyToID("_RcpMaxCoC");
+
+ internal static readonly int _RcpAspect = Shader.PropertyToID("_RcpAspect");
+
+ internal static readonly int _MainTex = Shader.PropertyToID("_MainTex");
+
+ internal static readonly int _CoCTex = Shader.PropertyToID("_CoCTex");
+
+ internal static readonly int _TaaParams = Shader.PropertyToID("_TaaParams");
+
+ internal static readonly int _DepthOfFieldParams = Shader.PropertyToID("_DepthOfFieldParams");
+ }
+
+ private const string k_ShaderString = "Hidden/Post FX/Depth Of Field";
+
+ private RenderTexture m_CoCHistory;
+
+ private const float k_FilmHeight = 0.024f;
+
+ public override bool active => base.model.enabled && !context.interrupted;
+
+ public override DepthTextureMode GetCameraFlags()
+ {
+ return DepthTextureMode.Depth;
+ }
+
+ private float CalculateFocalLength()
+ {
+ DepthOfFieldModel.Settings settings = base.model.settings;
+ if (!settings.useCameraFov)
+ {
+ return settings.focalLength / 1000f;
+ }
+ float num = context.camera.fieldOfView * ((float)Math.PI / 180f);
+ return 0.012f / Mathf.Tan(0.5f * num);
+ }
+
+ private float CalculateMaxCoCRadius(int screenHeight)
+ {
+ float num = (float)base.model.settings.kernelSize * 4f + 6f;
+ return Mathf.Min(0.05f, num / (float)screenHeight);
+ }
+
+ private bool CheckHistory(int width, int height)
+ {
+ return m_CoCHistory != null && m_CoCHistory.IsCreated() && m_CoCHistory.width == width && m_CoCHistory.height == height;
+ }
+
+ private RenderTextureFormat SelectFormat(RenderTextureFormat primary, RenderTextureFormat secondary)
+ {
+ if (SystemInfo.SupportsRenderTextureFormat(primary))
+ {
+ return primary;
+ }
+ if (SystemInfo.SupportsRenderTextureFormat(secondary))
+ {
+ return secondary;
+ }
+ return RenderTextureFormat.Default;
+ }
+
+ public void Prepare(RenderTexture source, Material uberMaterial, bool antialiasCoC, Vector2 taaJitter, float taaBlending)
+ {
+ DepthOfFieldModel.Settings settings = base.model.settings;
+ RenderTextureFormat format = RenderTextureFormat.DefaultHDR;
+ RenderTextureFormat format2 = SelectFormat(RenderTextureFormat.R8, RenderTextureFormat.RHalf);
+ float num = CalculateFocalLength();
+ float num2 = Mathf.Max(settings.focusDistance, num);
+ float num3 = (float)source.width / (float)source.height;
+ float num4 = num * num / (settings.aperture * (num2 - num) * 0.024f * 2f);
+ float num5 = CalculateMaxCoCRadius(source.height);
+ Material material = context.materialFactory.Get("Hidden/Post FX/Depth Of Field");
+ material.SetFloat(Uniforms._Distance, num2);
+ material.SetFloat(Uniforms._LensCoeff, num4);
+ material.SetFloat(Uniforms._MaxCoC, num5);
+ material.SetFloat(Uniforms._RcpMaxCoC, 1f / num5);
+ material.SetFloat(Uniforms._RcpAspect, 1f / num3);
+ RenderTexture renderTexture = context.renderTextureFactory.Get(context.width, context.height, 0, format2, RenderTextureReadWrite.Linear);
+ Graphics.Blit(null, renderTexture, material, 0);
+ if (antialiasCoC)
+ {
+ material.SetTexture(Uniforms._CoCTex, renderTexture);
+ float z = ((!CheckHistory(context.width, context.height)) ? 0f : taaBlending);
+ material.SetVector(Uniforms._TaaParams, new Vector3(taaJitter.x, taaJitter.y, z));
+ RenderTexture temporary = RenderTexture.GetTemporary(context.width, context.height, 0, format2);
+ Graphics.Blit(m_CoCHistory, temporary, material, 1);
+ context.renderTextureFactory.Release(renderTexture);
+ if (m_CoCHistory != null)
+ {
+ RenderTexture.ReleaseTemporary(m_CoCHistory);
+ }
+ renderTexture = (m_CoCHistory = temporary);
+ }
+ RenderTexture renderTexture2 = context.renderTextureFactory.Get(context.width / 2, context.height / 2, 0, format);
+ material.SetTexture(Uniforms._CoCTex, renderTexture);
+ Graphics.Blit(source, renderTexture2, material, 2);
+ RenderTexture renderTexture3 = context.renderTextureFactory.Get(context.width / 2, context.height / 2, 0, format);
+ Graphics.Blit(renderTexture2, renderTexture3, material, (int)(3 + settings.kernelSize));
+ Graphics.Blit(renderTexture3, renderTexture2, material, 7);
+ uberMaterial.SetVector(Uniforms._DepthOfFieldParams, new Vector3(num2, num4, num5));
+ if (context.profile.debugViews.IsModeActive(BuiltinDebugViewsModel.Mode.FocusPlane))
+ {
+ uberMaterial.EnableKeyword("DEPTH_OF_FIELD_COC_VIEW");
+ context.Interrupt();
+ }
+ else
+ {
+ uberMaterial.SetTexture(Uniforms._DepthOfFieldTex, renderTexture2);
+ uberMaterial.SetTexture(Uniforms._DepthOfFieldCoCTex, renderTexture);
+ uberMaterial.EnableKeyword("DEPTH_OF_FIELD");
+ }
+ context.renderTextureFactory.Release(renderTexture3);
+ }
+
+ public override void OnDisable()
+ {
+ if (m_CoCHistory != null)
+ {
+ RenderTexture.ReleaseTemporary(m_CoCHistory);
+ }
+ m_CoCHistory = null;
+ }
+}
diff --git a/UnityEngine.PostProcessing/DepthOfFieldModel.cs b/UnityEngine.PostProcessing/DepthOfFieldModel.cs
new file mode 100644
index 0000000..6ead0de
--- /dev/null
+++ b/UnityEngine.PostProcessing/DepthOfFieldModel.cs
@@ -0,0 +1,71 @@
+using System;
+
+namespace UnityEngine.PostProcessing;
+
+[Serializable]
+public class DepthOfFieldModel : PostProcessingModel
+{
+ public enum KernelSize
+ {
+ Small,
+ Medium,
+ Large,
+ VeryLarge
+ }
+
+ [Serializable]
+ public struct Settings
+ {
+ [Min(0.1f)]
+ [Tooltip("Distance to the point of focus.")]
+ public float focusDistance;
+
+ [Range(0.05f, 32f)]
+ [Tooltip("Ratio of aperture (known as f-stop or f-number). The smaller the value is, the shallower the depth of field is.")]
+ public float aperture;
+
+ [Range(1f, 300f)]
+ [Tooltip("Distance between the lens and the film. The larger the value is, the shallower the depth of field is.")]
+ public float focalLength;
+
+ [Tooltip("Calculate the focal length automatically from the field-of-view value set on the camera. Using this setting isn't recommended.")]
+ public bool useCameraFov;
+
+ [Tooltip("Convolution kernel size of the bokeh filter, which determines the maximum radius of bokeh. It also affects the performance (the larger the kernel is, the longer the GPU time is required).")]
+ public KernelSize kernelSize;
+
+ public static Settings defaultSettings
+ {
+ get
+ {
+ Settings result = default(Settings);
+ result.focusDistance = 10f;
+ result.aperture = 5.6f;
+ result.focalLength = 50f;
+ result.useCameraFov = false;
+ result.kernelSize = KernelSize.Medium;
+ return result;
+ }
+ }
+ }
+
+ [SerializeField]
+ private Settings m_Settings = Settings.defaultSettings;
+
+ public Settings settings
+ {
+ get
+ {
+ return m_Settings;
+ }
+ set
+ {
+ m_Settings = value;
+ }
+ }
+
+ public override void Reset()
+ {
+ m_Settings = Settings.defaultSettings;
+ }
+}
diff --git a/UnityEngine.PostProcessing/DitheringComponent.cs b/UnityEngine.PostProcessing/DitheringComponent.cs
new file mode 100644
index 0000000..a9f0554
--- /dev/null
+++ b/UnityEngine.PostProcessing/DitheringComponent.cs
@@ -0,0 +1,51 @@
+namespace UnityEngine.PostProcessing;
+
+public sealed class DitheringComponent : PostProcessingComponentRenderTexture<DitheringModel>
+{
+ private static class Uniforms
+ {
+ internal static readonly int _DitheringTex = Shader.PropertyToID("_DitheringTex");
+
+ internal static readonly int _DitheringCoords = Shader.PropertyToID("_DitheringCoords");
+ }
+
+ private Texture2D[] noiseTextures;
+
+ private int textureIndex;
+
+ private const int k_TextureCount = 64;
+
+ public override bool active => base.model.enabled && !context.interrupted;
+
+ public override void OnDisable()
+ {
+ noiseTextures = null;
+ }
+
+ private void LoadNoiseTextures()
+ {
+ noiseTextures = new Texture2D[64];
+ for (int i = 0; i < 64; i++)
+ {
+ noiseTextures[i] = Resources.Load<Texture2D>("Bluenoise64/LDR_LLL1_" + i);
+ }
+ }
+
+ public override void Prepare(Material uberMaterial)
+ {
+ if (++textureIndex >= 64)
+ {
+ textureIndex = 0;
+ }
+ float value = Random.value;
+ float value2 = Random.value;
+ if (noiseTextures == null)
+ {
+ LoadNoiseTextures();
+ }
+ Texture2D texture2D = noiseTextures[textureIndex];
+ uberMaterial.EnableKeyword("DITHERING");
+ uberMaterial.SetTexture(Uniforms._DitheringTex, texture2D);
+ uberMaterial.SetVector(Uniforms._DitheringCoords, new Vector4((float)context.width / (float)texture2D.width, (float)context.height / (float)texture2D.height, value, value2));
+ }
+}
diff --git a/UnityEngine.PostProcessing/DitheringModel.cs b/UnityEngine.PostProcessing/DitheringModel.cs
new file mode 100644
index 0000000..1258f2e
--- /dev/null
+++ b/UnityEngine.PostProcessing/DitheringModel.cs
@@ -0,0 +1,35 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace UnityEngine.PostProcessing;
+
+[Serializable]
+public class DitheringModel : PostProcessingModel
+{
+ [Serializable]
+ [StructLayout(LayoutKind.Sequential, Size = 1)]
+ public struct Settings
+ {
+ public static Settings defaultSettings => default(Settings);
+ }
+
+ [SerializeField]
+ private Settings m_Settings = Settings.defaultSettings;
+
+ public Settings settings
+ {
+ get
+ {
+ return m_Settings;
+ }
+ set
+ {
+ m_Settings = value;
+ }
+ }
+
+ public override void Reset()
+ {
+ m_Settings = Settings.defaultSettings;
+ }
+}
diff --git a/UnityEngine.PostProcessing/EyeAdaptationComponent.cs b/UnityEngine.PostProcessing/EyeAdaptationComponent.cs
new file mode 100644
index 0000000..fce1172
--- /dev/null
+++ b/UnityEngine.PostProcessing/EyeAdaptationComponent.cs
@@ -0,0 +1,168 @@
+namespace UnityEngine.PostProcessing;
+
+public sealed class EyeAdaptationComponent : PostProcessingComponentRenderTexture<EyeAdaptationModel>
+{
+ private static class Uniforms
+ {
+ internal static readonly int _Params = Shader.PropertyToID("_Params");
+
+ internal static readonly int _Speed = Shader.PropertyToID("_Speed");
+
+ internal static readonly int _ScaleOffsetRes = Shader.PropertyToID("_ScaleOffsetRes");
+
+ internal static readonly int _ExposureCompensation = Shader.PropertyToID("_ExposureCompensation");
+
+ internal static readonly int _AutoExposure = Shader.PropertyToID("_AutoExposure");
+
+ internal static readonly int _DebugWidth = Shader.PropertyToID("_DebugWidth");
+ }
+
+ private ComputeShader m_EyeCompute;
+
+ private ComputeBuffer m_HistogramBuffer;
+
+ private readonly RenderTexture[] m_AutoExposurePool = new RenderTexture[2];
+
+ private int m_AutoExposurePingPing;
+
+ private RenderTexture m_CurrentAutoExposure;
+
+ private RenderTexture m_DebugHistogram;
+
+ private static uint[] s_EmptyHistogramBuffer;
+
+ private bool m_FirstFrame = true;
+
+ private const int k_HistogramBins = 64;
+
+ private const int k_HistogramThreadX = 16;
+
+ private const int k_HistogramThreadY = 16;
+
+ public override bool active => base.model.enabled && SystemInfo.supportsComputeShaders && !context.interrupted;
+
+ public void ResetHistory()
+ {
+ m_FirstFrame = true;
+ }
+
+ public override void OnEnable()
+ {
+ m_FirstFrame = true;
+ }
+
+ public override void OnDisable()
+ {
+ RenderTexture[] autoExposurePool = m_AutoExposurePool;
+ foreach (RenderTexture obj in autoExposurePool)
+ {
+ GraphicsUtils.Destroy(obj);
+ }
+ if (m_HistogramBuffer != null)
+ {
+ m_HistogramBuffer.Release();
+ }
+ m_HistogramBuffer = null;
+ if (m_DebugHistogram != null)
+ {
+ m_DebugHistogram.Release();
+ }
+ m_DebugHistogram = null;
+ }
+
+ private Vector4 GetHistogramScaleOffsetRes()
+ {
+ EyeAdaptationModel.Settings settings = base.model.settings;
+ float num = settings.logMax - settings.logMin;
+ float num2 = 1f / num;
+ float y = (float)(-settings.logMin) * num2;
+ return new Vector4(num2, y, Mathf.Floor((float)context.width / 2f), Mathf.Floor((float)context.height / 2f));
+ }
+
+ public Texture Prepare(RenderTexture source, Material uberMaterial)
+ {
+ EyeAdaptationModel.Settings settings = base.model.settings;
+ if (m_EyeCompute == null)
+ {
+ m_EyeCompute = Resources.Load<ComputeShader>("Shaders/EyeHistogram");
+ }
+ Material material = context.materialFactory.Get("Hidden/Post FX/Eye Adaptation");
+ material.shaderKeywords = null;
+ if (m_HistogramBuffer == null)
+ {
+ m_HistogramBuffer = new ComputeBuffer(64, 4);
+ }
+ if (s_EmptyHistogramBuffer == null)
+ {
+ s_EmptyHistogramBuffer = new uint[64];
+ }
+ Vector4 histogramScaleOffsetRes = GetHistogramScaleOffsetRes();
+ RenderTexture renderTexture = context.renderTextureFactory.Get((int)histogramScaleOffsetRes.z, (int)histogramScaleOffsetRes.w, 0, source.format);
+ Graphics.Blit(source, renderTexture);
+ if (m_AutoExposurePool[0] == null || !m_AutoExposurePool[0].IsCreated())
+ {
+ m_AutoExposurePool[0] = new RenderTexture(1, 1, 0, RenderTextureFormat.RFloat);
+ }
+ if (m_AutoExposurePool[1] == null || !m_AutoExposurePool[1].IsCreated())
+ {
+ m_AutoExposurePool[1] = new RenderTexture(1, 1, 0, RenderTextureFormat.RFloat);
+ }
+ m_HistogramBuffer.SetData(s_EmptyHistogramBuffer);
+ int kernelIndex = m_EyeCompute.FindKernel("KEyeHistogram");
+ m_EyeCompute.SetBuffer(kernelIndex, "_Histogram", m_HistogramBuffer);
+ m_EyeCompute.SetTexture(kernelIndex, "_Source", renderTexture);
+ m_EyeCompute.SetVector("_ScaleOffsetRes", histogramScaleOffsetRes);
+ m_EyeCompute.Dispatch(kernelIndex, Mathf.CeilToInt((float)renderTexture.width / 16f), Mathf.CeilToInt((float)renderTexture.height / 16f), 1);
+ context.renderTextureFactory.Release(renderTexture);
+ settings.highPercent = Mathf.Clamp(settings.highPercent, 1.01f, 99f);
+ settings.lowPercent = Mathf.Clamp(settings.lowPercent, 1f, settings.highPercent - 0.01f);
+ material.SetBuffer("_Histogram", m_HistogramBuffer);
+ material.SetVector(Uniforms._Params, new Vector4(settings.lowPercent * 0.01f, settings.highPercent * 0.01f, Mathf.Exp(settings.minLuminance * 0.6931472f), Mathf.Exp(settings.maxLuminance * 0.6931472f)));
+ material.SetVector(Uniforms._Speed, new Vector2(settings.speedDown, settings.speedUp));
+ material.SetVector(Uniforms._ScaleOffsetRes, histogramScaleOffsetRes);
+ material.SetFloat(Uniforms._ExposureCompensation, settings.keyValue);
+ if (settings.dynamicKeyValue)
+ {
+ material.EnableKeyword("AUTO_KEY_VALUE");
+ }
+ if (m_FirstFrame || !Application.isPlaying)
+ {
+ m_CurrentAutoExposure = m_AutoExposurePool[0];
+ Graphics.Blit(null, m_CurrentAutoExposure, material, 1);
+ Graphics.Blit(m_AutoExposurePool[0], m_AutoExposurePool[1]);
+ }
+ else
+ {
+ int autoExposurePingPing = m_AutoExposurePingPing;
+ RenderTexture source2 = m_AutoExposurePool[++autoExposurePingPing % 2];
+ RenderTexture renderTexture2 = m_AutoExposurePool[++autoExposurePingPing % 2];
+ Graphics.Blit(source2, renderTexture2, material, (int)settings.adaptationType);
+ m_AutoExposurePingPing = ++autoExposurePingPing % 2;
+ m_CurrentAutoExposure = renderTexture2;
+ }
+ if (context.profile.debugViews.IsModeActive(BuiltinDebugViewsModel.Mode.EyeAdaptation))
+ {
+ if (m_DebugHistogram == null || !m_DebugHistogram.IsCreated())
+ {
+ m_DebugHistogram = new RenderTexture(256, 128, 0, RenderTextureFormat.ARGB32)
+ {
+ filterMode = FilterMode.Point,
+ wrapMode = TextureWrapMode.Clamp
+ };
+ }
+ material.SetFloat(Uniforms._DebugWidth, m_DebugHistogram.width);
+ Graphics.Blit(null, m_DebugHistogram, material, 2);
+ }
+ m_FirstFrame = false;
+ return m_CurrentAutoExposure;
+ }
+
+ public void OnGUI()
+ {
+ if (!(m_DebugHistogram == null) && m_DebugHistogram.IsCreated())
+ {
+ Rect position = new Rect(context.viewport.x * (float)Screen.width + 8f, 8f, m_DebugHistogram.width, m_DebugHistogram.height);
+ GUI.DrawTexture(position, m_DebugHistogram);
+ }
+ }
+}
diff --git a/UnityEngine.PostProcessing/EyeAdaptationModel.cs b/UnityEngine.PostProcessing/EyeAdaptationModel.cs
new file mode 100644
index 0000000..aab9a3d
--- /dev/null
+++ b/UnityEngine.PostProcessing/EyeAdaptationModel.cs
@@ -0,0 +1,97 @@
+using System;
+
+namespace UnityEngine.PostProcessing;
+
+[Serializable]
+public class EyeAdaptationModel : PostProcessingModel
+{
+ public enum EyeAdaptationType
+ {
+ Progressive,
+ Fixed
+ }
+
+ [Serializable]
+ public struct Settings
+ {
+ [Range(1f, 99f)]
+ [Tooltip("Filters the dark part of the histogram when computing the average luminance to avoid very dark pixels from contributing to the auto exposure. Unit is in percent.")]
+ public float lowPercent;
+
+ [Range(1f, 99f)]
+ [Tooltip("Filters the bright part of the histogram when computing the average luminance to avoid very dark pixels from contributing to the auto exposure. Unit is in percent.")]
+ public float highPercent;
+
+ [Tooltip("Minimum average luminance to consider for auto exposure (in EV).")]
+ public float minLuminance;
+
+ [Tooltip("Maximum average luminance to consider for auto exposure (in EV).")]
+ public float maxLuminance;
+
+ [Min(0f)]
+ [Tooltip("Exposure bias. Use this to offset the global exposure of the scene.")]
+ public float keyValue;
+
+ [Tooltip("Set this to true to let Unity handle the key value automatically based on average luminance.")]
+ public bool dynamicKeyValue;
+
+ [Tooltip("Use \"Progressive\" if you want the auto exposure to be animated. Use \"Fixed\" otherwise.")]
+ public EyeAdaptationType adaptationType;
+
+ [Min(0f)]
+ [Tooltip("Adaptation speed from a dark to a light environment.")]
+ public float speedUp;
+
+ [Min(0f)]
+ [Tooltip("Adaptation speed from a light to a dark environment.")]
+ public float speedDown;
+
+ [Range(-16f, -1f)]
+ [Tooltip("Lower bound for the brightness range of the generated histogram (in EV). The bigger the spread between min & max, the lower the precision will be.")]
+ public int logMin;
+
+ [Range(1f, 16f)]
+ [Tooltip("Upper bound for the brightness range of the generated histogram (in EV). The bigger the spread between min & max, the lower the precision will be.")]
+ public int logMax;
+
+ public static Settings defaultSettings
+ {
+ get
+ {
+ Settings result = default(Settings);
+ result.lowPercent = 45f;
+ result.highPercent = 95f;
+ result.minLuminance = -5f;
+ result.maxLuminance = 1f;
+ result.keyValue = 0.25f;
+ result.dynamicKeyValue = true;
+ result.adaptationType = EyeAdaptationType.Progressive;
+ result.speedUp = 2f;
+ result.speedDown = 1f;
+ result.logMin = -8;
+ result.logMax = 4;
+ return result;
+ }
+ }
+ }
+
+ [SerializeField]
+ private Settings m_Settings = Settings.defaultSettings;
+
+ public Settings settings
+ {
+ get
+ {
+ return m_Settings;
+ }
+ set
+ {
+ m_Settings = value;
+ }
+ }
+
+ public override void Reset()
+ {
+ m_Settings = Settings.defaultSettings;
+ }
+}
diff --git a/UnityEngine.PostProcessing/FogComponent.cs b/UnityEngine.PostProcessing/FogComponent.cs
new file mode 100644
index 0000000..387ec64
--- /dev/null
+++ b/UnityEngine.PostProcessing/FogComponent.cs
@@ -0,0 +1,67 @@
+using UnityEngine.Rendering;
+
+namespace UnityEngine.PostProcessing;
+
+public sealed class FogComponent : PostProcessingComponentCommandBuffer<FogModel>
+{
+ private static class Uniforms
+ {
+ internal static readonly int _FogColor = Shader.PropertyToID("_FogColor");
+
+ internal static readonly int _Density = Shader.PropertyToID("_Density");
+
+ internal static readonly int _Start = Shader.PropertyToID("_Start");
+
+ internal static readonly int _End = Shader.PropertyToID("_End");
+
+ internal static readonly int _TempRT = Shader.PropertyToID("_TempRT");
+ }
+
+ private const string k_ShaderString = "Hidden/Post FX/Fog";
+
+ public override bool active => base.model.enabled && context.isGBufferAvailable && RenderSettings.fog && !context.interrupted;
+
+ public override string GetName()
+ {
+ return "Fog";
+ }
+
+ public override DepthTextureMode GetCameraFlags()
+ {
+ return DepthTextureMode.Depth;
+ }
+
+ public override CameraEvent GetCameraEvent()
+ {
+ return CameraEvent.AfterImageEffectsOpaque;
+ }
+
+ public override void PopulateCommandBuffer(CommandBuffer cb)
+ {
+ FogModel.Settings settings = base.model.settings;
+ Material material = context.materialFactory.Get("Hidden/Post FX/Fog");
+ material.shaderKeywords = null;
+ Color value = ((!GraphicsUtils.isLinearColorSpace) ? RenderSettings.fogColor : RenderSettings.fogColor.linear);
+ material.SetColor(Uniforms._FogColor, value);
+ material.SetFloat(Uniforms._Density, RenderSettings.fogDensity);
+ material.SetFloat(Uniforms._Start, RenderSettings.fogStartDistance);
+ material.SetFloat(Uniforms._End, RenderSettings.fogEndDistance);
+ switch (RenderSettings.fogMode)
+ {
+ case FogMode.Linear:
+ material.EnableKeyword("FOG_LINEAR");
+ break;
+ case FogMode.Exponential:
+ material.EnableKeyword("FOG_EXP");
+ break;
+ case FogMode.ExponentialSquared:
+ material.EnableKeyword("FOG_EXP2");
+ break;
+ }
+ RenderTextureFormat format = ((!context.isHdr) ? RenderTextureFormat.Default : RenderTextureFormat.DefaultHDR);
+ cb.GetTemporaryRT(Uniforms._TempRT, context.width, context.height, 24, FilterMode.Bilinear, format);
+ cb.Blit(BuiltinRenderTextureType.CameraTarget, Uniforms._TempRT);
+ cb.Blit(Uniforms._TempRT, BuiltinRenderTextureType.CameraTarget, material, settings.excludeSkybox ? 1 : 0);
+ cb.ReleaseTemporaryRT(Uniforms._TempRT);
+ }
+}
diff --git a/UnityEngine.PostProcessing/FogModel.cs b/UnityEngine.PostProcessing/FogModel.cs
new file mode 100644
index 0000000..4a7f4cd
--- /dev/null
+++ b/UnityEngine.PostProcessing/FogModel.cs
@@ -0,0 +1,44 @@
+using System;
+
+namespace UnityEngine.PostProcessing;
+
+[Serializable]
+public class FogModel : PostProcessingModel
+{
+ [Serializable]
+ public struct Settings
+ {
+ [Tooltip("Should the fog affect the skybox?")]
+ public bool excludeSkybox;
+
+ public static Settings defaultSettings
+ {
+ get
+ {
+ Settings result = default(Settings);
+ result.excludeSkybox = true;
+ return result;
+ }
+ }
+ }
+
+ [SerializeField]
+ private Settings m_Settings = Settings.defaultSettings;
+
+ public Settings settings
+ {
+ get
+ {
+ return m_Settings;
+ }
+ set
+ {
+ m_Settings = value;
+ }
+ }
+
+ public override void Reset()
+ {
+ m_Settings = Settings.defaultSettings;
+ }
+}
diff --git a/UnityEngine.PostProcessing/FxaaComponent.cs b/UnityEngine.PostProcessing/FxaaComponent.cs
new file mode 100644
index 0000000..9d74204
--- /dev/null
+++ b/UnityEngine.PostProcessing/FxaaComponent.cs
@@ -0,0 +1,24 @@
+namespace UnityEngine.PostProcessing;
+
+public sealed class FxaaComponent : PostProcessingComponentRenderTexture<AntialiasingModel>
+{
+ private static class Uniforms
+ {
+ internal static readonly int _QualitySettings = Shader.PropertyToID("_QualitySettings");
+
+ internal static readonly int _ConsoleSettings = Shader.PropertyToID("_ConsoleSettings");
+ }
+
+ public override bool active => base.model.enabled && base.model.settings.method == AntialiasingModel.Method.Fxaa && !context.interrupted;
+
+ public void Render(RenderTexture source, RenderTexture destination)
+ {
+ AntialiasingModel.FxaaSettings fxaaSettings = base.model.settings.fxaaSettings;
+ Material material = context.materialFactory.Get("Hidden/Post FX/FXAA");
+ AntialiasingModel.FxaaQualitySettings fxaaQualitySettings = AntialiasingModel.FxaaQualitySettings.presets[(int)fxaaSettings.preset];
+ AntialiasingModel.FxaaConsoleSettings fxaaConsoleSettings = AntialiasingModel.FxaaConsoleSettings.presets[(int)fxaaSettings.preset];
+ material.SetVector(Uniforms._QualitySettings, new Vector3(fxaaQualitySettings.subpixelAliasingRemovalAmount, fxaaQualitySettings.edgeDetectionThreshold, fxaaQualitySettings.minimumRequiredLuminance));
+ material.SetVector(Uniforms._ConsoleSettings, new Vector4(fxaaConsoleSettings.subpixelSpreadAmount, fxaaConsoleSettings.edgeSharpnessAmount, fxaaConsoleSettings.edgeDetectionThreshold, fxaaConsoleSettings.minimumRequiredLuminance));
+ Graphics.Blit(source, destination, material, 0);
+ }
+}
diff --git a/UnityEngine.PostProcessing/GetSetAttribute.cs b/UnityEngine.PostProcessing/GetSetAttribute.cs
new file mode 100644
index 0000000..1b34e7d
--- /dev/null
+++ b/UnityEngine.PostProcessing/GetSetAttribute.cs
@@ -0,0 +1,13 @@
+namespace UnityEngine.PostProcessing;
+
+public sealed class GetSetAttribute : PropertyAttribute
+{
+ public readonly string name;
+
+ public bool dirty;
+
+ public GetSetAttribute(string name)
+ {
+ this.name = name;
+ }
+}
diff --git a/UnityEngine.PostProcessing/GrainComponent.cs b/UnityEngine.PostProcessing/GrainComponent.cs
new file mode 100644
index 0000000..c01dcda
--- /dev/null
+++ b/UnityEngine.PostProcessing/GrainComponent.cs
@@ -0,0 +1,52 @@
+namespace UnityEngine.PostProcessing;
+
+public sealed class GrainComponent : PostProcessingComponentRenderTexture<GrainModel>
+{
+ private static class Uniforms
+ {
+ internal static readonly int _Grain_Params1 = Shader.PropertyToID("_Grain_Params1");
+
+ internal static readonly int _Grain_Params2 = Shader.PropertyToID("_Grain_Params2");
+
+ internal static readonly int _GrainTex = Shader.PropertyToID("_GrainTex");
+
+ internal static readonly int _Phase = Shader.PropertyToID("_Phase");
+ }
+
+ private RenderTexture m_GrainLookupRT;
+
+ public override bool active => base.model.enabled && base.model.settings.intensity > 0f && SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.ARGBHalf) && !context.interrupted;
+
+ public override void OnDisable()
+ {
+ GraphicsUtils.Destroy(m_GrainLookupRT);
+ m_GrainLookupRT = null;
+ }
+
+ public override void Prepare(Material uberMaterial)
+ {
+ GrainModel.Settings settings = base.model.settings;
+ uberMaterial.EnableKeyword("GRAIN");
+ float realtimeSinceStartup = Time.realtimeSinceStartup;
+ float value = Random.value;
+ float value2 = Random.value;
+ if (m_GrainLookupRT == null || !m_GrainLookupRT.IsCreated())
+ {
+ GraphicsUtils.Destroy(m_GrainLookupRT);
+ m_GrainLookupRT = new RenderTexture(192, 192, 0, RenderTextureFormat.ARGBHalf)
+ {
+ filterMode = FilterMode.Bilinear,
+ wrapMode = TextureWrapMode.Repeat,
+ anisoLevel = 0,
+ name = "Grain Lookup Texture"
+ };
+ m_GrainLookupRT.Create();
+ }
+ Material material = context.materialFactory.Get("Hidden/Post FX/Grain Generator");
+ material.SetFloat(Uniforms._Phase, realtimeSinceStartup / 20f);
+ Graphics.Blit(null, m_GrainLookupRT, material, settings.colored ? 1 : 0);
+ uberMaterial.SetTexture(Uniforms._GrainTex, m_GrainLookupRT);
+ uberMaterial.SetVector(Uniforms._Grain_Params1, new Vector2(settings.luminanceContribution, settings.intensity * 20f));
+ uberMaterial.SetVector(Uniforms._Grain_Params2, new Vector4((float)context.width / (float)m_GrainLookupRT.width / settings.size, (float)context.height / (float)m_GrainLookupRT.height / settings.size, value, value2));
+ }
+}
diff --git a/UnityEngine.PostProcessing/GrainModel.cs b/UnityEngine.PostProcessing/GrainModel.cs
new file mode 100644
index 0000000..20ca694
--- /dev/null
+++ b/UnityEngine.PostProcessing/GrainModel.cs
@@ -0,0 +1,59 @@
+using System;
+
+namespace UnityEngine.PostProcessing;
+
+[Serializable]
+public class GrainModel : PostProcessingModel
+{
+ [Serializable]
+ public struct Settings
+ {
+ [Tooltip("Enable the use of colored grain.")]
+ public bool colored;
+
+ [Range(0f, 1f)]
+ [Tooltip("Grain strength. Higher means more visible grain.")]
+ public float intensity;
+
+ [Range(0.3f, 3f)]
+ [Tooltip("Grain particle size.")]
+ public float size;
+
+ [Range(0f, 1f)]
+ [Tooltip("Controls the noisiness response curve based on scene luminance. Lower values mean less noise in dark areas.")]
+ public float luminanceContribution;
+
+ public static Settings defaultSettings
+ {
+ get
+ {
+ Settings result = default(Settings);
+ result.colored = true;
+ result.intensity = 0.5f;
+ result.size = 1f;
+ result.luminanceContribution = 0.8f;
+ return result;
+ }
+ }
+ }
+
+ [SerializeField]
+ private Settings m_Settings = Settings.defaultSettings;
+
+ public Settings settings
+ {
+ get
+ {
+ return m_Settings;
+ }
+ set
+ {
+ m_Settings = value;
+ }
+ }
+
+ public override void Reset()
+ {
+ m_Settings = Settings.defaultSettings;
+ }
+}
diff --git a/UnityEngine.PostProcessing/GraphicsUtils.cs b/UnityEngine.PostProcessing/GraphicsUtils.cs
new file mode 100644
index 0000000..9062c77
--- /dev/null
+++ b/UnityEngine.PostProcessing/GraphicsUtils.cs
@@ -0,0 +1,115 @@
+namespace UnityEngine.PostProcessing;
+
+public static class GraphicsUtils
+{
+ private static Texture2D s_WhiteTexture;
+
+ private static Mesh s_Quad;
+
+ public static bool isLinearColorSpace => QualitySettings.activeColorSpace == ColorSpace.Linear;
+
+ public static bool supportsDX11 => SystemInfo.graphicsShaderLevel >= 50 && SystemInfo.supportsComputeShaders;
+
+ public static Texture2D whiteTexture
+ {
+ get
+ {
+ if (s_WhiteTexture != null)
+ {
+ return s_WhiteTexture;
+ }
+ s_WhiteTexture = new Texture2D(1, 1, TextureFormat.ARGB32, mipmap: false);
+ s_WhiteTexture.SetPixel(0, 0, new Color(1f, 1f, 1f, 1f));
+ s_WhiteTexture.Apply();
+ return s_WhiteTexture;
+ }
+ }
+
+ public static Mesh quad
+ {
+ get
+ {
+ if (s_Quad != null)
+ {
+ return s_Quad;
+ }
+ Vector3[] vertices = new Vector3[4]
+ {
+ new Vector3(-1f, -1f, 0f),
+ new Vector3(1f, 1f, 0f),
+ new Vector3(1f, -1f, 0f),
+ new Vector3(-1f, 1f, 0f)
+ };
+ Vector2[] uv = new Vector2[4]
+ {
+ new Vector2(0f, 0f),
+ new Vector2(1f, 1f),
+ new Vector2(1f, 0f),
+ new Vector2(0f, 1f)
+ };
+ int[] triangles = new int[6] { 0, 1, 2, 1, 0, 3 };
+ Mesh mesh = new Mesh();
+ mesh.vertices = vertices;
+ mesh.uv = uv;
+ mesh.triangles = triangles;
+ s_Quad = mesh;
+ s_Quad.RecalculateNormals();
+ s_Quad.RecalculateBounds();
+ return s_Quad;
+ }
+ }
+
+ public static void Blit(Material material, int pass)
+ {
+ GL.PushMatrix();
+ GL.LoadOrtho();
+ material.SetPass(pass);
+ GL.Begin(5);
+ GL.TexCoord2(0f, 0f);
+ GL.Vertex3(0f, 0f, 0.1f);
+ GL.TexCoord2(1f, 0f);
+ GL.Vertex3(1f, 0f, 0.1f);
+ GL.TexCoord2(0f, 1f);
+ GL.Vertex3(0f, 1f, 0.1f);
+ GL.TexCoord2(1f, 1f);
+ GL.Vertex3(1f, 1f, 0.1f);
+ GL.End();
+ GL.PopMatrix();
+ }
+
+ public static void ClearAndBlit(Texture source, RenderTexture destination, Material material, int pass, bool clearColor = true, bool clearDepth = false)
+ {
+ RenderTexture active = RenderTexture.active;
+ RenderTexture.active = destination;
+ GL.Clear(clearDepth: false, clearColor, Color.clear);
+ GL.PushMatrix();
+ GL.LoadOrtho();
+ material.SetTexture("_MainTex", source);
+ material.SetPass(pass);
+ GL.Begin(5);
+ GL.TexCoord2(0f, 0f);
+ GL.Vertex3(0f, 0f, 0.1f);
+ GL.TexCoord2(1f, 0f);
+ GL.Vertex3(1f, 0f, 0.1f);
+ GL.TexCoord2(0f, 1f);
+ GL.Vertex3(0f, 1f, 0.1f);
+ GL.TexCoord2(1f, 1f);
+ GL.Vertex3(1f, 1f, 0.1f);
+ GL.End();
+ GL.PopMatrix();
+ RenderTexture.active = active;
+ }
+
+ public static void Destroy(Object obj)
+ {
+ if (obj != null)
+ {
+ Object.Destroy(obj);
+ }
+ }
+
+ public static void Dispose()
+ {
+ Destroy(s_Quad);
+ }
+}
diff --git a/UnityEngine.PostProcessing/MaterialFactory.cs b/UnityEngine.PostProcessing/MaterialFactory.cs
new file mode 100644
index 0000000..dbbed34
--- /dev/null
+++ b/UnityEngine.PostProcessing/MaterialFactory.cs
@@ -0,0 +1,43 @@
+using System;
+using System.Collections.Generic;
+
+namespace UnityEngine.PostProcessing;
+
+public sealed class MaterialFactory : IDisposable
+{
+ private Dictionary<string, Material> m_Materials;
+
+ public MaterialFactory()
+ {
+ m_Materials = new Dictionary<string, Material>();
+ }
+
+ public Material Get(string shaderName)
+ {
+ if (!m_Materials.TryGetValue(shaderName, out var value))
+ {
+ Shader shader = Shader.Find(shaderName);
+ if (shader == null)
+ {
+ throw new ArgumentException($"Shader not found ({shaderName})");
+ }
+ Material material = new Material(shader);
+ material.name = string.Format("PostFX - {0}", shaderName.Substring(shaderName.LastIndexOf("/") + 1));
+ material.hideFlags = HideFlags.DontSave;
+ value = material;
+ m_Materials.Add(shaderName, value);
+ }
+ return value;
+ }
+
+ public void Dispose()
+ {
+ Dictionary<string, Material>.Enumerator enumerator = m_Materials.GetEnumerator();
+ while (enumerator.MoveNext())
+ {
+ Material value = enumerator.Current.Value;
+ GraphicsUtils.Destroy(value);
+ }
+ m_Materials.Clear();
+ }
+}
diff --git a/UnityEngine.PostProcessing/MinAttribute.cs b/UnityEngine.PostProcessing/MinAttribute.cs
new file mode 100644
index 0000000..cc991ef
--- /dev/null
+++ b/UnityEngine.PostProcessing/MinAttribute.cs
@@ -0,0 +1,11 @@
+namespace UnityEngine.PostProcessing;
+
+public sealed class MinAttribute : PropertyAttribute
+{
+ public readonly float min;
+
+ public MinAttribute(float min)
+ {
+ this.min = min;
+ }
+}
diff --git a/UnityEngine.PostProcessing/MotionBlurComponent.cs b/UnityEngine.PostProcessing/MotionBlurComponent.cs
new file mode 100644
index 0000000..59199e1
--- /dev/null
+++ b/UnityEngine.PostProcessing/MotionBlurComponent.cs
@@ -0,0 +1,421 @@
+using UnityEngine.Rendering;
+
+namespace UnityEngine.PostProcessing;
+
+public sealed class MotionBlurComponent : PostProcessingComponentCommandBuffer<MotionBlurModel>
+{
+ private static class Uniforms
+ {
+ internal static readonly int _VelocityScale = Shader.PropertyToID("_VelocityScale");
+
+ internal static readonly int _MaxBlurRadius = Shader.PropertyToID("_MaxBlurRadius");
+
+ internal static readonly int _RcpMaxBlurRadius = Shader.PropertyToID("_RcpMaxBlurRadius");
+
+ internal static readonly int _VelocityTex = Shader.PropertyToID("_VelocityTex");
+
+ internal static readonly int _MainTex = Shader.PropertyToID("_MainTex");
+
+ internal static readonly int _Tile2RT = Shader.PropertyToID("_Tile2RT");
+
+ internal static readonly int _Tile4RT = Shader.PropertyToID("_Tile4RT");
+
+ internal static readonly int _Tile8RT = Shader.PropertyToID("_Tile8RT");
+
+ internal static readonly int _TileMaxOffs = Shader.PropertyToID("_TileMaxOffs");
+
+ internal static readonly int _TileMaxLoop = Shader.PropertyToID("_TileMaxLoop");
+
+ internal static readonly int _TileVRT = Shader.PropertyToID("_TileVRT");
+
+ internal static readonly int _NeighborMaxTex = Shader.PropertyToID("_NeighborMaxTex");
+
+ internal static readonly int _LoopCount = Shader.PropertyToID("_LoopCount");
+
+ internal static readonly int _TempRT = Shader.PropertyToID("_TempRT");
+
+ internal static readonly int _History1LumaTex = Shader.PropertyToID("_History1LumaTex");
+
+ internal static readonly int _History2LumaTex = Shader.PropertyToID("_History2LumaTex");
+
+ internal static readonly int _History3LumaTex = Shader.PropertyToID("_History3LumaTex");
+
+ internal static readonly int _History4LumaTex = Shader.PropertyToID("_History4LumaTex");
+
+ internal static readonly int _History1ChromaTex = Shader.PropertyToID("_History1ChromaTex");
+
+ internal static readonly int _History2ChromaTex = Shader.PropertyToID("_History2ChromaTex");
+
+ internal static readonly int _History3ChromaTex = Shader.PropertyToID("_History3ChromaTex");
+
+ internal static readonly int _History4ChromaTex = Shader.PropertyToID("_History4ChromaTex");
+
+ internal static readonly int _History1Weight = Shader.PropertyToID("_History1Weight");
+
+ internal static readonly int _History2Weight = Shader.PropertyToID("_History2Weight");
+
+ internal static readonly int _History3Weight = Shader.PropertyToID("_History3Weight");
+
+ internal static readonly int _History4Weight = Shader.PropertyToID("_History4Weight");
+ }
+
+ private enum Pass
+ {
+ VelocitySetup,
+ TileMax1,
+ TileMax2,
+ TileMaxV,
+ NeighborMax,
+ Reconstruction,
+ FrameCompression,
+ FrameBlendingChroma,
+ FrameBlendingRaw
+ }
+
+ public class ReconstructionFilter
+ {
+ private RenderTextureFormat m_VectorRTFormat = RenderTextureFormat.RGHalf;
+
+ private RenderTextureFormat m_PackedRTFormat = RenderTextureFormat.ARGB2101010;
+
+ public ReconstructionFilter()
+ {
+ CheckTextureFormatSupport();
+ }
+
+ private void CheckTextureFormatSupport()
+ {
+ if (!SystemInfo.SupportsRenderTextureFormat(m_PackedRTFormat))
+ {
+ m_PackedRTFormat = RenderTextureFormat.ARGB32;
+ }
+ }
+
+ public bool IsSupported()
+ {
+ return SystemInfo.supportsMotionVectors;
+ }
+
+ public void ProcessImage(PostProcessingContext context, CommandBuffer cb, ref MotionBlurModel.Settings settings, RenderTargetIdentifier source, RenderTargetIdentifier destination, Material material)
+ {
+ int num = (int)(5f * (float)context.height / 100f);
+ int num2 = ((num - 1) / 8 + 1) * 8;
+ float value = settings.shutterAngle / 360f;
+ cb.SetGlobalFloat(Uniforms._VelocityScale, value);
+ cb.SetGlobalFloat(Uniforms._MaxBlurRadius, num);
+ cb.SetGlobalFloat(Uniforms._RcpMaxBlurRadius, 1f / (float)num);
+ int velocityTex = Uniforms._VelocityTex;
+ cb.GetTemporaryRT(velocityTex, context.width, context.height, 0, FilterMode.Point, m_PackedRTFormat, RenderTextureReadWrite.Linear);
+ cb.Blit(null, velocityTex, material, 0);
+ int tile2RT = Uniforms._Tile2RT;
+ cb.GetTemporaryRT(tile2RT, context.width / 2, context.height / 2, 0, FilterMode.Point, m_VectorRTFormat, RenderTextureReadWrite.Linear);
+ cb.SetGlobalTexture(Uniforms._MainTex, velocityTex);
+ cb.Blit(velocityTex, tile2RT, material, 1);
+ int tile4RT = Uniforms._Tile4RT;
+ cb.GetTemporaryRT(tile4RT, context.width / 4, context.height / 4, 0, FilterMode.Point, m_VectorRTFormat, RenderTextureReadWrite.Linear);
+ cb.SetGlobalTexture(Uniforms._MainTex, tile2RT);
+ cb.Blit(tile2RT, tile4RT, material, 2);
+ cb.ReleaseTemporaryRT(tile2RT);
+ int tile8RT = Uniforms._Tile8RT;
+ cb.GetTemporaryRT(tile8RT, context.width / 8, context.height / 8, 0, FilterMode.Point, m_VectorRTFormat, RenderTextureReadWrite.Linear);
+ cb.SetGlobalTexture(Uniforms._MainTex, tile4RT);
+ cb.Blit(tile4RT, tile8RT, material, 2);
+ cb.ReleaseTemporaryRT(tile4RT);
+ Vector2 vector = Vector2.one * ((float)num2 / 8f - 1f) * -0.5f;
+ cb.SetGlobalVector(Uniforms._TileMaxOffs, vector);
+ cb.SetGlobalFloat(Uniforms._TileMaxLoop, (int)((float)num2 / 8f));
+ int tileVRT = Uniforms._TileVRT;
+ cb.GetTemporaryRT(tileVRT, context.width / num2, context.height / num2, 0, FilterMode.Point, m_VectorRTFormat, RenderTextureReadWrite.Linear);
+ cb.SetGlobalTexture(Uniforms._MainTex, tile8RT);
+ cb.Blit(tile8RT, tileVRT, material, 3);
+ cb.ReleaseTemporaryRT(tile8RT);
+ int neighborMaxTex = Uniforms._NeighborMaxTex;
+ int width = context.width / num2;
+ int height = context.height / num2;
+ cb.GetTemporaryRT(neighborMaxTex, width, height, 0, FilterMode.Point, m_VectorRTFormat, RenderTextureReadWrite.Linear);
+ cb.SetGlobalTexture(Uniforms._MainTex, tileVRT);
+ cb.Blit(tileVRT, neighborMaxTex, material, 4);
+ cb.ReleaseTemporaryRT(tileVRT);
+ cb.SetGlobalFloat(Uniforms._LoopCount, Mathf.Clamp(settings.sampleCount / 2, 1, 64));
+ cb.SetGlobalTexture(Uniforms._MainTex, source);
+ cb.Blit(source, destination, material, 5);
+ cb.ReleaseTemporaryRT(velocityTex);
+ cb.ReleaseTemporaryRT(neighborMaxTex);
+ }
+ }
+
+ public class FrameBlendingFilter
+ {
+ private struct Frame
+ {
+ public RenderTexture lumaTexture;
+
+ public RenderTexture chromaTexture;
+
+ private float m_Time;
+
+ private RenderTargetIdentifier[] m_MRT;
+
+ public float CalculateWeight(float strength, float currentTime)
+ {
+ if (Mathf.Approximately(m_Time, 0f))
+ {
+ return 0f;
+ }
+ float num = Mathf.Lerp(80f, 16f, strength);
+ return Mathf.Exp((m_Time - currentTime) * num);
+ }
+
+ public void Release()
+ {
+ if (lumaTexture != null)
+ {
+ RenderTexture.ReleaseTemporary(lumaTexture);
+ }
+ if (chromaTexture != null)
+ {
+ RenderTexture.ReleaseTemporary(chromaTexture);
+ }
+ lumaTexture = null;
+ chromaTexture = null;
+ }
+
+ public void MakeRecord(CommandBuffer cb, RenderTargetIdentifier source, int width, int height, Material material)
+ {
+ Release();
+ lumaTexture = RenderTexture.GetTemporary(width, height, 0, RenderTextureFormat.R8, RenderTextureReadWrite.Linear);
+ chromaTexture = RenderTexture.GetTemporary(width, height, 0, RenderTextureFormat.R8, RenderTextureReadWrite.Linear);
+ lumaTexture.filterMode = FilterMode.Point;
+ chromaTexture.filterMode = FilterMode.Point;
+ if (m_MRT == null)
+ {
+ m_MRT = new RenderTargetIdentifier[2];
+ }
+ ref RenderTargetIdentifier reference = ref m_MRT[0];
+ reference = lumaTexture;
+ ref RenderTargetIdentifier reference2 = ref m_MRT[1];
+ reference2 = chromaTexture;
+ cb.SetGlobalTexture(Uniforms._MainTex, source);
+ cb.SetRenderTarget(m_MRT, lumaTexture);
+ cb.DrawMesh(GraphicsUtils.quad, Matrix4x4.identity, material, 0, 6);
+ m_Time = Time.time;
+ }
+
+ public void MakeRecordRaw(CommandBuffer cb, RenderTargetIdentifier source, int width, int height, RenderTextureFormat format)
+ {
+ Release();
+ lumaTexture = RenderTexture.GetTemporary(width, height, 0, format);
+ lumaTexture.filterMode = FilterMode.Point;
+ cb.SetGlobalTexture(Uniforms._MainTex, source);
+ cb.Blit(source, lumaTexture);
+ m_Time = Time.time;
+ }
+ }
+
+ private bool m_UseCompression;
+
+ private RenderTextureFormat m_RawTextureFormat;
+
+ private Frame[] m_FrameList;
+
+ private int m_LastFrameCount;
+
+ public FrameBlendingFilter()
+ {
+ m_UseCompression = CheckSupportCompression();
+ m_RawTextureFormat = GetPreferredRenderTextureFormat();
+ m_FrameList = new Frame[4];
+ }
+
+ public void Dispose()
+ {
+ Frame[] frameList = m_FrameList;
+ foreach (Frame frame in frameList)
+ {
+ frame.Release();
+ }
+ }
+
+ public void PushFrame(CommandBuffer cb, RenderTargetIdentifier source, int width, int height, Material material)
+ {
+ int frameCount = Time.frameCount;
+ if (frameCount != m_LastFrameCount)
+ {
+ int num = frameCount % m_FrameList.Length;
+ if (m_UseCompression)
+ {
+ m_FrameList[num].MakeRecord(cb, source, width, height, material);
+ }
+ else
+ {
+ m_FrameList[num].MakeRecordRaw(cb, source, width, height, m_RawTextureFormat);
+ }
+ m_LastFrameCount = frameCount;
+ }
+ }
+
+ public void BlendFrames(CommandBuffer cb, float strength, RenderTargetIdentifier source, RenderTargetIdentifier destination, Material material)
+ {
+ float time = Time.time;
+ Frame frameRelative = GetFrameRelative(-1);
+ Frame frameRelative2 = GetFrameRelative(-2);
+ Frame frameRelative3 = GetFrameRelative(-3);
+ Frame frameRelative4 = GetFrameRelative(-4);
+ cb.SetGlobalTexture(Uniforms._History1LumaTex, frameRelative.lumaTexture);
+ cb.SetGlobalTexture(Uniforms._History2LumaTex, frameRelative2.lumaTexture);
+ cb.SetGlobalTexture(Uniforms._History3LumaTex, frameRelative3.lumaTexture);
+ cb.SetGlobalTexture(Uniforms._History4LumaTex, frameRelative4.lumaTexture);
+ cb.SetGlobalTexture(Uniforms._History1ChromaTex, frameRelative.chromaTexture);
+ cb.SetGlobalTexture(Uniforms._History2ChromaTex, frameRelative2.chromaTexture);
+ cb.SetGlobalTexture(Uniforms._History3ChromaTex, frameRelative3.chromaTexture);
+ cb.SetGlobalTexture(Uniforms._History4ChromaTex, frameRelative4.chromaTexture);
+ cb.SetGlobalFloat(Uniforms._History1Weight, frameRelative.CalculateWeight(strength, time));
+ cb.SetGlobalFloat(Uniforms._History2Weight, frameRelative2.CalculateWeight(strength, time));
+ cb.SetGlobalFloat(Uniforms._History3Weight, frameRelative3.CalculateWeight(strength, time));
+ cb.SetGlobalFloat(Uniforms._History4Weight, frameRelative4.CalculateWeight(strength, time));
+ cb.SetGlobalTexture(Uniforms._MainTex, source);
+ cb.Blit(source, destination, material, (!m_UseCompression) ? 8 : 7);
+ }
+
+ private static bool CheckSupportCompression()
+ {
+ return SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.R8) && SystemInfo.supportedRenderTargetCount > 1;
+ }
+
+ private static RenderTextureFormat GetPreferredRenderTextureFormat()
+ {
+ RenderTextureFormat[] array = new RenderTextureFormat[3]
+ {
+ RenderTextureFormat.RGB565,
+ RenderTextureFormat.ARGB1555,
+ RenderTextureFormat.ARGB4444
+ };
+ RenderTextureFormat[] array2 = array;
+ foreach (RenderTextureFormat renderTextureFormat in array2)
+ {
+ if (SystemInfo.SupportsRenderTextureFormat(renderTextureFormat))
+ {
+ return renderTextureFormat;
+ }
+ }
+ return RenderTextureFormat.Default;
+ }
+
+ private Frame GetFrameRelative(int offset)
+ {
+ int num = (Time.frameCount + m_FrameList.Length + offset) % m_FrameList.Length;
+ return m_FrameList[num];
+ }
+ }
+
+ private ReconstructionFilter m_ReconstructionFilter;
+
+ private FrameBlendingFilter m_FrameBlendingFilter;
+
+ private bool m_FirstFrame = true;
+
+ public ReconstructionFilter reconstructionFilter
+ {
+ get
+ {
+ if (m_ReconstructionFilter == null)
+ {
+ m_ReconstructionFilter = new ReconstructionFilter();
+ }
+ return m_ReconstructionFilter;
+ }
+ }
+
+ public FrameBlendingFilter frameBlendingFilter
+ {
+ get
+ {
+ if (m_FrameBlendingFilter == null)
+ {
+ m_FrameBlendingFilter = new FrameBlendingFilter();
+ }
+ return m_FrameBlendingFilter;
+ }
+ }
+
+ public override bool active
+ {
+ get
+ {
+ MotionBlurModel.Settings settings = base.model.settings;
+ return base.model.enabled && ((settings.shutterAngle > 0f && reconstructionFilter.IsSupported()) || settings.frameBlending > 0f) && SystemInfo.graphicsDeviceType != GraphicsDeviceType.OpenGLES2 && !context.interrupted;
+ }
+ }
+
+ public override string GetName()
+ {
+ return "Motion Blur";
+ }
+
+ public void ResetHistory()
+ {
+ if (m_FrameBlendingFilter != null)
+ {
+ m_FrameBlendingFilter.Dispose();
+ }
+ m_FrameBlendingFilter = null;
+ }
+
+ public override DepthTextureMode GetCameraFlags()
+ {
+ return DepthTextureMode.Depth | DepthTextureMode.MotionVectors;
+ }
+
+ public override CameraEvent GetCameraEvent()
+ {
+ return CameraEvent.BeforeImageEffects;
+ }
+
+ public override void OnEnable()
+ {
+ m_FirstFrame = true;
+ }
+
+ public override void PopulateCommandBuffer(CommandBuffer cb)
+ {
+ if (m_FirstFrame)
+ {
+ m_FirstFrame = false;
+ return;
+ }
+ Material material = context.materialFactory.Get("Hidden/Post FX/Motion Blur");
+ Material mat = context.materialFactory.Get("Hidden/Post FX/Blit");
+ MotionBlurModel.Settings settings = base.model.settings;
+ RenderTextureFormat format = ((!context.isHdr) ? RenderTextureFormat.Default : RenderTextureFormat.DefaultHDR);
+ int tempRT = Uniforms._TempRT;
+ cb.GetTemporaryRT(tempRT, context.width, context.height, 0, FilterMode.Point, format);
+ if (settings.shutterAngle > 0f && settings.frameBlending > 0f)
+ {
+ reconstructionFilter.ProcessImage(context, cb, ref settings, BuiltinRenderTextureType.CameraTarget, tempRT, material);
+ frameBlendingFilter.BlendFrames(cb, settings.frameBlending, tempRT, BuiltinRenderTextureType.CameraTarget, material);
+ frameBlendingFilter.PushFrame(cb, tempRT, context.width, context.height, material);
+ }
+ else if (settings.shutterAngle > 0f)
+ {
+ cb.SetGlobalTexture(Uniforms._MainTex, BuiltinRenderTextureType.CameraTarget);
+ cb.Blit(BuiltinRenderTextureType.CameraTarget, tempRT, mat, 0);
+ reconstructionFilter.ProcessImage(context, cb, ref settings, tempRT, BuiltinRenderTextureType.CameraTarget, material);
+ }
+ else if (settings.frameBlending > 0f)
+ {
+ cb.SetGlobalTexture(Uniforms._MainTex, BuiltinRenderTextureType.CameraTarget);
+ cb.Blit(BuiltinRenderTextureType.CameraTarget, tempRT, mat, 0);
+ frameBlendingFilter.BlendFrames(cb, settings.frameBlending, tempRT, BuiltinRenderTextureType.CameraTarget, material);
+ frameBlendingFilter.PushFrame(cb, tempRT, context.width, context.height, material);
+ }
+ cb.ReleaseTemporaryRT(tempRT);
+ }
+
+ public override void OnDisable()
+ {
+ if (m_FrameBlendingFilter != null)
+ {
+ m_FrameBlendingFilter.Dispose();
+ }
+ }
+}
diff --git a/UnityEngine.PostProcessing/MotionBlurModel.cs b/UnityEngine.PostProcessing/MotionBlurModel.cs
new file mode 100644
index 0000000..5b0a996
--- /dev/null
+++ b/UnityEngine.PostProcessing/MotionBlurModel.cs
@@ -0,0 +1,55 @@
+using System;
+
+namespace UnityEngine.PostProcessing;
+
+[Serializable]
+public class MotionBlurModel : PostProcessingModel
+{
+ [Serializable]
+ public struct Settings
+ {
+ [Range(0f, 360f)]
+ [Tooltip("The angle of rotary shutter. Larger values give longer exposure.")]
+ public float shutterAngle;
+
+ [Range(4f, 32f)]
+ [Tooltip("The amount of sample points, which affects quality and performances.")]
+ public int sampleCount;
+
+ [Range(0f, 1f)]
+ [Tooltip("The strength of multiple frame blending. The opacity of preceding frames are determined from this coefficient and time differences.")]
+ public float frameBlending;
+
+ public static Settings defaultSettings
+ {
+ get
+ {
+ Settings result = default(Settings);
+ result.shutterAngle = 270f;
+ result.sampleCount = 10;
+ result.frameBlending = 0f;
+ return result;
+ }
+ }
+ }
+
+ [SerializeField]
+ private Settings m_Settings = Settings.defaultSettings;
+
+ public Settings settings
+ {
+ get
+ {
+ return m_Settings;
+ }
+ set
+ {
+ m_Settings = value;
+ }
+ }
+
+ public override void Reset()
+ {
+ m_Settings = Settings.defaultSettings;
+ }
+}
diff --git a/UnityEngine.PostProcessing/PostProcessingBehaviour.cs b/UnityEngine.PostProcessing/PostProcessingBehaviour.cs
new file mode 100644
index 0000000..d99d027
--- /dev/null
+++ b/UnityEngine.PostProcessing/PostProcessingBehaviour.cs
@@ -0,0 +1,405 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine.Rendering;
+
+namespace UnityEngine.PostProcessing;
+
+[ImageEffectAllowedInSceneView]
+[RequireComponent(typeof(Camera))]
+[DisallowMultipleComponent]
+[ExecuteInEditMode]
+[AddComponentMenu("Effects/Post-Processing Behaviour", -1)]
+public class PostProcessingBehaviour : MonoBehaviour
+{
+ public PostProcessingProfile profile;
+
+ public Func<Vector2, Matrix4x4> jitteredMatrixFunc;
+
+ private Dictionary<Type, KeyValuePair<CameraEvent, CommandBuffer>> m_CommandBuffers;
+
+ private List<PostProcessingComponentBase> m_Components;
+
+ private Dictionary<PostProcessingComponentBase, bool> m_ComponentStates;
+
+ private MaterialFactory m_MaterialFactory;
+
+ private RenderTextureFactory m_RenderTextureFactory;
+
+ private PostProcessingContext m_Context;
+
+ private Camera m_Camera;
+
+ private PostProcessingProfile m_PreviousProfile;
+
+ private bool m_RenderingInSceneView;
+
+ private BuiltinDebugViewsComponent m_DebugViews;
+
+ private AmbientOcclusionComponent m_AmbientOcclusion;
+
+ private ScreenSpaceReflectionComponent m_ScreenSpaceReflection;
+
+ private FogComponent m_FogComponent;
+
+ private MotionBlurComponent m_MotionBlur;
+
+ private TaaComponent m_Taa;
+
+ private EyeAdaptationComponent m_EyeAdaptation;
+
+ private DepthOfFieldComponent m_DepthOfField;
+
+ private BloomComponent m_Bloom;
+
+ private ChromaticAberrationComponent m_ChromaticAberration;
+
+ private ColorGradingComponent m_ColorGrading;
+
+ private UserLutComponent m_UserLut;
+
+ private GrainComponent m_Grain;
+
+ private VignetteComponent m_Vignette;
+
+ private DitheringComponent m_Dithering;
+
+ private FxaaComponent m_Fxaa;
+
+ private List<PostProcessingComponentBase> m_ComponentsToEnable = new List<PostProcessingComponentBase>();
+
+ private List<PostProcessingComponentBase> m_ComponentsToDisable = new List<PostProcessingComponentBase>();
+
+ private void OnEnable()
+ {
+ m_CommandBuffers = new Dictionary<Type, KeyValuePair<CameraEvent, CommandBuffer>>();
+ m_MaterialFactory = new MaterialFactory();
+ m_RenderTextureFactory = new RenderTextureFactory();
+ m_Context = new PostProcessingContext();
+ m_Components = new List<PostProcessingComponentBase>();
+ m_DebugViews = AddComponent(new BuiltinDebugViewsComponent());
+ m_AmbientOcclusion = AddComponent(new AmbientOcclusionComponent());
+ m_ScreenSpaceReflection = AddComponent(new ScreenSpaceReflectionComponent());
+ m_FogComponent = AddComponent(new FogComponent());
+ m_MotionBlur = AddComponent(new MotionBlurComponent());
+ m_Taa = AddComponent(new TaaComponent());
+ m_EyeAdaptation = AddComponent(new EyeAdaptationComponent());
+ m_DepthOfField = AddComponent(new DepthOfFieldComponent());
+ m_Bloom = AddComponent(new BloomComponent());
+ m_ChromaticAberration = AddComponent(new ChromaticAberrationComponent());
+ m_ColorGrading = AddComponent(new ColorGradingComponent());
+ m_UserLut = AddComponent(new UserLutComponent());
+ m_Grain = AddComponent(new GrainComponent());
+ m_Vignette = AddComponent(new VignetteComponent());
+ m_Dithering = AddComponent(new DitheringComponent());
+ m_Fxaa = AddComponent(new FxaaComponent());
+ m_ComponentStates = new Dictionary<PostProcessingComponentBase, bool>();
+ foreach (PostProcessingComponentBase component in m_Components)
+ {
+ m_ComponentStates.Add(component, value: false);
+ }
+ base.useGUILayout = false;
+ }
+
+ private void OnPreCull()
+ {
+ m_Camera = GetComponent<Camera>();
+ if (profile == null || m_Camera == null)
+ {
+ return;
+ }
+ PostProcessingContext postProcessingContext = m_Context.Reset();
+ postProcessingContext.profile = profile;
+ postProcessingContext.renderTextureFactory = m_RenderTextureFactory;
+ postProcessingContext.materialFactory = m_MaterialFactory;
+ postProcessingContext.camera = m_Camera;
+ m_DebugViews.Init(postProcessingContext, profile.debugViews);
+ m_AmbientOcclusion.Init(postProcessingContext, profile.ambientOcclusion);
+ m_ScreenSpaceReflection.Init(postProcessingContext, profile.screenSpaceReflection);
+ m_FogComponent.Init(postProcessingContext, profile.fog);
+ m_MotionBlur.Init(postProcessingContext, profile.motionBlur);
+ m_Taa.Init(postProcessingContext, profile.antialiasing);
+ m_EyeAdaptation.Init(postProcessingContext, profile.eyeAdaptation);
+ m_DepthOfField.Init(postProcessingContext, profile.depthOfField);
+ m_Bloom.Init(postProcessingContext, profile.bloom);
+ m_ChromaticAberration.Init(postProcessingContext, profile.chromaticAberration);
+ m_ColorGrading.Init(postProcessingContext, profile.colorGrading);
+ m_UserLut.Init(postProcessingContext, profile.userLut);
+ m_Grain.Init(postProcessingContext, profile.grain);
+ m_Vignette.Init(postProcessingContext, profile.vignette);
+ m_Dithering.Init(postProcessingContext, profile.dithering);
+ m_Fxaa.Init(postProcessingContext, profile.antialiasing);
+ if (m_PreviousProfile != profile)
+ {
+ DisableComponents();
+ m_PreviousProfile = profile;
+ }
+ CheckObservers();
+ DepthTextureMode depthTextureMode = postProcessingContext.camera.depthTextureMode;
+ foreach (PostProcessingComponentBase component in m_Components)
+ {
+ if (component.active)
+ {
+ depthTextureMode |= component.GetCameraFlags();
+ }
+ }
+ postProcessingContext.camera.depthTextureMode = depthTextureMode;
+ if (!m_RenderingInSceneView && m_Taa.active && !profile.debugViews.willInterrupt)
+ {
+ m_Taa.SetProjectionMatrix(jitteredMatrixFunc);
+ }
+ }
+
+ private void OnPreRender()
+ {
+ if (!(profile == null))
+ {
+ TryExecuteCommandBuffer(m_DebugViews);
+ TryExecuteCommandBuffer(m_AmbientOcclusion);
+ TryExecuteCommandBuffer(m_ScreenSpaceReflection);
+ TryExecuteCommandBuffer(m_FogComponent);
+ if (!m_RenderingInSceneView)
+ {
+ TryExecuteCommandBuffer(m_MotionBlur);
+ }
+ }
+ }
+
+ private void OnPostRender()
+ {
+ if (!(profile == null) && !(m_Camera == null) && !m_RenderingInSceneView && m_Taa.active && !profile.debugViews.willInterrupt)
+ {
+ m_Context.camera.ResetProjectionMatrix();
+ }
+ }
+
+ private void OnRenderImage(RenderTexture source, RenderTexture destination)
+ {
+ if (profile == null || m_Camera == null)
+ {
+ Graphics.Blit(source, destination);
+ return;
+ }
+ bool flag = false;
+ bool active = m_Fxaa.active;
+ bool flag2 = m_Taa.active && !m_RenderingInSceneView;
+ bool flag3 = m_DepthOfField.active && !m_RenderingInSceneView;
+ Material material = m_MaterialFactory.Get("Hidden/Post FX/Uber Shader");
+ material.shaderKeywords = null;
+ RenderTexture renderTexture = source;
+ if (flag2)
+ {
+ RenderTexture renderTexture2 = m_RenderTextureFactory.Get(renderTexture);
+ m_Taa.Render(renderTexture, renderTexture2);
+ renderTexture = renderTexture2;
+ }
+ Texture texture = GraphicsUtils.whiteTexture;
+ if (m_EyeAdaptation.active)
+ {
+ flag = true;
+ texture = m_EyeAdaptation.Prepare(renderTexture, material);
+ }
+ material.SetTexture("_AutoExposure", texture);
+ if (flag3)
+ {
+ flag = true;
+ m_DepthOfField.Prepare(renderTexture, material, flag2, m_Taa.jitterVector, m_Taa.model.settings.taaSettings.motionBlending);
+ }
+ if (m_Bloom.active)
+ {
+ flag = true;
+ m_Bloom.Prepare(renderTexture, material, texture);
+ }
+ flag |= TryPrepareUberImageEffect(m_ChromaticAberration, material);
+ flag |= TryPrepareUberImageEffect(m_ColorGrading, material);
+ flag |= TryPrepareUberImageEffect(m_Vignette, material);
+ flag |= TryPrepareUberImageEffect(m_UserLut, material);
+ Material material2 = ((!active) ? null : m_MaterialFactory.Get("Hidden/Post FX/FXAA"));
+ if (active)
+ {
+ material2.shaderKeywords = null;
+ TryPrepareUberImageEffect(m_Grain, material2);
+ TryPrepareUberImageEffect(m_Dithering, material2);
+ if (flag)
+ {
+ RenderTexture renderTexture3 = m_RenderTextureFactory.Get(renderTexture);
+ Graphics.Blit(renderTexture, renderTexture3, material, 0);
+ renderTexture = renderTexture3;
+ }
+ m_Fxaa.Render(renderTexture, destination);
+ }
+ else
+ {
+ flag |= TryPrepareUberImageEffect(m_Grain, material);
+ flag |= TryPrepareUberImageEffect(m_Dithering, material);
+ if (flag)
+ {
+ if (!GraphicsUtils.isLinearColorSpace)
+ {
+ material.EnableKeyword("UNITY_COLORSPACE_GAMMA");
+ }
+ Graphics.Blit(renderTexture, destination, material, 0);
+ }
+ }
+ if (!flag && !active)
+ {
+ Graphics.Blit(renderTexture, destination);
+ }
+ m_RenderTextureFactory.ReleaseAll();
+ }
+
+ private void OnGUI()
+ {
+ if (Event.current.type == EventType.Repaint && !(profile == null) && !(m_Camera == null))
+ {
+ if (m_EyeAdaptation.active && profile.debugViews.IsModeActive(BuiltinDebugViewsModel.Mode.EyeAdaptation))
+ {
+ m_EyeAdaptation.OnGUI();
+ }
+ else if (m_ColorGrading.active && profile.debugViews.IsModeActive(BuiltinDebugViewsModel.Mode.LogLut))
+ {
+ m_ColorGrading.OnGUI();
+ }
+ else if (m_UserLut.active && profile.debugViews.IsModeActive(BuiltinDebugViewsModel.Mode.UserLut))
+ {
+ m_UserLut.OnGUI();
+ }
+ }
+ }
+
+ private void OnDisable()
+ {
+ foreach (KeyValuePair<CameraEvent, CommandBuffer> value in m_CommandBuffers.Values)
+ {
+ m_Camera.RemoveCommandBuffer(value.Key, value.Value);
+ value.Value.Dispose();
+ }
+ m_CommandBuffers.Clear();
+ if (profile != null)
+ {
+ DisableComponents();
+ }
+ m_Components.Clear();
+ m_MaterialFactory.Dispose();
+ m_RenderTextureFactory.Dispose();
+ GraphicsUtils.Dispose();
+ }
+
+ public void ResetTemporalEffects()
+ {
+ m_Taa.ResetHistory();
+ m_MotionBlur.ResetHistory();
+ m_EyeAdaptation.ResetHistory();
+ }
+
+ private void CheckObservers()
+ {
+ foreach (KeyValuePair<PostProcessingComponentBase, bool> componentState in m_ComponentStates)
+ {
+ PostProcessingComponentBase key = componentState.Key;
+ bool flag = key.GetModel().enabled;
+ if (flag != componentState.Value)
+ {
+ if (flag)
+ {
+ m_ComponentsToEnable.Add(key);
+ }
+ else
+ {
+ m_ComponentsToDisable.Add(key);
+ }
+ }
+ }
+ for (int i = 0; i < m_ComponentsToDisable.Count; i++)
+ {
+ PostProcessingComponentBase postProcessingComponentBase = m_ComponentsToDisable[i];
+ m_ComponentStates[postProcessingComponentBase] = false;
+ postProcessingComponentBase.OnDisable();
+ }
+ for (int j = 0; j < m_ComponentsToEnable.Count; j++)
+ {
+ PostProcessingComponentBase postProcessingComponentBase2 = m_ComponentsToEnable[j];
+ m_ComponentStates[postProcessingComponentBase2] = true;
+ postProcessingComponentBase2.OnEnable();
+ }
+ m_ComponentsToDisable.Clear();
+ m_ComponentsToEnable.Clear();
+ }
+
+ private void DisableComponents()
+ {
+ foreach (PostProcessingComponentBase component in m_Components)
+ {
+ PostProcessingModel model = component.GetModel();
+ if (model != null && model.enabled)
+ {
+ component.OnDisable();
+ }
+ }
+ }
+
+ private CommandBuffer AddCommandBuffer<T>(CameraEvent evt, string name) where T : PostProcessingModel
+ {
+ CommandBuffer commandBuffer = new CommandBuffer();
+ commandBuffer.name = name;
+ CommandBuffer value = commandBuffer;
+ KeyValuePair<CameraEvent, CommandBuffer> value2 = new KeyValuePair<CameraEvent, CommandBuffer>(evt, value);
+ m_CommandBuffers.Add(typeof(T), value2);
+ m_Camera.AddCommandBuffer(evt, value2.Value);
+ return value2.Value;
+ }
+
+ private void RemoveCommandBuffer<T>() where T : PostProcessingModel
+ {
+ Type typeFromHandle = typeof(T);
+ if (m_CommandBuffers.TryGetValue(typeFromHandle, out var value))
+ {
+ m_Camera.RemoveCommandBuffer(value.Key, value.Value);
+ m_CommandBuffers.Remove(typeFromHandle);
+ value.Value.Dispose();
+ }
+ }
+
+ private CommandBuffer GetCommandBuffer<T>(CameraEvent evt, string name) where T : PostProcessingModel
+ {
+ if (!m_CommandBuffers.TryGetValue(typeof(T), out var value))
+ {
+ return AddCommandBuffer<T>(evt, name);
+ }
+ if (value.Key != evt)
+ {
+ RemoveCommandBuffer<T>();
+ return AddCommandBuffer<T>(evt, name);
+ }
+ return value.Value;
+ }
+
+ private void TryExecuteCommandBuffer<T>(PostProcessingComponentCommandBuffer<T> component) where T : PostProcessingModel
+ {
+ if (component.active)
+ {
+ CommandBuffer commandBuffer = GetCommandBuffer<T>(component.GetCameraEvent(), component.GetName());
+ commandBuffer.Clear();
+ component.PopulateCommandBuffer(commandBuffer);
+ }
+ else
+ {
+ RemoveCommandBuffer<T>();
+ }
+ }
+
+ private bool TryPrepareUberImageEffect<T>(PostProcessingComponentRenderTexture<T> component, Material material) where T : PostProcessingModel
+ {
+ if (!component.active)
+ {
+ return false;
+ }
+ component.Prepare(material);
+ return true;
+ }
+
+ private T AddComponent<T>(T component) where T : PostProcessingComponentBase
+ {
+ m_Components.Add(component);
+ return component;
+ }
+}
diff --git a/UnityEngine.PostProcessing/PostProcessingComponent.cs b/UnityEngine.PostProcessing/PostProcessingComponent.cs
new file mode 100644
index 0000000..08c2ba7
--- /dev/null
+++ b/UnityEngine.PostProcessing/PostProcessingComponent.cs
@@ -0,0 +1,17 @@
+namespace UnityEngine.PostProcessing;
+
+public abstract class PostProcessingComponent<T> : PostProcessingComponentBase where T : PostProcessingModel
+{
+ public T model { get; internal set; }
+
+ public virtual void Init(PostProcessingContext pcontext, T pmodel)
+ {
+ context = pcontext;
+ model = pmodel;
+ }
+
+ public override PostProcessingModel GetModel()
+ {
+ return model;
+ }
+}
diff --git a/UnityEngine.PostProcessing/PostProcessingComponentBase.cs b/UnityEngine.PostProcessing/PostProcessingComponentBase.cs
new file mode 100644
index 0000000..491f371
--- /dev/null
+++ b/UnityEngine.PostProcessing/PostProcessingComponentBase.cs
@@ -0,0 +1,23 @@
+namespace UnityEngine.PostProcessing;
+
+public abstract class PostProcessingComponentBase
+{
+ public PostProcessingContext context;
+
+ public abstract bool active { get; }
+
+ public virtual DepthTextureMode GetCameraFlags()
+ {
+ return DepthTextureMode.None;
+ }
+
+ public virtual void OnEnable()
+ {
+ }
+
+ public virtual void OnDisable()
+ {
+ }
+
+ public abstract PostProcessingModel GetModel();
+}
diff --git a/UnityEngine.PostProcessing/PostProcessingComponentCommandBuffer.cs b/UnityEngine.PostProcessing/PostProcessingComponentCommandBuffer.cs
new file mode 100644
index 0000000..a8a9408
--- /dev/null
+++ b/UnityEngine.PostProcessing/PostProcessingComponentCommandBuffer.cs
@@ -0,0 +1,12 @@
+using UnityEngine.Rendering;
+
+namespace UnityEngine.PostProcessing;
+
+public abstract class PostProcessingComponentCommandBuffer<T> : PostProcessingComponent<T> where T : PostProcessingModel
+{
+ public abstract CameraEvent GetCameraEvent();
+
+ public abstract string GetName();
+
+ public abstract void PopulateCommandBuffer(CommandBuffer cb);
+}
diff --git a/UnityEngine.PostProcessing/PostProcessingComponentRenderTexture.cs b/UnityEngine.PostProcessing/PostProcessingComponentRenderTexture.cs
new file mode 100644
index 0000000..8284bb2
--- /dev/null
+++ b/UnityEngine.PostProcessing/PostProcessingComponentRenderTexture.cs
@@ -0,0 +1,8 @@
+namespace UnityEngine.PostProcessing;
+
+public abstract class PostProcessingComponentRenderTexture<T> : PostProcessingComponent<T> where T : PostProcessingModel
+{
+ public virtual void Prepare(Material material)
+ {
+ }
+}
diff --git a/UnityEngine.PostProcessing/PostProcessingContext.cs b/UnityEngine.PostProcessing/PostProcessingContext.cs
new file mode 100644
index 0000000..ab810a1
--- /dev/null
+++ b/UnityEngine.PostProcessing/PostProcessingContext.cs
@@ -0,0 +1,39 @@
+namespace UnityEngine.PostProcessing;
+
+public class PostProcessingContext
+{
+ public PostProcessingProfile profile;
+
+ public Camera camera;
+
+ public MaterialFactory materialFactory;
+
+ public RenderTextureFactory renderTextureFactory;
+
+ public bool interrupted { get; private set; }
+
+ public bool isGBufferAvailable => camera.actualRenderingPath == RenderingPath.DeferredShading;
+
+ public bool isHdr => camera.allowHDR;
+
+ public int width => camera.pixelWidth;
+
+ public int height => camera.pixelHeight;
+
+ public Rect viewport => camera.rect;
+
+ public void Interrupt()
+ {
+ interrupted = true;
+ }
+
+ public PostProcessingContext Reset()
+ {
+ profile = null;
+ camera = null;
+ materialFactory = null;
+ renderTextureFactory = null;
+ interrupted = false;
+ return this;
+ }
+}
diff --git a/UnityEngine.PostProcessing/PostProcessingModel.cs b/UnityEngine.PostProcessing/PostProcessingModel.cs
new file mode 100644
index 0000000..986b42b
--- /dev/null
+++ b/UnityEngine.PostProcessing/PostProcessingModel.cs
@@ -0,0 +1,33 @@
+using System;
+
+namespace UnityEngine.PostProcessing;
+
+[Serializable]
+public abstract class PostProcessingModel
+{
+ [SerializeField]
+ [GetSet("enabled")]
+ private bool m_Enabled;
+
+ public bool enabled
+ {
+ get
+ {
+ return m_Enabled;
+ }
+ set
+ {
+ m_Enabled = value;
+ if (value)
+ {
+ OnValidate();
+ }
+ }
+ }
+
+ public abstract void Reset();
+
+ public virtual void OnValidate()
+ {
+ }
+}
diff --git a/UnityEngine.PostProcessing/PostProcessingProfile.cs b/UnityEngine.PostProcessing/PostProcessingProfile.cs
new file mode 100644
index 0000000..3c847b3
--- /dev/null
+++ b/UnityEngine.PostProcessing/PostProcessingProfile.cs
@@ -0,0 +1,34 @@
+namespace UnityEngine.PostProcessing;
+
+public class PostProcessingProfile : ScriptableObject
+{
+ public BuiltinDebugViewsModel debugViews = new BuiltinDebugViewsModel();
+
+ public FogModel fog = new FogModel();
+
+ public AntialiasingModel antialiasing = new AntialiasingModel();
+
+ public AmbientOcclusionModel ambientOcclusion = new AmbientOcclusionModel();
+
+ public ScreenSpaceReflectionModel screenSpaceReflection = new ScreenSpaceReflectionModel();
+
+ public DepthOfFieldModel depthOfField = new DepthOfFieldModel();
+
+ public MotionBlurModel motionBlur = new MotionBlurModel();
+
+ public EyeAdaptationModel eyeAdaptation = new EyeAdaptationModel();
+
+ public BloomModel bloom = new BloomModel();
+
+ public ColorGradingModel colorGrading = new ColorGradingModel();
+
+ public UserLutModel userLut = new UserLutModel();
+
+ public ChromaticAberrationModel chromaticAberration = new ChromaticAberrationModel();
+
+ public GrainModel grain = new GrainModel();
+
+ public VignetteModel vignette = new VignetteModel();
+
+ public DitheringModel dithering = new DitheringModel();
+}
diff --git a/UnityEngine.PostProcessing/RenderTextureFactory.cs b/UnityEngine.PostProcessing/RenderTextureFactory.cs
new file mode 100644
index 0000000..51d9f15
--- /dev/null
+++ b/UnityEngine.PostProcessing/RenderTextureFactory.cs
@@ -0,0 +1,57 @@
+using System;
+using System.Collections.Generic;
+
+namespace UnityEngine.PostProcessing;
+
+public sealed class RenderTextureFactory : IDisposable
+{
+ private HashSet<RenderTexture> m_TemporaryRTs;
+
+ public RenderTextureFactory()
+ {
+ m_TemporaryRTs = new HashSet<RenderTexture>();
+ }
+
+ public RenderTexture Get(RenderTexture baseRenderTexture)
+ {
+ return Get(baseRenderTexture.width, baseRenderTexture.height, baseRenderTexture.depth, baseRenderTexture.format, (!baseRenderTexture.sRGB) ? RenderTextureReadWrite.Linear : RenderTextureReadWrite.sRGB, baseRenderTexture.filterMode, baseRenderTexture.wrapMode);
+ }
+
+ public RenderTexture Get(int width, int height, int depthBuffer = 0, RenderTextureFormat format = RenderTextureFormat.ARGBHalf, RenderTextureReadWrite rw = RenderTextureReadWrite.Default, FilterMode filterMode = FilterMode.Bilinear, TextureWrapMode wrapMode = TextureWrapMode.Clamp, string name = "FactoryTempTexture")
+ {
+ RenderTexture temporary = RenderTexture.GetTemporary(width, height, depthBuffer, format, rw);
+ temporary.filterMode = filterMode;
+ temporary.wrapMode = wrapMode;
+ temporary.name = name;
+ m_TemporaryRTs.Add(temporary);
+ return temporary;
+ }
+
+ public void Release(RenderTexture rt)
+ {
+ if (!(rt == null))
+ {
+ if (!m_TemporaryRTs.Contains(rt))
+ {
+ throw new ArgumentException($"Attempting to remove a RenderTexture that was not allocated: {rt}");
+ }
+ m_TemporaryRTs.Remove(rt);
+ RenderTexture.ReleaseTemporary(rt);
+ }
+ }
+
+ public void ReleaseAll()
+ {
+ HashSet<RenderTexture>.Enumerator enumerator = m_TemporaryRTs.GetEnumerator();
+ while (enumerator.MoveNext())
+ {
+ RenderTexture.ReleaseTemporary(enumerator.Current);
+ }
+ m_TemporaryRTs.Clear();
+ }
+
+ public void Dispose()
+ {
+ ReleaseAll();
+ }
+}
diff --git a/UnityEngine.PostProcessing/ScreenSpaceReflectionComponent.cs b/UnityEngine.PostProcessing/ScreenSpaceReflectionComponent.cs
new file mode 100644
index 0000000..e9f0c02
--- /dev/null
+++ b/UnityEngine.PostProcessing/ScreenSpaceReflectionComponent.cs
@@ -0,0 +1,217 @@
+using System;
+using UnityEngine.Rendering;
+
+namespace UnityEngine.PostProcessing;
+
+public sealed class ScreenSpaceReflectionComponent : PostProcessingComponentCommandBuffer<ScreenSpaceReflectionModel>
+{
+ private static class Uniforms
+ {
+ internal static readonly int _RayStepSize = Shader.PropertyToID("_RayStepSize");
+
+ internal static readonly int _AdditiveReflection = Shader.PropertyToID("_AdditiveReflection");
+
+ internal static readonly int _BilateralUpsampling = Shader.PropertyToID("_BilateralUpsampling");
+
+ internal static readonly int _TreatBackfaceHitAsMiss = Shader.PropertyToID("_TreatBackfaceHitAsMiss");
+
+ internal static readonly int _AllowBackwardsRays = Shader.PropertyToID("_AllowBackwardsRays");
+
+ internal static readonly int _TraceBehindObjects = Shader.PropertyToID("_TraceBehindObjects");
+
+ internal static readonly int _MaxSteps = Shader.PropertyToID("_MaxSteps");
+
+ internal static readonly int _FullResolutionFiltering = Shader.PropertyToID("_FullResolutionFiltering");
+
+ internal static readonly int _HalfResolution = Shader.PropertyToID("_HalfResolution");
+
+ internal static readonly int _HighlightSuppression = Shader.PropertyToID("_HighlightSuppression");
+
+ internal static readonly int _PixelsPerMeterAtOneMeter = Shader.PropertyToID("_PixelsPerMeterAtOneMeter");
+
+ internal static readonly int _ScreenEdgeFading = Shader.PropertyToID("_ScreenEdgeFading");
+
+ internal static readonly int _ReflectionBlur = Shader.PropertyToID("_ReflectionBlur");
+
+ internal static readonly int _MaxRayTraceDistance = Shader.PropertyToID("_MaxRayTraceDistance");
+
+ internal static readonly int _FadeDistance = Shader.PropertyToID("_FadeDistance");
+
+ internal static readonly int _LayerThickness = Shader.PropertyToID("_LayerThickness");
+
+ internal static readonly int _SSRMultiplier = Shader.PropertyToID("_SSRMultiplier");
+
+ internal static readonly int _FresnelFade = Shader.PropertyToID("_FresnelFade");
+
+ internal static readonly int _FresnelFadePower = Shader.PropertyToID("_FresnelFadePower");
+
+ internal static readonly int _ReflectionBufferSize = Shader.PropertyToID("_ReflectionBufferSize");
+
+ internal static readonly int _ScreenSize = Shader.PropertyToID("_ScreenSize");
+
+ internal static readonly int _InvScreenSize = Shader.PropertyToID("_InvScreenSize");
+
+ internal static readonly int _ProjInfo = Shader.PropertyToID("_ProjInfo");
+
+ internal static readonly int _CameraClipInfo = Shader.PropertyToID("_CameraClipInfo");
+
+ internal static readonly int _ProjectToPixelMatrix = Shader.PropertyToID("_ProjectToPixelMatrix");
+
+ internal static readonly int _WorldToCameraMatrix = Shader.PropertyToID("_WorldToCameraMatrix");
+
+ internal static readonly int _CameraToWorldMatrix = Shader.PropertyToID("_CameraToWorldMatrix");
+
+ internal static readonly int _Axis = Shader.PropertyToID("_Axis");
+
+ internal static readonly int _CurrentMipLevel = Shader.PropertyToID("_CurrentMipLevel");
+
+ internal static readonly int _NormalAndRoughnessTexture = Shader.PropertyToID("_NormalAndRoughnessTexture");
+
+ internal static readonly int _HitPointTexture = Shader.PropertyToID("_HitPointTexture");
+
+ internal static readonly int _BlurTexture = Shader.PropertyToID("_BlurTexture");
+
+ internal static readonly int _FilteredReflections = Shader.PropertyToID("_FilteredReflections");
+
+ internal static readonly int _FinalReflectionTexture = Shader.PropertyToID("_FinalReflectionTexture");
+
+ internal static readonly int _TempTexture = Shader.PropertyToID("_TempTexture");
+ }
+
+ private enum PassIndex
+ {
+ RayTraceStep,
+ CompositeFinal,
+ Blur,
+ CompositeSSR,
+ MinMipGeneration,
+ HitPointToReflections,
+ BilateralKeyPack,
+ BlitDepthAsCSZ,
+ PoissonBlur
+ }
+
+ private bool k_HighlightSuppression;
+
+ private bool k_TraceBehindObjects = true;
+
+ private bool k_TreatBackfaceHitAsMiss;
+
+ private bool k_BilateralUpsample = true;
+
+ private readonly int[] m_ReflectionTextures = new int[5];
+
+ public override bool active => base.model.enabled && context.isGBufferAvailable && !context.interrupted;
+
+ public override DepthTextureMode GetCameraFlags()
+ {
+ return DepthTextureMode.Depth;
+ }
+
+ public override void OnEnable()
+ {
+ m_ReflectionTextures[0] = Shader.PropertyToID("_ReflectionTexture0");
+ m_ReflectionTextures[1] = Shader.PropertyToID("_ReflectionTexture1");
+ m_ReflectionTextures[2] = Shader.PropertyToID("_ReflectionTexture2");
+ m_ReflectionTextures[3] = Shader.PropertyToID("_ReflectionTexture3");
+ m_ReflectionTextures[4] = Shader.PropertyToID("_ReflectionTexture4");
+ }
+
+ public override string GetName()
+ {
+ return "Screen Space Reflection";
+ }
+
+ public override CameraEvent GetCameraEvent()
+ {
+ return CameraEvent.AfterFinalPass;
+ }
+
+ public override void PopulateCommandBuffer(CommandBuffer cb)
+ {
+ ScreenSpaceReflectionModel.Settings settings = base.model.settings;
+ Camera camera = context.camera;
+ int num = ((settings.reflection.reflectionQuality == ScreenSpaceReflectionModel.SSRResolution.High) ? 1 : 2);
+ int num2 = context.width / num;
+ int num3 = context.height / num;
+ float num4 = context.width;
+ float num5 = context.height;
+ float num6 = num4 / 2f;
+ float num7 = num5 / 2f;
+ Material material = context.materialFactory.Get("Hidden/Post FX/Screen Space Reflection");
+ material.SetInt(Uniforms._RayStepSize, settings.reflection.stepSize);
+ material.SetInt(Uniforms._AdditiveReflection, (settings.reflection.blendType == ScreenSpaceReflectionModel.SSRReflectionBlendType.Additive) ? 1 : 0);
+ material.SetInt(Uniforms._BilateralUpsampling, k_BilateralUpsample ? 1 : 0);
+ material.SetInt(Uniforms._TreatBackfaceHitAsMiss, k_TreatBackfaceHitAsMiss ? 1 : 0);
+ material.SetInt(Uniforms._AllowBackwardsRays, settings.reflection.reflectBackfaces ? 1 : 0);
+ material.SetInt(Uniforms._TraceBehindObjects, k_TraceBehindObjects ? 1 : 0);
+ material.SetInt(Uniforms._MaxSteps, settings.reflection.iterationCount);
+ material.SetInt(Uniforms._FullResolutionFiltering, 0);
+ material.SetInt(Uniforms._HalfResolution, (settings.reflection.reflectionQuality != 0) ? 1 : 0);
+ material.SetInt(Uniforms._HighlightSuppression, k_HighlightSuppression ? 1 : 0);
+ float value = num4 / (-2f * Mathf.Tan(camera.fieldOfView / 180f * (float)Math.PI * 0.5f));
+ material.SetFloat(Uniforms._PixelsPerMeterAtOneMeter, value);
+ material.SetFloat(Uniforms._ScreenEdgeFading, settings.screenEdgeMask.intensity);
+ material.SetFloat(Uniforms._ReflectionBlur, settings.reflection.reflectionBlur);
+ material.SetFloat(Uniforms._MaxRayTraceDistance, settings.reflection.maxDistance);
+ material.SetFloat(Uniforms._FadeDistance, settings.intensity.fadeDistance);
+ material.SetFloat(Uniforms._LayerThickness, settings.reflection.widthModifier);
+ material.SetFloat(Uniforms._SSRMultiplier, settings.intensity.reflectionMultiplier);
+ material.SetFloat(Uniforms._FresnelFade, settings.intensity.fresnelFade);
+ material.SetFloat(Uniforms._FresnelFadePower, settings.intensity.fresnelFadePower);
+ Matrix4x4 projectionMatrix = camera.projectionMatrix;
+ Vector4 value2 = new Vector4(-2f / (num4 * projectionMatrix[0]), -2f / (num5 * projectionMatrix[5]), (1f - projectionMatrix[2]) / projectionMatrix[0], (1f + projectionMatrix[6]) / projectionMatrix[5]);
+ Vector3 vector = ((!float.IsPositiveInfinity(camera.farClipPlane)) ? new Vector3(camera.nearClipPlane * camera.farClipPlane, camera.nearClipPlane - camera.farClipPlane, camera.farClipPlane) : new Vector3(camera.nearClipPlane, -1f, 1f));
+ material.SetVector(Uniforms._ReflectionBufferSize, new Vector2(num2, num3));
+ material.SetVector(Uniforms._ScreenSize, new Vector2(num4, num5));
+ material.SetVector(Uniforms._InvScreenSize, new Vector2(1f / num4, 1f / num5));
+ material.SetVector(Uniforms._ProjInfo, value2);
+ material.SetVector(Uniforms._CameraClipInfo, vector);
+ Matrix4x4 matrix4x = default(Matrix4x4);
+ matrix4x.SetRow(0, new Vector4(num6, 0f, 0f, num6));
+ matrix4x.SetRow(1, new Vector4(0f, num7, 0f, num7));
+ matrix4x.SetRow(2, new Vector4(0f, 0f, 1f, 0f));
+ matrix4x.SetRow(3, new Vector4(0f, 0f, 0f, 1f));
+ Matrix4x4 value3 = matrix4x * projectionMatrix;
+ material.SetMatrix(Uniforms._ProjectToPixelMatrix, value3);
+ material.SetMatrix(Uniforms._WorldToCameraMatrix, camera.worldToCameraMatrix);
+ material.SetMatrix(Uniforms._CameraToWorldMatrix, camera.worldToCameraMatrix.inverse);
+ RenderTextureFormat format = (context.isHdr ? RenderTextureFormat.ARGBHalf : RenderTextureFormat.ARGB32);
+ int normalAndRoughnessTexture = Uniforms._NormalAndRoughnessTexture;
+ int hitPointTexture = Uniforms._HitPointTexture;
+ int blurTexture = Uniforms._BlurTexture;
+ int filteredReflections = Uniforms._FilteredReflections;
+ int finalReflectionTexture = Uniforms._FinalReflectionTexture;
+ int tempTexture = Uniforms._TempTexture;
+ cb.GetTemporaryRT(normalAndRoughnessTexture, -1, -1, 0, FilterMode.Point, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);
+ cb.GetTemporaryRT(hitPointTexture, num2, num3, 0, FilterMode.Bilinear, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear);
+ for (int i = 0; i < 5; i++)
+ {
+ cb.GetTemporaryRT(m_ReflectionTextures[i], num2 >> i, num3 >> i, 0, FilterMode.Bilinear, format);
+ }
+ cb.GetTemporaryRT(filteredReflections, num2, num3, 0, (!k_BilateralUpsample) ? FilterMode.Bilinear : FilterMode.Point, format);
+ cb.GetTemporaryRT(finalReflectionTexture, num2, num3, 0, FilterMode.Point, format);
+ cb.Blit(BuiltinRenderTextureType.CameraTarget, normalAndRoughnessTexture, material, 6);
+ cb.Blit(BuiltinRenderTextureType.CameraTarget, hitPointTexture, material, 0);
+ cb.Blit(BuiltinRenderTextureType.CameraTarget, filteredReflections, material, 5);
+ cb.Blit(filteredReflections, m_ReflectionTextures[0], material, 8);
+ for (int j = 1; j < 5; j++)
+ {
+ int num8 = m_ReflectionTextures[j - 1];
+ int num9 = j;
+ cb.GetTemporaryRT(blurTexture, num2 >> num9, num3 >> num9, 0, FilterMode.Bilinear, format);
+ cb.SetGlobalVector(Uniforms._Axis, new Vector4(1f, 0f, 0f, 0f));
+ cb.SetGlobalFloat(Uniforms._CurrentMipLevel, (float)j - 1f);
+ cb.Blit(num8, blurTexture, material, 2);
+ cb.SetGlobalVector(Uniforms._Axis, new Vector4(0f, 1f, 0f, 0f));
+ num8 = m_ReflectionTextures[j];
+ cb.Blit(blurTexture, num8, material, 2);
+ cb.ReleaseTemporaryRT(blurTexture);
+ }
+ cb.Blit(m_ReflectionTextures[0], finalReflectionTexture, material, 3);
+ cb.GetTemporaryRT(tempTexture, camera.pixelWidth, camera.pixelHeight, 0, FilterMode.Bilinear, format);
+ cb.Blit(BuiltinRenderTextureType.CameraTarget, tempTexture, material, 1);
+ cb.Blit(tempTexture, BuiltinRenderTextureType.CameraTarget);
+ cb.ReleaseTemporaryRT(tempTexture);
+ }
+}
diff --git a/UnityEngine.PostProcessing/ScreenSpaceReflectionModel.cs b/UnityEngine.PostProcessing/ScreenSpaceReflectionModel.cs
new file mode 100644
index 0000000..2552044
--- /dev/null
+++ b/UnityEngine.PostProcessing/ScreenSpaceReflectionModel.cs
@@ -0,0 +1,141 @@
+using System;
+
+namespace UnityEngine.PostProcessing;
+
+[Serializable]
+public class ScreenSpaceReflectionModel : PostProcessingModel
+{
+ public enum SSRResolution
+ {
+ High = 0,
+ Low = 2
+ }
+
+ public enum SSRReflectionBlendType
+ {
+ PhysicallyBased,
+ Additive
+ }
+
+ [Serializable]
+ public struct IntensitySettings
+ {
+ [Tooltip("Nonphysical multiplier for the SSR reflections. 1.0 is physically based.")]
+ [Range(0f, 2f)]
+ public float reflectionMultiplier;
+
+ [Tooltip("How far away from the maxDistance to begin fading SSR.")]
+ [Range(0f, 1000f)]
+ public float fadeDistance;
+
+ [Tooltip("Amplify Fresnel fade out. Increase if floor reflections look good close to the surface and bad farther 'under' the floor.")]
+ [Range(0f, 1f)]
+ public float fresnelFade;
+
+ [Tooltip("Higher values correspond to a faster Fresnel fade as the reflection changes from the grazing angle.")]
+ [Range(0.1f, 10f)]
+ public float fresnelFadePower;
+ }
+
+ [Serializable]
+ public struct ReflectionSettings
+ {
+ [Tooltip("How the reflections are blended into the render.")]
+ public SSRReflectionBlendType blendType;
+
+ [Tooltip("Half resolution SSRR is much faster, but less accurate.")]
+ public SSRResolution reflectionQuality;
+
+ [Tooltip("Maximum reflection distance in world units.")]
+ [Range(0.1f, 300f)]
+ public float maxDistance;
+
+ [Tooltip("Max raytracing length.")]
+ [Range(16f, 1024f)]
+ public int iterationCount;
+
+ [Tooltip("Log base 2 of ray tracing coarse step size. Higher traces farther, lower gives better quality silhouettes.")]
+ [Range(1f, 16f)]
+ public int stepSize;
+
+ [Tooltip("Typical thickness of columns, walls, furniture, and other objects that reflection rays might pass behind.")]
+ [Range(0.01f, 10f)]
+ public float widthModifier;
+
+ [Tooltip("Blurriness of reflections.")]
+ [Range(0.1f, 8f)]
+ public float reflectionBlur;
+
+ [Tooltip("Disable for a performance gain in scenes where most glossy objects are horizontal, like floors, water, and tables. Leave on for scenes with glossy vertical objects.")]
+ public bool reflectBackfaces;
+ }
+
+ [Serializable]
+ public struct ScreenEdgeMask
+ {
+ [Tooltip("Higher = fade out SSRR near the edge of the screen so that reflections don't pop under camera motion.")]
+ [Range(0f, 1f)]
+ public float intensity;
+ }
+
+ [Serializable]
+ public struct Settings
+ {
+ public ReflectionSettings reflection;
+
+ public IntensitySettings intensity;
+
+ public ScreenEdgeMask screenEdgeMask;
+
+ public static Settings defaultSettings
+ {
+ get
+ {
+ Settings result = default(Settings);
+ result.reflection = new ReflectionSettings
+ {
+ blendType = SSRReflectionBlendType.PhysicallyBased,
+ reflectionQuality = SSRResolution.Low,
+ maxDistance = 100f,
+ iterationCount = 256,
+ stepSize = 3,
+ widthModifier = 0.5f,
+ reflectionBlur = 1f,
+ reflectBackfaces = false
+ };
+ result.intensity = new IntensitySettings
+ {
+ reflectionMultiplier = 1f,
+ fadeDistance = 100f,
+ fresnelFade = 1f,
+ fresnelFadePower = 1f
+ };
+ result.screenEdgeMask = new ScreenEdgeMask
+ {
+ intensity = 0.03f
+ };
+ return result;
+ }
+ }
+ }
+
+ [SerializeField]
+ private Settings m_Settings = Settings.defaultSettings;
+
+ public Settings settings
+ {
+ get
+ {
+ return m_Settings;
+ }
+ set
+ {
+ m_Settings = value;
+ }
+ }
+
+ public override void Reset()
+ {
+ m_Settings = Settings.defaultSettings;
+ }
+}
diff --git a/UnityEngine.PostProcessing/TaaComponent.cs b/UnityEngine.PostProcessing/TaaComponent.cs
new file mode 100644
index 0000000..83cf6dd
--- /dev/null
+++ b/UnityEngine.PostProcessing/TaaComponent.cs
@@ -0,0 +1,176 @@
+using System;
+
+namespace UnityEngine.PostProcessing;
+
+public sealed class TaaComponent : PostProcessingComponentRenderTexture<AntialiasingModel>
+{
+ private static class Uniforms
+ {
+ internal static int _Jitter = Shader.PropertyToID("_Jitter");
+
+ internal static int _SharpenParameters = Shader.PropertyToID("_SharpenParameters");
+
+ internal static int _FinalBlendParameters = Shader.PropertyToID("_FinalBlendParameters");
+
+ internal static int _HistoryTex = Shader.PropertyToID("_HistoryTex");
+
+ internal static int _MainTex = Shader.PropertyToID("_MainTex");
+ }
+
+ private const string k_ShaderString = "Hidden/Post FX/Temporal Anti-aliasing";
+
+ private const int k_SampleCount = 8;
+
+ private readonly RenderBuffer[] m_MRT = new RenderBuffer[2];
+
+ private int m_SampleIndex;
+
+ private bool m_ResetHistory = true;
+
+ private RenderTexture m_HistoryTexture;
+
+ public override bool active => base.model.enabled && base.model.settings.method == AntialiasingModel.Method.Taa && SystemInfo.supportsMotionVectors && SystemInfo.supportedRenderTargetCount >= 2 && !context.interrupted;
+
+ public Vector2 jitterVector { get; private set; }
+
+ public override DepthTextureMode GetCameraFlags()
+ {
+ return DepthTextureMode.Depth | DepthTextureMode.MotionVectors;
+ }
+
+ public void ResetHistory()
+ {
+ m_ResetHistory = true;
+ }
+
+ public void SetProjectionMatrix(Func<Vector2, Matrix4x4> jitteredFunc)
+ {
+ AntialiasingModel.TaaSettings taaSettings = base.model.settings.taaSettings;
+ Vector2 vector = GenerateRandomOffset();
+ vector *= taaSettings.jitterSpread;
+ context.camera.nonJitteredProjectionMatrix = context.camera.projectionMatrix;
+ if (jitteredFunc != null)
+ {
+ context.camera.projectionMatrix = jitteredFunc(vector);
+ }
+ else
+ {
+ context.camera.projectionMatrix = ((!context.camera.orthographic) ? GetPerspectiveProjectionMatrix(vector) : GetOrthographicProjectionMatrix(vector));
+ }
+ context.camera.useJitteredProjectionMatrixForTransparentRendering = false;
+ vector.x /= context.width;
+ vector.y /= context.height;
+ Material material = context.materialFactory.Get("Hidden/Post FX/Temporal Anti-aliasing");
+ material.SetVector(Uniforms._Jitter, vector);
+ jitterVector = vector;
+ }
+
+ public void Render(RenderTexture source, RenderTexture destination)
+ {
+ Material material = context.materialFactory.Get("Hidden/Post FX/Temporal Anti-aliasing");
+ material.shaderKeywords = null;
+ AntialiasingModel.TaaSettings taaSettings = base.model.settings.taaSettings;
+ if (m_ResetHistory || m_HistoryTexture == null || m_HistoryTexture.width != source.width || m_HistoryTexture.height != source.height)
+ {
+ if ((bool)m_HistoryTexture)
+ {
+ RenderTexture.ReleaseTemporary(m_HistoryTexture);
+ }
+ m_HistoryTexture = RenderTexture.GetTemporary(source.width, source.height, 0, source.format);
+ m_HistoryTexture.name = "TAA History";
+ Graphics.Blit(source, m_HistoryTexture, material, 2);
+ }
+ material.SetVector(Uniforms._SharpenParameters, new Vector4(taaSettings.sharpen, 0f, 0f, 0f));
+ material.SetVector(Uniforms._FinalBlendParameters, new Vector4(taaSettings.stationaryBlending, taaSettings.motionBlending, 6000f, 0f));
+ material.SetTexture(Uniforms._MainTex, source);
+ material.SetTexture(Uniforms._HistoryTex, m_HistoryTexture);
+ RenderTexture temporary = RenderTexture.GetTemporary(source.width, source.height, 0, source.format);
+ temporary.name = "TAA History";
+ ref RenderBuffer reference = ref m_MRT[0];
+ reference = destination.colorBuffer;
+ ref RenderBuffer reference2 = ref m_MRT[1];
+ reference2 = temporary.colorBuffer;
+ Graphics.SetRenderTarget(m_MRT, source.depthBuffer);
+ GraphicsUtils.Blit(material, context.camera.orthographic ? 1 : 0);
+ RenderTexture.ReleaseTemporary(m_HistoryTexture);
+ m_HistoryTexture = temporary;
+ m_ResetHistory = false;
+ }
+
+ private float GetHaltonValue(int index, int radix)
+ {
+ float num = 0f;
+ float num2 = 1f / (float)radix;
+ while (index > 0)
+ {
+ num += (float)(index % radix) * num2;
+ index /= radix;
+ num2 /= (float)radix;
+ }
+ return num;
+ }
+
+ private Vector2 GenerateRandomOffset()
+ {
+ Vector2 result = new Vector2(GetHaltonValue(m_SampleIndex & 0x3FF, 2), GetHaltonValue(m_SampleIndex & 0x3FF, 3));
+ if (++m_SampleIndex >= 8)
+ {
+ m_SampleIndex = 0;
+ }
+ return result;
+ }
+
+ private Matrix4x4 GetPerspectiveProjectionMatrix(Vector2 offset)
+ {
+ float num = Mathf.Tan((float)Math.PI / 360f * context.camera.fieldOfView);
+ float num2 = num * context.camera.aspect;
+ offset.x *= num2 / (0.5f * (float)context.width);
+ offset.y *= num / (0.5f * (float)context.height);
+ float num3 = (offset.x - num2) * context.camera.nearClipPlane;
+ float num4 = (offset.x + num2) * context.camera.nearClipPlane;
+ float num5 = (offset.y + num) * context.camera.nearClipPlane;
+ float num6 = (offset.y - num) * context.camera.nearClipPlane;
+ Matrix4x4 result = default(Matrix4x4);
+ result[0, 0] = 2f * context.camera.nearClipPlane / (num4 - num3);
+ result[0, 1] = 0f;
+ result[0, 2] = (num4 + num3) / (num4 - num3);
+ result[0, 3] = 0f;
+ result[1, 0] = 0f;
+ result[1, 1] = 2f * context.camera.nearClipPlane / (num5 - num6);
+ result[1, 2] = (num5 + num6) / (num5 - num6);
+ result[1, 3] = 0f;
+ result[2, 0] = 0f;
+ result[2, 1] = 0f;
+ result[2, 2] = (0f - (context.camera.farClipPlane + context.camera.nearClipPlane)) / (context.camera.farClipPlane - context.camera.nearClipPlane);
+ result[2, 3] = (0f - 2f * context.camera.farClipPlane * context.camera.nearClipPlane) / (context.camera.farClipPlane - context.camera.nearClipPlane);
+ result[3, 0] = 0f;
+ result[3, 1] = 0f;
+ result[3, 2] = -1f;
+ result[3, 3] = 0f;
+ return result;
+ }
+
+ private Matrix4x4 GetOrthographicProjectionMatrix(Vector2 offset)
+ {
+ float orthographicSize = context.camera.orthographicSize;
+ float num = orthographicSize * context.camera.aspect;
+ offset.x *= num / (0.5f * (float)context.width);
+ offset.y *= orthographicSize / (0.5f * (float)context.height);
+ float left = offset.x - num;
+ float right = offset.x + num;
+ float top = offset.y + orthographicSize;
+ float bottom = offset.y - orthographicSize;
+ return Matrix4x4.Ortho(left, right, bottom, top, context.camera.nearClipPlane, context.camera.farClipPlane);
+ }
+
+ public override void OnDisable()
+ {
+ if (m_HistoryTexture != null)
+ {
+ RenderTexture.ReleaseTemporary(m_HistoryTexture);
+ }
+ m_HistoryTexture = null;
+ m_SampleIndex = 0;
+ ResetHistory();
+ }
+}
diff --git a/UnityEngine.PostProcessing/TrackballAttribute.cs b/UnityEngine.PostProcessing/TrackballAttribute.cs
new file mode 100644
index 0000000..0f37d97
--- /dev/null
+++ b/UnityEngine.PostProcessing/TrackballAttribute.cs
@@ -0,0 +1,11 @@
+namespace UnityEngine.PostProcessing;
+
+public sealed class TrackballAttribute : PropertyAttribute
+{
+ public readonly string method;
+
+ public TrackballAttribute(string method)
+ {
+ this.method = method;
+ }
+}
diff --git a/UnityEngine.PostProcessing/TrackballGroupAttribute.cs b/UnityEngine.PostProcessing/TrackballGroupAttribute.cs
new file mode 100644
index 0000000..c64ea0e
--- /dev/null
+++ b/UnityEngine.PostProcessing/TrackballGroupAttribute.cs
@@ -0,0 +1,5 @@
+namespace UnityEngine.PostProcessing;
+
+public sealed class TrackballGroupAttribute : PropertyAttribute
+{
+}
diff --git a/UnityEngine.PostProcessing/UserLutComponent.cs b/UnityEngine.PostProcessing/UserLutComponent.cs
new file mode 100644
index 0000000..51f291a
--- /dev/null
+++ b/UnityEngine.PostProcessing/UserLutComponent.cs
@@ -0,0 +1,35 @@
+namespace UnityEngine.PostProcessing;
+
+public sealed class UserLutComponent : PostProcessingComponentRenderTexture<UserLutModel>
+{
+ private static class Uniforms
+ {
+ internal static readonly int _UserLut = Shader.PropertyToID("_UserLut");
+
+ internal static readonly int _UserLut_Params = Shader.PropertyToID("_UserLut_Params");
+ }
+
+ public override bool active
+ {
+ get
+ {
+ UserLutModel.Settings settings = base.model.settings;
+ return base.model.enabled && settings.lut != null && settings.contribution > 0f && settings.lut.height == (int)Mathf.Sqrt(settings.lut.width) && !context.interrupted;
+ }
+ }
+
+ public override void Prepare(Material uberMaterial)
+ {
+ UserLutModel.Settings settings = base.model.settings;
+ uberMaterial.EnableKeyword("USER_LUT");
+ uberMaterial.SetTexture(Uniforms._UserLut, settings.lut);
+ uberMaterial.SetVector(Uniforms._UserLut_Params, new Vector4(1f / (float)settings.lut.width, 1f / (float)settings.lut.height, (float)settings.lut.height - 1f, settings.contribution));
+ }
+
+ public void OnGUI()
+ {
+ UserLutModel.Settings settings = base.model.settings;
+ Rect position = new Rect(context.viewport.x * (float)Screen.width + 8f, 8f, settings.lut.width, settings.lut.height);
+ GUI.DrawTexture(position, settings.lut);
+ }
+}
diff --git a/UnityEngine.PostProcessing/UserLutModel.cs b/UnityEngine.PostProcessing/UserLutModel.cs
new file mode 100644
index 0000000..8cab02f
--- /dev/null
+++ b/UnityEngine.PostProcessing/UserLutModel.cs
@@ -0,0 +1,49 @@
+using System;
+
+namespace UnityEngine.PostProcessing;
+
+[Serializable]
+public class UserLutModel : PostProcessingModel
+{
+ [Serializable]
+ public struct Settings
+ {
+ [Tooltip("Custom lookup texture (strip format, e.g. 256x16).")]
+ public Texture2D lut;
+
+ [Range(0f, 1f)]
+ [Tooltip("Blending factor.")]
+ public float contribution;
+
+ public static Settings defaultSettings
+ {
+ get
+ {
+ Settings result = default(Settings);
+ result.lut = null;
+ result.contribution = 1f;
+ return result;
+ }
+ }
+ }
+
+ [SerializeField]
+ private Settings m_Settings = Settings.defaultSettings;
+
+ public Settings settings
+ {
+ get
+ {
+ return m_Settings;
+ }
+ set
+ {
+ m_Settings = value;
+ }
+ }
+
+ public override void Reset()
+ {
+ m_Settings = Settings.defaultSettings;
+ }
+}
diff --git a/UnityEngine.PostProcessing/VignetteComponent.cs b/UnityEngine.PostProcessing/VignetteComponent.cs
new file mode 100644
index 0000000..4b2f506
--- /dev/null
+++ b/UnityEngine.PostProcessing/VignetteComponent.cs
@@ -0,0 +1,38 @@
+namespace UnityEngine.PostProcessing;
+
+public sealed class VignetteComponent : PostProcessingComponentRenderTexture<VignetteModel>
+{
+ private static class Uniforms
+ {
+ internal static readonly int _Vignette_Color = Shader.PropertyToID("_Vignette_Color");
+
+ internal static readonly int _Vignette_Center = Shader.PropertyToID("_Vignette_Center");
+
+ internal static readonly int _Vignette_Settings = Shader.PropertyToID("_Vignette_Settings");
+
+ internal static readonly int _Vignette_Mask = Shader.PropertyToID("_Vignette_Mask");
+
+ internal static readonly int _Vignette_Opacity = Shader.PropertyToID("_Vignette_Opacity");
+ }
+
+ public override bool active => base.model.enabled && !context.interrupted;
+
+ public override void Prepare(Material uberMaterial)
+ {
+ VignetteModel.Settings settings = base.model.settings;
+ uberMaterial.SetColor(Uniforms._Vignette_Color, settings.color);
+ if (settings.mode == VignetteModel.Mode.Classic)
+ {
+ uberMaterial.SetVector(Uniforms._Vignette_Center, settings.center);
+ uberMaterial.EnableKeyword("VIGNETTE_CLASSIC");
+ float z = (1f - settings.roundness) * 6f + settings.roundness;
+ uberMaterial.SetVector(Uniforms._Vignette_Settings, new Vector4(settings.intensity * 3f, settings.smoothness * 5f, z, (!settings.rounded) ? 0f : 1f));
+ }
+ else if (settings.mode == VignetteModel.Mode.Masked && settings.mask != null && settings.opacity > 0f)
+ {
+ uberMaterial.EnableKeyword("VIGNETTE_MASKED");
+ uberMaterial.SetTexture(Uniforms._Vignette_Mask, settings.mask);
+ uberMaterial.SetFloat(Uniforms._Vignette_Opacity, settings.opacity);
+ }
+ }
+}
diff --git a/UnityEngine.PostProcessing/VignetteModel.cs b/UnityEngine.PostProcessing/VignetteModel.cs
new file mode 100644
index 0000000..963ce2d
--- /dev/null
+++ b/UnityEngine.PostProcessing/VignetteModel.cs
@@ -0,0 +1,87 @@
+using System;
+
+namespace UnityEngine.PostProcessing;
+
+[Serializable]
+public class VignetteModel : PostProcessingModel
+{
+ public enum Mode
+ {
+ Classic,
+ Masked
+ }
+
+ [Serializable]
+ public struct Settings
+ {
+ [Tooltip("Use the \"Classic\" mode for parametric controls. Use the \"Masked\" mode to use your own texture mask.")]
+ public Mode mode;
+
+ [ColorUsage(false)]
+ [Tooltip("Vignette color. Use the alpha channel for transparency.")]
+ public Color color;
+
+ [Tooltip("Sets the vignette center point (screen center is [0.5,0.5]).")]
+ public Vector2 center;
+
+ [Range(0f, 1f)]
+ [Tooltip("Amount of vignetting on screen.")]
+ public float intensity;
+
+ [Range(0.01f, 1f)]
+ [Tooltip("Smoothness of the vignette borders.")]
+ public float smoothness;
+
+ [Range(0f, 1f)]
+ [Tooltip("Lower values will make a square-ish vignette.")]
+ public float roundness;
+
+ [Tooltip("A black and white mask to use as a vignette.")]
+ public Texture mask;
+
+ [Range(0f, 1f)]
+ [Tooltip("Mask opacity.")]
+ public float opacity;
+
+ [Tooltip("Should the vignette be perfectly round or be dependent on the current aspect ratio?")]
+ public bool rounded;
+
+ public static Settings defaultSettings
+ {
+ get
+ {
+ Settings result = default(Settings);
+ result.mode = Mode.Classic;
+ result.color = new Color(0f, 0f, 0f, 1f);
+ result.center = new Vector2(0.5f, 0.5f);
+ result.intensity = 0.45f;
+ result.smoothness = 0.2f;
+ result.roundness = 1f;
+ result.mask = null;
+ result.opacity = 1f;
+ result.rounded = false;
+ return result;
+ }
+ }
+ }
+
+ [SerializeField]
+ private Settings m_Settings = Settings.defaultSettings;
+
+ public Settings settings
+ {
+ get
+ {
+ return m_Settings;
+ }
+ set
+ {
+ m_Settings = value;
+ }
+ }
+
+ public override void Reset()
+ {
+ m_Settings = Settings.defaultSettings;
+ }
+}