293 lines
12 KiB
C#
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");
|
|
}
|
|
}
|
|
}
|