using System.Collections.Generic; using INab.BetterFog.Core; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.Rendering.PostProcessing; namespace INab.BetterFog.BIRP { public sealed class BetterFogRenderer : PostProcessEffectRenderer { private const int kMaxIterations = 16; private int[] _blurBuffer1 = new int[16]; private int[] _blurBuffer2 = new int[16]; private BetterFogRenderers betterFogRenderers; public override void Init() { for (int i = 0; i < 16; i++) { _blurBuffer1[i] = Shader.PropertyToID("_MipDown" + i); _blurBuffer2[i] = Shader.PropertyToID("_MipUp" + i); } } private void DrawRenderers(List list, CommandBuffer cmd) { if (!betterFogRenderers) { return; } foreach (CustomRenderer item in list) { if (!item.render) { continue; } Material material = item.material; Renderer renderer = item.renderer; if (!renderer || !material || (!item.alwaysRender && (!renderer.enabled || !renderer.gameObject.activeInHierarchy))) { continue; } if (item.drawAllSubmeshes && !(renderer is ParticleSystemRenderer)) { Mesh mesh = null; if (renderer is SkinnedMeshRenderer) { mesh = (renderer as SkinnedMeshRenderer).sharedMesh; } else if (renderer is MeshRenderer) { mesh = renderer.GetComponent().sharedMesh; } for (int i = 0; i < mesh.subMeshCount; i++) { cmd.DrawRenderer(renderer, material, i, 0); } } else { cmd.DrawRenderer(renderer, material, 0, 0); } } } public override void Render(PostProcessRenderContext context) { CommandBuffer command = context.command; command.BeginSample("Better Fog"); PropertySheet propertySheet = context.propertySheets.Get(Shader.Find("Hidden/INabStudio/BetterFog")); PropertySheet propertySheet2 = context.propertySheets.Get(Shader.Find("Hidden/INabStudio/OnlyDepth")); propertySheet.ClearKeywords(); if (base.settings._UseSunLight.value) { propertySheet.EnableKeyword("_USESUNLIGHT_ON"); } if (base.settings._UseGradient.value) { propertySheet.EnableKeyword("_USEGRADIENT_ON"); } if (base.settings._UseDistanceFog.value) { propertySheet.EnableKeyword("_USEDISTANCEFOG_ON"); } if (base.settings._UseSkyboxHeightFog.value) { propertySheet.EnableKeyword("_USESKYBOXHEIGHTFOG_ON"); } if (base.settings._UseHeightFog.value) { propertySheet.EnableKeyword("_USEHEIGHTFOG_ON"); } if (base.settings._UseNoise.value) { propertySheet.EnableKeyword("_USENOISE_ON"); } propertySheet.properties.SetColor("_SunColor", base.settings._SunColor); propertySheet.properties.SetFloat("_SunPower", base.settings._SunPower); propertySheet.properties.SetFloat("_SunIntensity", base.settings._SunIntensity); propertySheet.properties.SetColor("_FogColor", base.settings._FogColor); propertySheet.properties.SetFloat("_GradientStart", base.settings._GradientStart); propertySheet.properties.SetFloat("_GradientEnd", base.settings._GradientEnd); Texture value = ((base.settings._GradientTexture.value == null) ? RuntimeUtilities.whiteTexture : base.settings._GradientTexture.value); propertySheet.properties.SetTexture("_GradientTexture", value); propertySheet.properties.SetFloat("_EnergyLoss", base.settings._EnergyLoss); propertySheet.properties.SetFloat("_FogIntensity", base.settings._FogIntensity); propertySheet.properties.SetFloat("_UseRadialDistance", base.settings._UseRadialDistance ? 1 : 0); switch (base.settings._FogType.value) { case FogMode.Linear: propertySheet.properties.SetInt("_FogType", 1); break; case FogMode.Exponential: propertySheet.properties.SetInt("_FogType", 2); break; case FogMode.ExponentialSquared: propertySheet.properties.SetInt("_FogType", 3); break; } propertySheet.properties.SetFloat("_DistanceFogOffset", base.settings._DistanceFogOffset); propertySheet.properties.SetFloat("_SkyboxFogIntensity", base.settings._SkyboxFogIntensity); propertySheet.properties.SetFloat("_SkyboxFogHardness", base.settings._SkyboxFogHardness); propertySheet.properties.SetFloat("_SkyboxFogOffset", base.settings._SkyboxFogOffset); propertySheet.properties.SetFloat("_SkyboxFill", base.settings._SkyboxFill); propertySheet.properties.SetFloat("_HeightDensity", Mathf.Pow(base.settings._HeightDensity, 4f)); propertySheet.properties.SetFloat("_Height", base.settings._Height); propertySheet.properties.SetInt("_HeightFogType", (int)base.settings._HeightFogType.value); propertySheet.properties.SetFloat("_Scale1", base.settings._Scale1); propertySheet.properties.SetFloat("_NoiseTimeScale1", base.settings._NoiseTimeScale1); propertySheet.properties.SetFloat("_Lerp1", base.settings._Lerp1); propertySheet.properties.SetFloat("_NoiseDistanceEnd", base.settings._NoiseDistanceEnd); propertySheet.properties.SetFloat("_NoiseIntensity", base.settings._NoiseIntensity); propertySheet.properties.SetFloat("_NoiseEndHardness", base.settings._NoiseEndHardness); propertySheet.properties.SetVector("_NoiseSpeed1", base.settings._NoiseSpeed1); int value2 = 0; int value3 = 0; switch (base.settings._NoiseAffect.value) { case NoiseAffect.DistanceOnly: value2 = 1; value3 = 0; break; case NoiseAffect.HeightOnly: value2 = 0; value3 = 1; break; case NoiseAffect.Both: value2 = 1; value3 = 1; break; } if (!base.settings._UseDistanceFog.value) { value2 = 0; } if (!base.settings._UseHeightFog.value) { value3 = 0; } propertySheet.properties.SetInt("_UseNoiseDistance", value2); propertySheet.properties.SetInt("_UseNoiseHeight", value3); float num = (float)base.settings._SceneEnd - (float)base.settings._SceneStart; float num2 = ((Mathf.Abs(num) > 0.0001f) ? (1f / num) : 0f); Vector4 value4 = default(Vector4); value4.x = (float)base.settings._FogDensity * 1.2011224f; value4.y = (float)base.settings._FogDensity * 1.442695f; value4.z = 0f - num2; value4.w = (float)base.settings._SceneEnd * num2; propertySheet.properties.SetVector("_SceneFogParams", value4); propertySheet.properties.SetMatrix("_InverseView", context.camera.cameraToWorldMatrix); RenderTextureFormat colorFormat = RenderTextureFormat.ARGBHalf; RenderTextureReadWrite readWrite = RenderTextureReadWrite.Default; FilterMode filter = FilterMode.Bilinear; int num3 = Shader.PropertyToID("fogFactorID"); context.GetScreenSpaceTemporaryRT(command, num3, 0, colorFormat, readWrite, filter, context.width, context.height); Camera camera = context.camera; betterFogRenderers = camera.gameObject.GetComponent(); int num4 = Shader.PropertyToID("onlyDepthID"); if ((bool)base.settings._UseCustomDepthTexture) { propertySheet.EnableKeyword("_USECUSTOMDEPTH_ON"); context.GetScreenSpaceTemporaryRT(command, num4, 32, RenderTextureFormat.RFloat, readWrite, FilterMode.Point, context.width, context.height); command.BlitFullscreenTriangle(context.source, num4, propertySheet2, 0); command.SetRenderTarget(num4); command.ClearRenderTarget(clearDepth: true, clearColor: false, Color.black); DrawRenderers(betterFogRenderers.depthRenderers, command); command.SetGlobalTexture("_CustomDepth", num4); } int num5 = Shader.PropertyToID("fogOffsetID"); if ((bool)base.settings._UseFogOffsetTexture) { propertySheet.EnableKeyword("_USEFOGOFFSET_ON"); context.GetScreenSpaceTemporaryRT(command, num5, 32, RenderTextureFormat.RGHalf, readWrite, FilterMode.Point, context.width, context.height); command.SetRenderTarget(num5); command.ClearRenderTarget(clearDepth: true, clearColor: true, Color.black); DrawRenderers(betterFogRenderers.fogOffsetRenderers, command); command.SetGlobalTexture("_FogOffset", num5); } if (!base.settings._UseSSMS) { command.BlitFullscreenTriangle(context.source, num3, propertySheet, 0); command.SetGlobalTexture("_FogFactor_RT", num3); command.BlitFullscreenTriangle(context.source, context.destination, propertySheet, 1); } if ((bool)base.settings._UseSSMS) { int num6 = Shader.PropertyToID("temporaryRT"); context.GetScreenSpaceTemporaryRT(command, num6, 0, colorFormat, readWrite, filter, context.width, context.height); command.BlitFullscreenTriangle(context.source, num3, propertySheet, 0); command.SetGlobalTexture("_FogFactor_RT", num3); command.BlitFullscreenTriangle(context.source, num6, propertySheet, 1); PropertySheet propertySheet3 = context.propertySheets.Get(Shader.Find("Hidden/INabStudio/SSMS")); int width = context.width; int height = context.height; width /= 2; height /= 2; float num7 = Mathf.Log(height, 2f) + (float)base.settings._Radius - 8f; int num8 = (int)num7; int num9 = Mathf.Clamp(num8, 1, 16); var threshold = base.settings._Threshold; propertySheet3.properties.SetFloat("_Threshold", threshold); float num10 = (float)threshold * (float)base.settings._SoftKnee + 1E-05f; Vector3 vector = new Vector3((float)threshold - num10, num10 * 2f, 0.25f / num10); propertySheet3.properties.SetVector("_Curve", vector); bool flag = !base.settings._HighQuality && (bool)base.settings._AntiFlicker; propertySheet3.properties.SetFloat("_PrefilterOffs", flag ? (-0.5f) : 0f); propertySheet3.properties.SetFloat("_SampleScale", 0.5f + num7 - (float)num8); propertySheet3.properties.SetFloat("_Intensity", base.settings._Intensity); Texture value5 = ((base.settings._FadeRamp.value == null) ? RuntimeUtilities.whiteTexture : base.settings._FadeRamp.value); propertySheet3.properties.SetTexture("_FadeTex", value5); propertySheet3.properties.SetFloat("_BlurWeight", base.settings._BlurWeight); propertySheet3.properties.SetFloat("_Radius", base.settings._Radius); propertySheet3.ClearKeywords(); if (base.settings._AntiFlicker.value) { propertySheet3.EnableKeyword("ANTI_FLICKER_ON"); } if (base.settings._HighQuality.value) { propertySheet3.EnableKeyword("_HIGH_QUALITY_ON"); } int num11 = Shader.PropertyToID("prefilteredRT"); context.GetScreenSpaceTemporaryRT(command, num11, 0, colorFormat, readWrite, filter, context.width, context.height); int pass = 0; command.BlitFullscreenTriangle(num6, num11, propertySheet3, pass); int num12 = num11; for (int i = 0; i < num9; i++) { context.GetScreenSpaceTemporaryRT(command, _blurBuffer1[i], 0, colorFormat, readWrite, filter, width, height); context.GetScreenSpaceTemporaryRT(command, _blurBuffer2[i], 0, colorFormat, readWrite, filter, width, height); width = Mathf.Max(width / 2, 1); height = Mathf.Max(height / 2, 1); pass = ((i == 0) ? 1 : 2); command.SetGlobalTexture("_MainTex", num12); command.BlitFullscreenTriangle(num12, _blurBuffer1[i], propertySheet3, pass); num12 = _blurBuffer1[i]; } for (int num13 = num9 - 2; num13 >= 0; num13--) { int num14 = _blurBuffer1[num13]; command.SetGlobalTexture("_BaseTex", num14); pass = 3; command.BlitFullscreenTriangle(num12, _blurBuffer2[num13], propertySheet3, pass); num12 = _blurBuffer2[num13]; } command.SetGlobalTexture("_BaseTex", num6); pass = 4; command.BlitFullscreenTriangle(num12, context.destination, propertySheet3, pass); for (int j = 0; j < 16; j++) { command.ReleaseTemporaryRT(_blurBuffer1[j]); command.ReleaseTemporaryRT(_blurBuffer2[j]); } command.ReleaseTemporaryRT(num11); command.ReleaseTemporaryRT(num6); } command.ReleaseTemporaryRT(num3); if ((bool)base.settings._UseCustomDepthTexture) { command.ReleaseTemporaryRT(num4); } if ((bool)base.settings._UseFogOffsetTexture) { command.ReleaseTemporaryRT(num5); } command.EndSample("Better Fog"); } } }