summaryrefslogtreecommitdiff
path: root/Thronefall/FlatKit/FlatKitFog.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Thronefall/FlatKit/FlatKitFog.cs')
-rw-r--r--Thronefall/FlatKit/FlatKitFog.cs175
1 files changed, 175 insertions, 0 deletions
diff --git a/Thronefall/FlatKit/FlatKitFog.cs b/Thronefall/FlatKit/FlatKitFog.cs
new file mode 100644
index 0000000..6991bf9
--- /dev/null
+++ b/Thronefall/FlatKit/FlatKitFog.cs
@@ -0,0 +1,175 @@
+using UnityEngine;
+using UnityEngine.Rendering;
+using UnityEngine.Rendering.Universal;
+
+namespace FlatKit;
+
+public class FlatKitFog : ScriptableRendererFeature
+{
+ [Tooltip("To create new settings use 'Create > FlatKit > Fog Settings'.")]
+ public FogSettings settings;
+
+ [SerializeField]
+ [HideInInspector]
+ private Material _effectMaterial;
+
+ private BlitTexturePass _blitTexturePass;
+
+ private RenderTargetHandle _fogTexture;
+
+ private Texture2D _lutDepth;
+
+ private Texture2D _lutHeight;
+
+ private static readonly string FogShaderName = "Hidden/FlatKit/FogFilter";
+
+ private static readonly int DistanceLut = Shader.PropertyToID("_DistanceLUT");
+
+ private static readonly int Near = Shader.PropertyToID("_Near");
+
+ private static readonly int Far = Shader.PropertyToID("_Far");
+
+ private static readonly int UseDistanceFog = Shader.PropertyToID("_UseDistanceFog");
+
+ private static readonly int UseDistanceFogOnSky = Shader.PropertyToID("_UseDistanceFogOnSky");
+
+ private static readonly int DistanceFogIntensity = Shader.PropertyToID("_DistanceFogIntensity");
+
+ private static readonly int HeightLut = Shader.PropertyToID("_HeightLUT");
+
+ private static readonly int LowWorldY = Shader.PropertyToID("_LowWorldY");
+
+ private static readonly int HighWorldY = Shader.PropertyToID("_HighWorldY");
+
+ private static readonly int UseHeightFog = Shader.PropertyToID("_UseHeightFog");
+
+ private static readonly int UseHeightFogOnSky = Shader.PropertyToID("_UseHeightFogOnSky");
+
+ private static readonly int HeightFogIntensity = Shader.PropertyToID("_HeightFogIntensity");
+
+ private static readonly int DistanceHeightBlend = Shader.PropertyToID("_DistanceHeightBlend");
+
+ public override void Create()
+ {
+ if (settings == null)
+ {
+ Debug.LogWarning("[FlatKit] Missing Fog Settings");
+ return;
+ }
+ _blitTexturePass = new BlitTexturePass
+ {
+ renderPassEvent = settings.renderEvent
+ };
+ _fogTexture.Init("_EffectTexture");
+ }
+
+ public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
+ {
+ if (settings == null)
+ {
+ Debug.LogWarning("[FlatKit] Missing Fog Settings");
+ }
+ else if (CreateMaterials())
+ {
+ SetMaterialProperties();
+ _blitTexturePass.Setup(_effectMaterial, useDepth: true, useNormals: false, useColor: false);
+ renderer.EnqueuePass(_blitTexturePass);
+ }
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ CoreUtils.Destroy(_effectMaterial);
+ }
+
+ private bool CreateMaterials()
+ {
+ if (_effectMaterial == null)
+ {
+ Shader shader = Shader.Find(FogShaderName);
+ Shader shader2 = Shader.Find(BlitTexturePass.CopyEffectShaderName);
+ if (shader == null || shader2 == null)
+ {
+ return false;
+ }
+ _effectMaterial = CoreUtils.CreateEngineMaterial(shader);
+ }
+ return true;
+ }
+
+ private void SetMaterialProperties()
+ {
+ if (!(_effectMaterial == null))
+ {
+ UpdateDistanceLut();
+ _effectMaterial.SetTexture(DistanceLut, _lutDepth);
+ _effectMaterial.SetFloat(Near, settings.near);
+ _effectMaterial.SetFloat(Far, settings.far);
+ _effectMaterial.SetFloat(UseDistanceFog, settings.useDistance ? 1f : 0f);
+ _effectMaterial.SetFloat(UseDistanceFogOnSky, settings.useDistanceFogOnSky ? 1f : 0f);
+ _effectMaterial.SetFloat(DistanceFogIntensity, settings.distanceFogIntensity);
+ UpdateHeightLut();
+ _effectMaterial.SetTexture(HeightLut, _lutHeight);
+ _effectMaterial.SetFloat(LowWorldY, settings.low);
+ _effectMaterial.SetFloat(HighWorldY, settings.high);
+ _effectMaterial.SetFloat(UseHeightFog, settings.useHeight ? 1f : 0f);
+ _effectMaterial.SetFloat(UseHeightFogOnSky, settings.useHeightFogOnSky ? 1f : 0f);
+ _effectMaterial.SetFloat(HeightFogIntensity, settings.heightFogIntensity);
+ _effectMaterial.SetFloat(DistanceHeightBlend, settings.distanceHeightBlend);
+ }
+ }
+
+ private void UpdateDistanceLut()
+ {
+ if (settings.distanceGradient == null)
+ {
+ return;
+ }
+ if (_lutDepth != null)
+ {
+ Object.DestroyImmediate(_lutDepth);
+ }
+ _lutDepth = new Texture2D(256, 1, TextureFormat.RGBA32, mipChain: false)
+ {
+ wrapMode = TextureWrapMode.Clamp,
+ hideFlags = HideFlags.HideAndDontSave,
+ filterMode = FilterMode.Bilinear
+ };
+ for (float num = 0f; num < 256f; num += 1f)
+ {
+ Color color = settings.distanceGradient.Evaluate(num / 255f);
+ for (float num2 = 0f; num2 < 1f; num2 += 1f)
+ {
+ _lutDepth.SetPixel(Mathf.CeilToInt(num), Mathf.CeilToInt(num2), color);
+ }
+ }
+ _lutDepth.Apply();
+ }
+
+ private void UpdateHeightLut()
+ {
+ if (settings.heightGradient == null)
+ {
+ return;
+ }
+ if (_lutHeight != null)
+ {
+ Object.DestroyImmediate(_lutHeight);
+ }
+ _lutHeight = new Texture2D(256, 1, TextureFormat.RGBA32, mipChain: false)
+ {
+ wrapMode = TextureWrapMode.Clamp,
+ hideFlags = HideFlags.HideAndDontSave,
+ filterMode = FilterMode.Bilinear
+ };
+ for (float num = 0f; num < 256f; num += 1f)
+ {
+ Color color = settings.heightGradient.Evaluate(num / 255f);
+ for (float num2 = 0f; num2 < 1f; num2 += 1f)
+ {
+ _lutHeight.SetPixel(Mathf.CeilToInt(num), Mathf.CeilToInt(num2), color);
+ }
+ }
+ _lutHeight.Apply();
+ }
+}