diff options
Diffstat (limited to 'DeepSky.Haze/DS_HazeView.cs')
-rw-r--r-- | DeepSky.Haze/DS_HazeView.cs | 1120 |
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(); + } +} |