summaryrefslogtreecommitdiff
path: root/DeepSky.Haze/DS_HazeView.cs
diff options
context:
space:
mode:
Diffstat (limited to 'DeepSky.Haze/DS_HazeView.cs')
-rw-r--r--DeepSky.Haze/DS_HazeView.cs1120
1 files changed, 1120 insertions, 0 deletions
diff --git a/DeepSky.Haze/DS_HazeView.cs b/DeepSky.Haze/DS_HazeView.cs
new file mode 100644
index 0000000..925f1a3
--- /dev/null
+++ b/DeepSky.Haze/DS_HazeView.cs
@@ -0,0 +1,1120 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.Rendering;
+
+namespace DeepSky.Haze;
+
+[ExecuteInEditMode]
+[AddComponentMenu("DeepSky Haze/View", 1)]
+public class DS_HazeView : MonoBehaviour
+{
+ private enum SizeFactor
+ {
+ Half = 2,
+ Quarter = 4
+ }
+
+ private enum VolumeSamples
+ {
+ x16,
+ x24,
+ x32
+ }
+
+ private static string kClearRadianceCmdBufferName = "DS_Haze_ClearRadiance";
+
+ private static string kShadowCascadesCmdBufferName = "DS_Haze_ShadowCascadesCopy";
+
+ private static string kDirectionalLightCmdBufferName = "DS_Haze_DirectLight";
+
+ private static string kRenderLightVolumeCmdBufferName = "DS_Haze_RenderLightVolume";
+
+ private static string kPreviousDepthTargetName = "DS_Haze_PreviousDepthTarget";
+
+ private static string kRadianceTarget01Name = "DS_Haze_RadianceTarget_01";
+
+ private static string kRadianceTarget02Name = "DS_Haze_RadianceTarget_02";
+
+ private static Shader kShader;
+
+ [SerializeField]
+ private bool m_OverrideTime;
+
+ [SerializeField]
+ [Range(0f, 1f)]
+ private float m_Time = 0.5f;
+
+ [SerializeField]
+ private bool m_OverrideContextAsset;
+
+ [SerializeField]
+ private DS_HazeContextAsset m_Context;
+
+ [SerializeField]
+ private bool m_OverrideContextVariant;
+
+ [SerializeField]
+ private int m_ContextItemIndex;
+
+ [SerializeField]
+ private Light m_DirectLight;
+
+ [SerializeField]
+ private bool m_RenderAtmosphereVolumetrics = true;
+
+ [SerializeField]
+ private bool m_RenderLocalVolumetrics = true;
+
+ [SerializeField]
+ private bool m_TemporalReprojection = true;
+
+ [SerializeField]
+ private SizeFactor m_DownsampleFactor = SizeFactor.Half;
+
+ [SerializeField]
+ private VolumeSamples m_VolumeSamples;
+
+ [SerializeField]
+ [Range(100f, 5000f)]
+ private int m_GaussianDepthFalloff = 500;
+
+ [SerializeField]
+ [Range(0f, 0.5f)]
+ private float m_UpsampleDepthThreshold = 0.06f;
+
+ [SerializeField]
+ [Range(0.001f, 1f)]
+ private float m_TemporalRejectionScale = 0.1f;
+
+ [SerializeField]
+ [Range(0.1f, 0.9f)]
+ private float m_TemporalBlendFactor = 0.25f;
+
+ private ShadowProjection m_ShadowProjectionType = ShadowProjection.StableFit;
+
+ [SerializeField]
+ private bool m_ApplyAirToSkybox;
+
+ [SerializeField]
+ private bool m_ApplyHazeToSkybox = true;
+
+ [SerializeField]
+ private bool m_ApplyFogExtinctionToSkybox = true;
+
+ [SerializeField]
+ private bool m_ApplyFogLightingToSkybox = true;
+
+ [SerializeField]
+ private bool m_ShowTemporalRejection;
+
+ [SerializeField]
+ private bool m_ShowUpsampleThreshold;
+
+ private Camera m_Camera;
+
+ private RenderTexture m_PerFrameRadianceTarget;
+
+ private RenderTexture m_RadianceTarget_01;
+
+ private RenderTexture m_RadianceTarget_02;
+
+ private RenderTexture m_CurrentRadianceTarget;
+
+ private RenderTexture m_PreviousRadianceTarget;
+
+ private RenderTexture m_PreviousDepthTarget;
+
+ private CommandBuffer m_ShadowCascadesCmdBuffer;
+
+ private CommandBuffer m_DirectionalLightCmdBuffer;
+
+ private CommandBuffer m_ClearRadianceCmdBuffer;
+
+ private CommandBuffer m_RenderNonShadowVolumes;
+
+ private Material m_Material;
+
+ private Matrix4x4 m_PreviousViewProjMatrix = Matrix4x4.identity;
+
+ private Matrix4x4 m_PreviousInvViewProjMatrix = Matrix4x4.identity;
+
+ private float m_InterleavedOffsetIndex;
+
+ private int m_X;
+
+ private int m_Y;
+
+ private RenderingPath m_PreviousRenderPath;
+
+ private ColorSpace m_ColourSpace;
+
+ private List<DS_HazeLightVolume> m_PerFrameLightVolumes = new List<DS_HazeLightVolume>();
+
+ private List<DS_HazeLightVolume> m_PerFrameShadowLightVolumes = new List<DS_HazeLightVolume>();
+
+ private Dictionary<Light, CommandBuffer> m_LightVolumeCmdBuffers = new Dictionary<Light, CommandBuffer>();
+
+ public bool OverrideTime
+ {
+ get
+ {
+ return m_OverrideTime;
+ }
+ set
+ {
+ m_OverrideTime = value;
+ if (value && m_OverrideContextVariant)
+ {
+ m_OverrideContextVariant = false;
+ }
+ }
+ }
+
+ public float Time
+ {
+ get
+ {
+ return m_Time;
+ }
+ set
+ {
+ m_Time = value;
+ }
+ }
+
+ public bool OverrideContextAsset
+ {
+ get
+ {
+ return m_OverrideContextAsset;
+ }
+ set
+ {
+ m_OverrideContextAsset = value;
+ }
+ }
+
+ public DS_HazeContextAsset ContextAsset
+ {
+ get
+ {
+ return m_Context;
+ }
+ set
+ {
+ m_Context = value;
+ }
+ }
+
+ public bool OverrideContextVariant
+ {
+ get
+ {
+ return m_OverrideContextVariant;
+ }
+ set
+ {
+ m_OverrideContextVariant = value;
+ if (value && m_OverrideTime)
+ {
+ m_OverrideTime = false;
+ }
+ }
+ }
+
+ public int ContextItemIndex
+ {
+ get
+ {
+ return m_ContextItemIndex;
+ }
+ set
+ {
+ m_ContextItemIndex = ((value > 0) ? value : 0);
+ }
+ }
+
+ public Light DirectLight
+ {
+ get
+ {
+ return m_DirectLight;
+ }
+ set
+ {
+ m_DirectLight = value;
+ }
+ }
+
+ public Vector2 RadianceTargetSize => new Vector2(m_X, m_Y);
+
+ public int SampleCount => m_VolumeSamples switch
+ {
+ VolumeSamples.x16 => 16,
+ VolumeSamples.x24 => 24,
+ VolumeSamples.x32 => 32,
+ _ => 16,
+ };
+
+ public int DownSampleFactor => (m_DownsampleFactor != SizeFactor.Half) ? 4 : 2;
+
+ public bool RenderAtmosphereVolumetrics
+ {
+ get
+ {
+ return m_RenderAtmosphereVolumetrics;
+ }
+ set
+ {
+ m_RenderAtmosphereVolumetrics = value;
+ SetTemporalKeywords();
+ }
+ }
+
+ public bool RenderLocalVolumetrics
+ {
+ get
+ {
+ return m_RenderLocalVolumetrics;
+ }
+ set
+ {
+ m_RenderLocalVolumetrics = value;
+ SetTemporalKeywords();
+ }
+ }
+
+ public bool TemporalReprojection
+ {
+ get
+ {
+ return m_TemporalReprojection;
+ }
+ set
+ {
+ m_TemporalReprojection = value;
+ SetTemporalKeywords();
+ }
+ }
+
+ public bool WillRenderWithTemporalReprojection => m_TemporalReprojection & (m_RenderAtmosphereVolumetrics | m_RenderLocalVolumetrics);
+
+ public int AntiAliasingLevel()
+ {
+ int result = 1;
+ if (m_Camera.actualRenderingPath == RenderingPath.Forward && m_Camera.allowMSAA && QualitySettings.antiAliasing > 0)
+ {
+ result = QualitySettings.antiAliasing;
+ }
+ return result;
+ }
+
+ private bool CheckHasSystemSupport()
+ {
+ if (!SystemInfo.supportsImageEffects)
+ {
+ Debug.LogError("DeepSky::DS_HazeView: Image effects are not supported on this platform.");
+ base.enabled = false;
+ return false;
+ }
+ if (SystemInfo.graphicsShaderLevel < 30)
+ {
+ Debug.LogError("DeepSky::DS_HazeView: Minimum required shader model (3.0) is not supported on this platform.");
+ base.enabled = false;
+ return false;
+ }
+ if (m_Camera.allowHDR && !SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.ARGBHalf))
+ {
+ Debug.LogError("DeepSky::DS_HazeView: ARGBHalf render texture format is not supported on this platform.");
+ base.enabled = false;
+ return false;
+ }
+ if (!SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.RFloat))
+ {
+ Debug.LogError("DeepSky::DS_HazeView: RFloat render texture format is not supported on this platform.");
+ base.enabled = false;
+ return false;
+ }
+ return true;
+ }
+
+ private void SetMaterialFromContext(DS_HazeContextItem ctx)
+ {
+ if (WillRenderWithTemporalReprojection)
+ {
+ m_InterleavedOffsetIndex += 0.0625f;
+ if (Mathf.Approximately(m_InterleavedOffsetIndex, 1f))
+ {
+ m_InterleavedOffsetIndex = 0f;
+ }
+ }
+ float x = 1f;
+ float y = 1f;
+ float z = 1f;
+ switch (DS_HazeCore.Instance.HeightFalloff)
+ {
+ case DS_HazeCore.HeightFalloffType.None:
+ x = 1f;
+ y = 1f;
+ z = 1f;
+ break;
+ case DS_HazeCore.HeightFalloffType.Exponential:
+ {
+ float num = Mathf.Abs(base.transform.position.y);
+ x = Mathf.Exp((0f - ctx.m_AirDensityHeightFalloff) * num);
+ y = Mathf.Exp((0f - ctx.m_HazeDensityHeightFalloff) * num);
+ z = Mathf.Exp((0f - ctx.m_FogDensityHeightFalloff) * (num - ctx.m_FogStartHeight));
+ break;
+ }
+ }
+ Vector3 vector = ctx.m_AirScatteringScale * new Vector3(0.00116f, 0.0027f, 0.00662f);
+ float x2 = ctx.m_HazeScatteringScale * 0.0021f;
+ float fogScatteringScale = ctx.m_FogScatteringScale;
+ float w = ctx.m_FogExtinctionScale * 0.01f;
+ Vector4 value = new Vector4(ctx.m_AirDensityHeightFalloff, ctx.m_HazeDensityHeightFalloff, 0f, ctx.m_HazeScatteringDirection);
+ Vector4 value2 = new Vector4(x2, (!m_RenderAtmosphereVolumetrics) ? 0f : ctx.m_HazeSecondaryScatteringRatio, fogScatteringScale, w);
+ Vector4 value3 = new Vector4(x, y, z, 0f);
+ Vector4 value4 = new Vector4(ctx.m_FogStartDistance, ctx.m_FogDensityHeightFalloff, ctx.m_FogOpacity, ctx.m_FogScatteringDirection);
+ Vector4 value5 = new Vector4(m_GaussianDepthFalloff, m_UpsampleDepthThreshold * 0.01f, m_TemporalRejectionScale, m_TemporalBlendFactor);
+ m_Material.SetVector("_SamplingParams", value5);
+ m_Material.SetVector("_InterleavedOffset", new Vector4(m_InterleavedOffsetIndex, 0f, 0f, 0f));
+ m_Material.SetMatrix("_PreviousViewProjMatrix", m_PreviousViewProjMatrix);
+ m_Material.SetMatrix("_PreviousInvViewProjMatrix", m_PreviousInvViewProjMatrix);
+ Shader.SetGlobalVector("_DS_BetaParams", value2);
+ Shader.SetGlobalVector("_DS_RBetaS", vector);
+ Shader.SetGlobalVector("_DS_AirHazeParams", value);
+ Shader.SetGlobalVector("_DS_FogParams", value4);
+ Shader.SetGlobalVector("_DS_InitialDensityParams", value3);
+ Vector3 vector2;
+ Color color;
+ if ((bool)m_DirectLight)
+ {
+ vector2 = -m_DirectLight.transform.forward;
+ color = m_DirectLight.color.linear * m_DirectLight.intensity;
+ Shader.SetGlobalColor("_DS_FogAmbientLight", ctx.m_FogAmbientColour.linear * m_DirectLight.intensity);
+ Shader.SetGlobalColor("_DS_FogDirectLight", ctx.m_FogLightColour.linear * m_DirectLight.intensity);
+ }
+ else
+ {
+ vector2 = Vector3.up;
+ color = Color.white;
+ Shader.SetGlobalColor("_DS_FogAmbientLight", ctx.m_FogAmbientColour.linear);
+ Shader.SetGlobalColor("_DS_FogDirectLight", ctx.m_FogLightColour.linear);
+ }
+ Shader.SetGlobalVector("_DS_LightDirection", vector2);
+ Shader.SetGlobalVector("_DS_LightColour", color);
+ }
+
+ private void SetGlobalParamsToNull()
+ {
+ Shader.SetGlobalVector("_DS_BetaParams", Vector4.zero);
+ Shader.SetGlobalVector("_DS_RBetaS", Vector4.zero);
+ }
+
+ public void SetDebugKeywords()
+ {
+ if (m_ShowTemporalRejection)
+ {
+ m_Material.EnableKeyword("SHOW_TEMPORAL_REJECTION");
+ }
+ else
+ {
+ m_Material.DisableKeyword("SHOW_TEMPORAL_REJECTION");
+ }
+ if (m_ShowUpsampleThreshold)
+ {
+ m_Material.EnableKeyword("SHOW_UPSAMPLE_THRESHOLD");
+ }
+ else
+ {
+ m_Material.DisableKeyword("SHOW_UPSAMPLE_THRESHOLD");
+ }
+ }
+
+ public void SetSkyboxKeywords()
+ {
+ if (m_ApplyAirToSkybox)
+ {
+ m_Material.EnableKeyword("DS_HAZE_APPLY_RAYLEIGH");
+ }
+ else
+ {
+ m_Material.DisableKeyword("DS_HAZE_APPLY_RAYLEIGH");
+ }
+ if (m_ApplyHazeToSkybox)
+ {
+ m_Material.EnableKeyword("DS_HAZE_APPLY_MIE");
+ }
+ else
+ {
+ m_Material.DisableKeyword("DS_HAZE_APPLY_MIE");
+ }
+ if (m_ApplyFogExtinctionToSkybox)
+ {
+ m_Material.EnableKeyword("DS_HAZE_APPLY_FOG_EXTINCTION");
+ }
+ else
+ {
+ m_Material.DisableKeyword("DS_HAZE_APPLY_FOG_EXTINCTION");
+ }
+ if (m_ApplyFogLightingToSkybox)
+ {
+ m_Material.EnableKeyword("DS_HAZE_APPLY_FOG_RADIANCE");
+ }
+ else
+ {
+ m_Material.DisableKeyword("DS_HAZE_APPLY_FOG_RADIANCE");
+ }
+ }
+
+ public void SetTemporalKeywords()
+ {
+ if (WillRenderWithTemporalReprojection)
+ {
+ m_Material.EnableKeyword("DS_HAZE_TEMPORAL");
+ return;
+ }
+ m_Material.DisableKeyword("DS_HAZE_TEMPORAL");
+ if (m_ShowTemporalRejection)
+ {
+ m_ShowTemporalRejection = false;
+ m_Material.DisableKeyword("SHOW_TEMPORAL_REJECTION");
+ }
+ if ((bool)m_RadianceTarget_01)
+ {
+ m_RadianceTarget_01.Release();
+ UnityEngine.Object.DestroyImmediate(m_RadianceTarget_01);
+ m_RadianceTarget_01 = null;
+ }
+ if ((bool)m_RadianceTarget_02)
+ {
+ m_RadianceTarget_02.Release();
+ UnityEngine.Object.DestroyImmediate(m_RadianceTarget_02);
+ m_RadianceTarget_02 = null;
+ }
+ if ((bool)m_PreviousDepthTarget)
+ {
+ m_PreviousDepthTarget.Release();
+ UnityEngine.Object.DestroyImmediate(m_PreviousDepthTarget);
+ m_PreviousDepthTarget = null;
+ }
+ }
+
+ private void SetShaderKeyWords()
+ {
+ if (m_ShadowProjectionType == ShadowProjection.CloseFit)
+ {
+ m_Material.EnableKeyword("SHADOW_PROJ_CLOSE");
+ }
+ else if (m_ShadowProjectionType == ShadowProjection.StableFit)
+ {
+ m_Material.DisableKeyword("SHADOW_PROJ_CLOSE");
+ }
+ if (DS_HazeCore.Instance != null)
+ {
+ switch (DS_HazeCore.Instance.HeightFalloff)
+ {
+ case DS_HazeCore.HeightFalloffType.None:
+ m_Material.EnableKeyword("DS_HAZE_HEIGHT_FALLOFF_NONE");
+ break;
+ case DS_HazeCore.HeightFalloffType.Exponential:
+ m_Material.DisableKeyword("DS_HAZE_HEIGHT_FALLOFF_NONE");
+ break;
+ default:
+ m_Material.EnableKeyword("DS_HAZE_HEIGHT_FALLOFF_NONE");
+ break;
+ }
+ }
+ }
+
+ private void OnEnable()
+ {
+ SetGlobalParamsToNull();
+ m_Camera = GetComponent<Camera>();
+ if (!m_Camera)
+ {
+ Debug.LogError("DeepSky::DS_HazeView: GameObject '" + base.gameObject.name + "' does not have a camera component!");
+ base.enabled = false;
+ return;
+ }
+ if (!CheckHasSystemSupport())
+ {
+ base.enabled = false;
+ return;
+ }
+ if (kShader == null)
+ {
+ kShader = Resources.Load<Shader>("DS_Haze");
+ }
+ if (m_Material == null)
+ {
+ m_Material = new Material(kShader);
+ m_Material.hideFlags = HideFlags.HideAndDontSave;
+ }
+ if (m_Camera.actualRenderingPath == RenderingPath.Forward && (m_Camera.depthTextureMode & DepthTextureMode.Depth) != DepthTextureMode.Depth)
+ {
+ m_Camera.depthTextureMode |= DepthTextureMode.Depth;
+ }
+ if (m_RenderNonShadowVolumes == null)
+ {
+ CommandBuffer[] commandBuffers = m_Camera.GetCommandBuffers(CameraEvent.BeforeImageEffectsOpaque);
+ bool flag = false;
+ CommandBuffer[] array = commandBuffers;
+ foreach (CommandBuffer commandBuffer in array)
+ {
+ if (commandBuffer.name == kRenderLightVolumeCmdBufferName)
+ {
+ m_RenderNonShadowVolumes = commandBuffer;
+ flag = true;
+ break;
+ }
+ }
+ if (!flag)
+ {
+ m_RenderNonShadowVolumes = new CommandBuffer();
+ m_RenderNonShadowVolumes.name = kRenderLightVolumeCmdBufferName;
+ m_Camera.AddCommandBuffer(CameraEvent.BeforeImageEffectsOpaque, m_RenderNonShadowVolumes);
+ }
+ }
+ m_CurrentRadianceTarget = m_RadianceTarget_01;
+ m_PreviousRadianceTarget = m_RadianceTarget_02;
+ SetSkyboxKeywords();
+ SetDebugKeywords();
+ m_ColourSpace = QualitySettings.activeColorSpace;
+ m_PreviousRenderPath = m_Camera.actualRenderingPath;
+ }
+
+ private void CreateRadianceTarget(string name, out RenderTexture radianceTarget)
+ {
+ if (m_Camera.allowHDR)
+ {
+ radianceTarget = new RenderTexture(m_Camera.pixelWidth, m_Camera.pixelHeight, 0, RenderTextureFormat.ARGBHalf);
+ }
+ else
+ {
+ radianceTarget = new RenderTexture(m_Camera.pixelWidth, m_Camera.pixelHeight, 0, RenderTextureFormat.ARGB32);
+ }
+ radianceTarget.name = name;
+ radianceTarget.antiAliasing = AntiAliasingLevel();
+ radianceTarget.useMipMap = false;
+ radianceTarget.hideFlags = HideFlags.HideAndDontSave;
+ radianceTarget.filterMode = FilterMode.Point;
+ }
+
+ private void CreateDepthTarget(string name, out RenderTexture depthTarget, bool downsample = false)
+ {
+ depthTarget = new RenderTexture((!downsample) ? m_Camera.pixelWidth : m_X, (!downsample) ? m_Camera.pixelHeight : m_Y, 0, RenderTextureFormat.RFloat, RenderTextureReadWrite.Linear);
+ depthTarget.name = name;
+ depthTarget.antiAliasing = 1;
+ depthTarget.useMipMap = false;
+ depthTarget.hideFlags = HideFlags.HideAndDontSave;
+ depthTarget.filterMode = FilterMode.Point;
+ }
+
+ private bool CameraHasClearRadianceCmdBuffer(out CommandBuffer foundCmd)
+ {
+ CommandBuffer[] commandBuffers;
+ if (m_Camera.actualRenderingPath == RenderingPath.DeferredShading)
+ {
+ commandBuffers = m_Camera.GetCommandBuffers(CameraEvent.BeforeGBuffer);
+ }
+ else
+ {
+ CameraEvent evt = (((m_Camera.depthTextureMode & DepthTextureMode.DepthNormals) == DepthTextureMode.DepthNormals) ? CameraEvent.BeforeDepthNormalsTexture : CameraEvent.BeforeDepthTexture);
+ commandBuffers = m_Camera.GetCommandBuffers(evt);
+ }
+ CommandBuffer[] array = commandBuffers;
+ foreach (CommandBuffer commandBuffer in array)
+ {
+ if (commandBuffer.name == kClearRadianceCmdBufferName)
+ {
+ foundCmd = commandBuffer;
+ return true;
+ }
+ }
+ foundCmd = null;
+ return false;
+ }
+
+ private CommandBuffer LightHasCascadesCopyCmdBuffer()
+ {
+ CommandBuffer[] commandBuffers = m_DirectLight.GetCommandBuffers(LightEvent.AfterShadowMap);
+ CommandBuffer[] array = commandBuffers;
+ foreach (CommandBuffer commandBuffer in array)
+ {
+ if (commandBuffer.name == kShadowCascadesCmdBufferName)
+ {
+ return commandBuffer;
+ }
+ }
+ return null;
+ }
+
+ private CommandBuffer LightHasRenderCmdBuffer()
+ {
+ CommandBuffer[] commandBuffers = m_DirectLight.GetCommandBuffers(LightEvent.AfterScreenspaceMask);
+ CommandBuffer[] array = commandBuffers;
+ foreach (CommandBuffer commandBuffer in array)
+ {
+ if (commandBuffer.name == kDirectionalLightCmdBufferName)
+ {
+ return commandBuffer;
+ }
+ }
+ return null;
+ }
+
+ public void RemoveCommandBufferFromLight(Light light)
+ {
+ CommandBuffer[] commandBuffers = light.GetCommandBuffers(LightEvent.AfterShadowMap);
+ for (int i = 0; i < commandBuffers.Length; i++)
+ {
+ if (commandBuffers[i].name == kShadowCascadesCmdBufferName)
+ {
+ light.RemoveCommandBuffer(LightEvent.AfterShadowMap, commandBuffers[i]);
+ break;
+ }
+ }
+ commandBuffers = light.GetCommandBuffers(LightEvent.AfterScreenspaceMask);
+ for (int j = 0; j < commandBuffers.Length; j++)
+ {
+ if (commandBuffers[j].name == kDirectionalLightCmdBufferName)
+ {
+ light.RemoveCommandBuffer(LightEvent.AfterScreenspaceMask, commandBuffers[j]);
+ break;
+ }
+ }
+ }
+
+ private void RenderPathChanged()
+ {
+ if (m_Camera.actualRenderingPath == RenderingPath.Forward && (m_Camera.depthTextureMode & DepthTextureMode.Depth) != DepthTextureMode.Depth)
+ {
+ m_Camera.depthTextureMode |= DepthTextureMode.Depth;
+ }
+ if (m_ClearRadianceCmdBuffer != null)
+ {
+ CameraEvent evt = ((m_PreviousRenderPath != RenderingPath.DeferredShading) ? (((m_Camera.depthTextureMode & DepthTextureMode.DepthNormals) == DepthTextureMode.DepthNormals) ? CameraEvent.BeforeDepthNormalsTexture : CameraEvent.BeforeDepthTexture) : CameraEvent.BeforeGBuffer);
+ CommandBuffer[] commandBuffers = m_Camera.GetCommandBuffers(evt);
+ CommandBuffer[] array = commandBuffers;
+ foreach (CommandBuffer commandBuffer in array)
+ {
+ if (commandBuffer.name == kClearRadianceCmdBufferName)
+ {
+ m_Camera.RemoveCommandBuffer(evt, commandBuffer);
+ break;
+ }
+ }
+ }
+ m_PreviousRenderPath = m_Camera.actualRenderingPath;
+ }
+
+ private void UpdateResources()
+ {
+ m_X = m_Camera.pixelWidth / (int)m_DownsampleFactor;
+ m_Y = m_Camera.pixelHeight / (int)m_DownsampleFactor;
+ if (m_Camera.actualRenderingPath != m_PreviousRenderPath)
+ {
+ RenderPathChanged();
+ }
+ RenderTextureFormat renderTextureFormat = (m_Camera.allowHDR ? RenderTextureFormat.ARGBHalf : RenderTextureFormat.ARGB32);
+ bool flag = m_ColourSpace != QualitySettings.activeColorSpace;
+ m_ColourSpace = QualitySettings.activeColorSpace;
+ if (WillRenderWithTemporalReprojection)
+ {
+ if (m_RadianceTarget_01 == null)
+ {
+ CreateRadianceTarget(kRadianceTarget01Name, out m_RadianceTarget_01);
+ m_CurrentRadianceTarget = m_RadianceTarget_01;
+ }
+ else if (flag || m_RadianceTarget_01.width != m_Camera.pixelWidth || m_RadianceTarget_01.height != m_Camera.pixelHeight || m_RadianceTarget_01.format != renderTextureFormat)
+ {
+ UnityEngine.Object.DestroyImmediate(m_RadianceTarget_01);
+ CreateRadianceTarget(kRadianceTarget01Name, out m_RadianceTarget_01);
+ m_CurrentRadianceTarget = m_RadianceTarget_01;
+ }
+ if (m_RadianceTarget_02 == null)
+ {
+ CreateRadianceTarget(kRadianceTarget02Name, out m_RadianceTarget_02);
+ m_PreviousRadianceTarget = m_RadianceTarget_02;
+ }
+ else if (flag || m_RadianceTarget_02.width != m_Camera.pixelWidth || m_RadianceTarget_02.height != m_Camera.pixelHeight || m_RadianceTarget_02.format != renderTextureFormat)
+ {
+ UnityEngine.Object.DestroyImmediate(m_RadianceTarget_02);
+ CreateRadianceTarget(kRadianceTarget02Name, out m_RadianceTarget_02);
+ m_PreviousRadianceTarget = m_RadianceTarget_02;
+ }
+ if (m_PreviousDepthTarget == null)
+ {
+ CreateDepthTarget(kPreviousDepthTargetName, out m_PreviousDepthTarget);
+ }
+ else if (m_PreviousDepthTarget.width != m_Camera.pixelWidth || m_PreviousDepthTarget.height != m_Camera.pixelHeight)
+ {
+ UnityEngine.Object.DestroyImmediate(m_PreviousDepthTarget);
+ CreateDepthTarget(kPreviousDepthTargetName, out m_PreviousDepthTarget);
+ }
+ }
+ if (m_ClearRadianceCmdBuffer == null)
+ {
+ m_ClearRadianceCmdBuffer = new CommandBuffer();
+ m_ClearRadianceCmdBuffer.name = kClearRadianceCmdBufferName;
+ }
+ CameraEvent evt = ((m_Camera.actualRenderingPath != RenderingPath.DeferredShading) ? (((m_Camera.depthTextureMode & DepthTextureMode.DepthNormals) == DepthTextureMode.DepthNormals) ? CameraEvent.BeforeDepthNormalsTexture : CameraEvent.BeforeDepthTexture) : CameraEvent.BeforeGBuffer);
+ if (!CameraHasClearRadianceCmdBuffer(out var foundCmd))
+ {
+ m_Camera.AddCommandBuffer(evt, m_ClearRadianceCmdBuffer);
+ }
+ else if (foundCmd != m_ClearRadianceCmdBuffer)
+ {
+ m_Camera.RemoveCommandBuffer(evt, foundCmd);
+ foundCmd.Dispose();
+ m_Camera.AddCommandBuffer(evt, m_ClearRadianceCmdBuffer);
+ }
+ if ((bool)m_DirectLight)
+ {
+ m_ShadowCascadesCmdBuffer = LightHasCascadesCopyCmdBuffer();
+ if (m_ShadowCascadesCmdBuffer == null)
+ {
+ m_ShadowCascadesCmdBuffer = new CommandBuffer();
+ m_ShadowCascadesCmdBuffer.name = kShadowCascadesCmdBufferName;
+ m_ShadowCascadesCmdBuffer.SetGlobalTexture("_ShadowCascades", new RenderTargetIdentifier(BuiltinRenderTextureType.CurrentActive));
+ m_DirectLight.AddCommandBuffer(LightEvent.AfterShadowMap, m_ShadowCascadesCmdBuffer);
+ }
+ m_DirectionalLightCmdBuffer = LightHasRenderCmdBuffer();
+ if (m_DirectionalLightCmdBuffer == null)
+ {
+ m_DirectionalLightCmdBuffer = new CommandBuffer();
+ m_DirectionalLightCmdBuffer.name = kDirectionalLightCmdBufferName;
+ m_DirectLight.AddCommandBuffer(LightEvent.AfterScreenspaceMask, m_DirectionalLightCmdBuffer);
+ }
+ if (m_ShadowProjectionType != QualitySettings.shadowProjection)
+ {
+ m_ShadowProjectionType = QualitySettings.shadowProjection;
+ }
+ }
+ }
+
+ private void OnDisable()
+ {
+ SetGlobalParamsToNull();
+ CommandBuffer[] commandBuffers = m_Camera.GetCommandBuffers(CameraEvent.AfterSkybox);
+ CameraEvent evt = ((m_Camera.actualRenderingPath != RenderingPath.DeferredShading) ? (((m_Camera.depthTextureMode & DepthTextureMode.DepthNormals) == DepthTextureMode.DepthNormals) ? CameraEvent.BeforeDepthNormalsTexture : CameraEvent.BeforeDepthTexture) : CameraEvent.BeforeGBuffer);
+ commandBuffers = m_Camera.GetCommandBuffers(evt);
+ CommandBuffer[] array = commandBuffers;
+ foreach (CommandBuffer commandBuffer in array)
+ {
+ if (commandBuffer.name == kClearRadianceCmdBufferName)
+ {
+ m_Camera.RemoveCommandBuffer(evt, commandBuffer);
+ break;
+ }
+ }
+ if ((bool)m_DirectLight)
+ {
+ commandBuffers = m_DirectLight.GetCommandBuffers(LightEvent.AfterShadowMap);
+ CommandBuffer[] array2 = commandBuffers;
+ foreach (CommandBuffer commandBuffer2 in array2)
+ {
+ if (commandBuffer2.name == kShadowCascadesCmdBufferName)
+ {
+ m_DirectLight.RemoveCommandBuffer(LightEvent.AfterShadowMap, commandBuffer2);
+ break;
+ }
+ }
+ commandBuffers = m_DirectLight.GetCommandBuffers(LightEvent.AfterScreenspaceMask);
+ CommandBuffer[] array3 = commandBuffers;
+ foreach (CommandBuffer commandBuffer3 in array3)
+ {
+ if (commandBuffer3.name == kDirectionalLightCmdBufferName)
+ {
+ m_DirectLight.RemoveCommandBuffer(LightEvent.AfterScreenspaceMask, commandBuffer3);
+ break;
+ }
+ }
+ }
+ if (m_LightVolumeCmdBuffers.Count > 0)
+ {
+ foreach (KeyValuePair<Light, CommandBuffer> lightVolumeCmdBuffer in m_LightVolumeCmdBuffers)
+ {
+ lightVolumeCmdBuffer.Key.RemoveCommandBuffer(LightEvent.AfterShadowMap, lightVolumeCmdBuffer.Value);
+ lightVolumeCmdBuffer.Value.Dispose();
+ }
+ m_LightVolumeCmdBuffers.Clear();
+ }
+ if (m_RenderNonShadowVolumes != null)
+ {
+ m_RenderNonShadowVolumes.Clear();
+ }
+ }
+
+ private void OnDestroy()
+ {
+ if ((bool)m_RadianceTarget_01)
+ {
+ m_RadianceTarget_01.Release();
+ UnityEngine.Object.DestroyImmediate(m_RadianceTarget_01);
+ m_RadianceTarget_01 = null;
+ }
+ if ((bool)m_RadianceTarget_02)
+ {
+ m_RadianceTarget_02.Release();
+ UnityEngine.Object.DestroyImmediate(m_RadianceTarget_02);
+ m_RadianceTarget_02 = null;
+ }
+ if ((bool)m_PreviousDepthTarget)
+ {
+ m_PreviousDepthTarget.Release();
+ UnityEngine.Object.DestroyImmediate(m_PreviousDepthTarget);
+ m_PreviousDepthTarget = null;
+ }
+ if (m_ClearRadianceCmdBuffer != null)
+ {
+ if (m_Camera.actualRenderingPath == RenderingPath.DeferredShading)
+ {
+ m_Camera.RemoveCommandBuffer(CameraEvent.BeforeGBuffer, m_ClearRadianceCmdBuffer);
+ }
+ else
+ {
+ CameraEvent evt = (((m_Camera.depthTextureMode & DepthTextureMode.DepthNormals) == DepthTextureMode.DepthNormals) ? CameraEvent.BeforeDepthNormalsTexture : CameraEvent.BeforeDepthTexture);
+ m_Camera.RemoveCommandBuffer(evt, m_ClearRadianceCmdBuffer);
+ }
+ m_ClearRadianceCmdBuffer.Dispose();
+ m_ClearRadianceCmdBuffer = null;
+ }
+ if (m_ShadowCascadesCmdBuffer != null)
+ {
+ if (m_DirectLight != null)
+ {
+ m_DirectLight.RemoveCommandBuffer(LightEvent.AfterShadowMap, m_ShadowCascadesCmdBuffer);
+ }
+ m_ShadowCascadesCmdBuffer.Dispose();
+ m_ShadowCascadesCmdBuffer = null;
+ }
+ if (m_DirectionalLightCmdBuffer != null)
+ {
+ if (m_DirectLight != null)
+ {
+ m_DirectLight.RemoveCommandBuffer(LightEvent.AfterScreenspaceMask, m_DirectionalLightCmdBuffer);
+ }
+ m_DirectionalLightCmdBuffer.Dispose();
+ m_DirectionalLightCmdBuffer = null;
+ }
+ if (m_LightVolumeCmdBuffers.Count > 0)
+ {
+ foreach (KeyValuePair<Light, CommandBuffer> lightVolumeCmdBuffer in m_LightVolumeCmdBuffers)
+ {
+ lightVolumeCmdBuffer.Key.RemoveCommandBuffer(LightEvent.AfterShadowMap, lightVolumeCmdBuffer.Value);
+ lightVolumeCmdBuffer.Value.Dispose();
+ }
+ m_LightVolumeCmdBuffers.Clear();
+ }
+ if (m_RenderNonShadowVolumes != null)
+ {
+ m_Camera.RemoveCommandBuffer(CameraEvent.BeforeImageEffectsOpaque, m_RenderNonShadowVolumes);
+ m_RenderNonShadowVolumes.Dispose();
+ m_RenderNonShadowVolumes = null;
+ }
+ }
+
+ private void OnPreRender()
+ {
+ if (!CheckHasSystemSupport())
+ {
+ base.enabled = false;
+ }
+ UpdateResources();
+ SetShaderKeyWords();
+ RenderTextureFormat format = (m_Camera.allowHDR ? RenderTextureFormat.ARGBHalf : RenderTextureFormat.ARGB32);
+ m_PerFrameRadianceTarget = RenderTexture.GetTemporary(m_X, m_Y, 0, format, RenderTextureReadWrite.Linear, AntiAliasingLevel());
+ m_PerFrameRadianceTarget.name = "_DS_Haze_PerFrameRadiance";
+ m_PerFrameRadianceTarget.filterMode = FilterMode.Point;
+ m_ClearRadianceCmdBuffer.Clear();
+ m_ClearRadianceCmdBuffer.SetRenderTarget(m_PerFrameRadianceTarget);
+ m_ClearRadianceCmdBuffer.ClearRenderTarget(clearDepth: false, clearColor: true, Color.clear);
+ DS_HazeCore instance = DS_HazeCore.Instance;
+ DS_HazeContextItem dS_HazeContextItem = null;
+ if (m_OverrideContextAsset && m_Context != null)
+ {
+ dS_HazeContextItem = ((!m_OverrideContextVariant) ? m_Context.Context.GetContextItemBlended(m_Time) : m_Context.Context.GetItemAtIndex(m_ContextItemIndex));
+ }
+ else
+ {
+ if (instance == null)
+ {
+ SetGlobalParamsToNull();
+ return;
+ }
+ dS_HazeContextItem = instance.GetRenderContextAtPosition(base.transform.position);
+ }
+ if (dS_HazeContextItem == null)
+ {
+ SetGlobalParamsToNull();
+ }
+ else
+ {
+ SetMaterialFromContext(dS_HazeContextItem);
+ float farClipPlane = m_Camera.farClipPlane;
+ float num = m_Camera.fieldOfView * 0.5f;
+ float num2 = Mathf.Tan(num * ((float)Math.PI / 180f));
+ float num3 = num2 * m_Camera.aspect;
+ Vector3 vector = base.transform.forward * farClipPlane;
+ Vector3 vector2 = base.transform.right * num3 * farClipPlane;
+ Vector3 vector3 = base.transform.up * num2 * farClipPlane;
+ m_Material.SetVector("_ViewportCorner", vector - vector2 - vector3);
+ m_Material.SetVector("_ViewportRight", vector2 * 2f);
+ m_Material.SetVector("_ViewportUp", vector3 * 2f);
+ if ((bool)m_DirectLight && m_RenderAtmosphereVolumetrics)
+ {
+ m_DirectionalLightCmdBuffer.Blit(BuiltinRenderTextureType.None, m_PerFrameRadianceTarget, m_Material, (int)(m_VolumeSamples + ((m_DownsampleFactor != SizeFactor.Half) ? 3 : 0)));
+ }
+ }
+ if (!m_RenderLocalVolumetrics)
+ {
+ return;
+ }
+ Matrix4x4 gPUProjectionMatrix = GL.GetGPUProjectionMatrix(m_Camera.projectionMatrix, renderIntoTexture: true);
+ Matrix4x4 viewProjMtx = gPUProjectionMatrix * m_Camera.worldToCameraMatrix;
+ instance.GetRenderLightVolumes(base.transform.position, m_PerFrameLightVolumes, m_PerFrameShadowLightVolumes);
+ if (m_PerFrameLightVolumes.Count > 0)
+ {
+ m_RenderNonShadowVolumes.SetRenderTarget(m_PerFrameRadianceTarget);
+ }
+ foreach (DS_HazeLightVolume perFrameLightVolume in m_PerFrameLightVolumes)
+ {
+ perFrameLightVolume.SetupMaterialPerFrame(viewProjMtx, m_Camera.worldToCameraMatrix, base.transform, (!WillRenderWithTemporalReprojection) ? 0f : m_InterleavedOffsetIndex);
+ perFrameLightVolume.AddLightRenderCommand(base.transform, m_RenderNonShadowVolumes, (int)m_DownsampleFactor);
+ }
+ foreach (DS_HazeLightVolume perFrameShadowLightVolume in m_PerFrameShadowLightVolumes)
+ {
+ perFrameShadowLightVolume.SetupMaterialPerFrame(viewProjMtx, m_Camera.worldToCameraMatrix, base.transform, (!WillRenderWithTemporalReprojection) ? 0f : m_InterleavedOffsetIndex);
+ perFrameShadowLightVolume.FillLightCommandBuffer(m_PerFrameRadianceTarget, base.transform, (int)m_DownsampleFactor);
+ m_LightVolumeCmdBuffers.Add(perFrameShadowLightVolume.LightSource, perFrameShadowLightVolume.RenderCommandBuffer);
+ }
+ }
+
+ private void BlitToMRT(RenderTexture source, RenderTexture[] destination, Material mat, int pass)
+ {
+ RenderBuffer[] array = new RenderBuffer[destination.Length];
+ for (int i = 0; i < destination.Length; i++)
+ {
+ ref RenderBuffer reference = ref array[i];
+ reference = destination[i].colorBuffer;
+ }
+ Graphics.SetRenderTarget(array, destination[0].depthBuffer);
+ mat.SetTexture("_MainTex", source);
+ mat.SetPass(pass);
+ GL.PushMatrix();
+ GL.LoadOrtho();
+ GL.Begin(7);
+ GL.MultiTexCoord2(0, 0f, 0f);
+ GL.Vertex3(0f, 0f, 0.1f);
+ GL.MultiTexCoord2(0, 1f, 0f);
+ GL.Vertex3(1f, 0f, 0.1f);
+ GL.MultiTexCoord2(0, 1f, 1f);
+ GL.Vertex3(1f, 1f, 0.1f);
+ GL.MultiTexCoord2(0, 0f, 1f);
+ GL.Vertex3(0f, 1f, 0.1f);
+ GL.End();
+ GL.PopMatrix();
+ }
+
+ [ImageEffectOpaque]
+ private void OnRenderImage(RenderTexture src, RenderTexture dest)
+ {
+ RenderTexture renderTexture = null;
+ RenderTexture renderTexture2 = null;
+ if (m_RenderAtmosphereVolumetrics || m_RenderLocalVolumetrics)
+ {
+ renderTexture = RenderTexture.GetTemporary(m_X, m_Y, 0, m_Camera.allowHDR ? RenderTextureFormat.ARGBHalf : RenderTextureFormat.ARGB32);
+ renderTexture2 = RenderTexture.GetTemporary(m_X, m_Y, 0, RenderTextureFormat.RFloat, RenderTextureReadWrite.Linear, 1);
+ Graphics.Blit(null, renderTexture2, m_Material, (m_DownsampleFactor != SizeFactor.Half) ? 11 : 10);
+ m_Material.SetTexture("_HalfResDepth", renderTexture2);
+ Graphics.Blit(m_PerFrameRadianceTarget, renderTexture, m_Material, 6);
+ Graphics.Blit(renderTexture, m_PerFrameRadianceTarget, m_Material, 7);
+ if (m_TemporalReprojection)
+ {
+ m_Material.SetTexture("_PrevAccumBuffer", m_PreviousRadianceTarget);
+ m_Material.SetTexture("_PrevDepthBuffer", m_PreviousDepthTarget);
+ }
+ }
+ m_PerFrameRadianceTarget.filterMode = FilterMode.Bilinear;
+ m_Material.SetTexture("_RadianceBuffer", m_PerFrameRadianceTarget);
+ if (dest == null)
+ {
+ RenderTexture temporary = RenderTexture.GetTemporary(src.width, src.height, src.depth, src.format);
+ if (WillRenderWithTemporalReprojection)
+ {
+ RenderTexture[] destination = new RenderTexture[2] { temporary, m_CurrentRadianceTarget };
+ BlitToMRT(src, destination, m_Material, 8);
+ }
+ else
+ {
+ Graphics.Blit(src, temporary, m_Material, 8);
+ }
+ Graphics.Blit((Texture)temporary, (RenderTexture)null);
+ RenderTexture.ReleaseTemporary(temporary);
+ }
+ else if (WillRenderWithTemporalReprojection)
+ {
+ RenderTexture[] destination2 = new RenderTexture[2] { dest, m_CurrentRadianceTarget };
+ BlitToMRT(src, destination2, m_Material, 8);
+ }
+ else
+ {
+ Graphics.Blit(src, dest, m_Material, 8);
+ }
+ if (WillRenderWithTemporalReprojection)
+ {
+ Graphics.Blit(src, m_PreviousDepthTarget, m_Material, 9);
+ Graphics.SetRenderTarget(dest);
+ Shader.SetGlobalTexture("_DS_RadianceBuffer", m_CurrentRadianceTarget);
+ RenderTexture.ReleaseTemporary(m_PerFrameRadianceTarget);
+ }
+ else
+ {
+ Shader.SetGlobalTexture("_DS_RadianceBuffer", m_PerFrameRadianceTarget);
+ }
+ if (renderTexture != null)
+ {
+ RenderTexture.ReleaseTemporary(renderTexture);
+ }
+ if (renderTexture2 != null)
+ {
+ RenderTexture.ReleaseTemporary(renderTexture2);
+ }
+ }
+
+ private void OnPostRender()
+ {
+ if (WillRenderWithTemporalReprojection)
+ {
+ RenderTexture currentRadianceTarget = m_CurrentRadianceTarget;
+ m_CurrentRadianceTarget = m_PreviousRadianceTarget;
+ m_PreviousRadianceTarget = currentRadianceTarget;
+ Matrix4x4 worldToCameraMatrix = m_Camera.worldToCameraMatrix;
+ Matrix4x4 gPUProjectionMatrix = GL.GetGPUProjectionMatrix(m_Camera.projectionMatrix, renderIntoTexture: true);
+ m_PreviousViewProjMatrix = gPUProjectionMatrix * worldToCameraMatrix;
+ m_PreviousInvViewProjMatrix = m_PreviousViewProjMatrix.inverse;
+ }
+ else
+ {
+ RenderTexture.ReleaseTemporary(m_PerFrameRadianceTarget);
+ }
+ if (m_LightVolumeCmdBuffers.Count > 0)
+ {
+ foreach (KeyValuePair<Light, CommandBuffer> lightVolumeCmdBuffer in m_LightVolumeCmdBuffers)
+ {
+ lightVolumeCmdBuffer.Value.Clear();
+ }
+ m_LightVolumeCmdBuffers.Clear();
+ }
+ if ((bool)m_DirectLight)
+ {
+ m_DirectionalLightCmdBuffer.Clear();
+ }
+ m_RenderNonShadowVolumes.Clear();
+ m_PerFrameLightVolumes.Clear();
+ m_PerFrameShadowLightVolumes.Clear();
+ }
+}