Files
2026-03-04 10:03:45 +08:00

293 lines
12 KiB
C#

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<BetterFog>
{
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<CustomRenderer> 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<MeshFilter>().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<BetterFogRenderers>();
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");
}
}
}