177 lines
5.5 KiB
C#
177 lines
5.5 KiB
C#
using System;
|
|
using UnityEngine;
|
|
|
|
[AddComponentMenu("Enviro/Effects/Fog Image Effect")]
|
|
[ExecuteInEditMode]
|
|
[RequireComponent(typeof(Camera))]
|
|
public class EnviroFog : EnviroEffects
|
|
{
|
|
public bool distanceFog = true;
|
|
|
|
public bool useRadialDistance;
|
|
|
|
public bool heightFog = true;
|
|
|
|
public float height = 1f;
|
|
|
|
[Range(0.001f, 10f)]
|
|
public float heightDensity = 2f;
|
|
|
|
public float startDistance;
|
|
|
|
public Shader fogShader;
|
|
|
|
public Material fogMaterial;
|
|
|
|
private Texture3D _noiseTexture;
|
|
|
|
public override bool CheckResources()
|
|
{
|
|
CheckSupport(true);
|
|
fogMaterial = CheckShaderAndCreateMaterial(fogShader, fogMaterial);
|
|
if (!isSupported)
|
|
{
|
|
ReportAutoDisable();
|
|
}
|
|
return isSupported;
|
|
}
|
|
|
|
private new void Start()
|
|
{
|
|
LoadNoise3dTexture();
|
|
}
|
|
|
|
private void OnRenderImage(RenderTexture source, RenderTexture destination)
|
|
{
|
|
if (!CheckResources() || (!distanceFog && !heightFog))
|
|
{
|
|
Graphics.Blit(source, destination);
|
|
return;
|
|
}
|
|
Camera component = GetComponent<Camera>();
|
|
Transform transform = component.transform;
|
|
float nearClipPlane = component.nearClipPlane;
|
|
float farClipPlane = component.farClipPlane;
|
|
float fieldOfView = component.fieldOfView;
|
|
float aspect = component.aspect;
|
|
Matrix4x4 identity = Matrix4x4.identity;
|
|
float num = fieldOfView * 0.5f;
|
|
Vector3 vector = transform.right * nearClipPlane * Mathf.Tan(num * ((float)Math.PI / 180f)) * aspect;
|
|
Vector3 vector2 = transform.up * nearClipPlane * Mathf.Tan(num * ((float)Math.PI / 180f));
|
|
Vector3 vector3 = transform.forward * nearClipPlane - vector + vector2;
|
|
float num2 = vector3.magnitude * farClipPlane / nearClipPlane;
|
|
vector3.Normalize();
|
|
vector3 *= num2;
|
|
Vector3 vector4 = transform.forward * nearClipPlane + vector + vector2;
|
|
vector4.Normalize();
|
|
vector4 *= num2;
|
|
Vector3 vector5 = transform.forward * nearClipPlane + vector - vector2;
|
|
vector5.Normalize();
|
|
vector5 *= num2;
|
|
Vector3 vector6 = transform.forward * nearClipPlane - vector - vector2;
|
|
vector6.Normalize();
|
|
vector6 *= num2;
|
|
identity.SetRow(0, vector3);
|
|
identity.SetRow(1, vector4);
|
|
identity.SetRow(2, vector5);
|
|
identity.SetRow(3, vector6);
|
|
Vector3 position = transform.position;
|
|
float num3 = position.y - height;
|
|
float z = ((!(num3 <= 0f)) ? 0f : 1f);
|
|
fogMaterial.SetMatrix("_FrustumCornersWS", identity);
|
|
fogMaterial.SetVector("_CameraWS", position);
|
|
fogMaterial.SetVector("_HeightParams", new Vector4(height, num3, z, heightDensity * 0.5f));
|
|
fogMaterial.SetVector("_DistanceParams", new Vector4(0f - Mathf.Max(startDistance, 0f), 0f, 0f, 0f));
|
|
fogMaterial.SetTexture("_NoiseTexture", _noiseTexture);
|
|
FogMode fogMode = RenderSettings.fogMode;
|
|
float fogDensity = RenderSettings.fogDensity;
|
|
float fogStartDistance = RenderSettings.fogStartDistance;
|
|
float fogEndDistance = RenderSettings.fogEndDistance;
|
|
bool flag = fogMode == FogMode.Linear;
|
|
float num4 = ((!flag) ? 0f : (fogEndDistance - fogStartDistance));
|
|
float num5 = ((!(Mathf.Abs(num4) > 0.0001f)) ? 0f : (1f / num4));
|
|
Vector4 value = default(Vector4);
|
|
value.x = fogDensity * 1.2011224f;
|
|
value.y = fogDensity * 1.442695f;
|
|
value.z = ((!flag) ? 0f : (0f - num5));
|
|
value.w = ((!flag) ? 0f : (fogEndDistance * num5));
|
|
fogMaterial.SetVector("_SceneFogParams", value);
|
|
fogMaterial.SetVector("_SceneFogMode", new Vector4((float)fogMode, useRadialDistance ? 1 : 0, 0f, 0f));
|
|
int num6 = 0;
|
|
CustomGraphicsBlit(passNr: (!distanceFog || !heightFog) ? (distanceFog ? 1 : 2) : 0, source: source, dest: destination, fxMaterial: fogMaterial);
|
|
}
|
|
|
|
private static void CustomGraphicsBlit(RenderTexture source, RenderTexture dest, Material fxMaterial, int passNr)
|
|
{
|
|
RenderTexture.active = dest;
|
|
fxMaterial.SetTexture("_MainTex", source);
|
|
GL.PushMatrix();
|
|
GL.LoadOrtho();
|
|
fxMaterial.SetPass(passNr);
|
|
GL.Begin(7);
|
|
GL.MultiTexCoord2(0, 0f, 0f);
|
|
GL.Vertex3(0f, 0f, 3f);
|
|
GL.MultiTexCoord2(0, 1f, 0f);
|
|
GL.Vertex3(1f, 0f, 2f);
|
|
GL.MultiTexCoord2(0, 1f, 1f);
|
|
GL.Vertex3(1f, 1f, 1f);
|
|
GL.MultiTexCoord2(0, 0f, 1f);
|
|
GL.Vertex3(0f, 1f, 0f);
|
|
GL.End();
|
|
GL.PopMatrix();
|
|
}
|
|
|
|
private void LoadNoise3dTexture()
|
|
{
|
|
TextAsset textAsset = Resources.Load("NoiseVolume") as TextAsset;
|
|
byte[] bytes = textAsset.bytes;
|
|
uint num = BitConverter.ToUInt32(textAsset.bytes, 12);
|
|
uint num2 = BitConverter.ToUInt32(textAsset.bytes, 16);
|
|
uint num3 = BitConverter.ToUInt32(textAsset.bytes, 20);
|
|
uint num4 = BitConverter.ToUInt32(textAsset.bytes, 24);
|
|
uint num5 = BitConverter.ToUInt32(textAsset.bytes, 80);
|
|
uint num6 = BitConverter.ToUInt32(textAsset.bytes, 88);
|
|
if (num6 == 0)
|
|
{
|
|
num6 = num3 / num2 * 8;
|
|
}
|
|
_noiseTexture = new Texture3D((int)num2, (int)num, (int)num4, TextureFormat.RGBA32, false);
|
|
_noiseTexture.name = "3D Noise";
|
|
Color[] array = new Color[num2 * num * num4];
|
|
uint num7 = 128u;
|
|
if (textAsset.bytes[84] == 68 && textAsset.bytes[85] == 88 && textAsset.bytes[86] == 49 && textAsset.bytes[87] == 48 && (num5 & 4) != 0)
|
|
{
|
|
uint num8 = BitConverter.ToUInt32(textAsset.bytes, (int)num7);
|
|
if (num8 >= 60 && num8 <= 65)
|
|
{
|
|
num6 = 8u;
|
|
}
|
|
else if (num8 >= 48 && num8 <= 52)
|
|
{
|
|
num6 = 16u;
|
|
}
|
|
else if (num8 >= 27 && num8 <= 32)
|
|
{
|
|
num6 = 32u;
|
|
}
|
|
num7 += 20;
|
|
}
|
|
uint num9 = num6 / 8;
|
|
num3 = (num2 * num6 + 7) / 8;
|
|
for (int i = 0; i < num4; i++)
|
|
{
|
|
for (int j = 0; j < num; j++)
|
|
{
|
|
for (int k = 0; k < num2; k++)
|
|
{
|
|
float num10 = (float)(int)bytes[num7 + k * num9] / 255f;
|
|
array[k + j * num2 + i * num2 * num] = new Color(num10, num10, num10, num10);
|
|
}
|
|
num7 += num3;
|
|
}
|
|
}
|
|
_noiseTexture.SetPixels(array);
|
|
_noiseTexture.Apply();
|
|
}
|
|
}
|