FiE-Game/Assets/Cinematic Effects/LensAberrations/LensAberrations.cs

328 lines
12 KiB
C#

using UnityEngine;
using System;
namespace UnityStandardAssets.CinematicEffects
{
[ExecuteInEditMode]
[RequireComponent(typeof(Camera))]
[AddComponentMenu("Image Effects/Cinematic/Lens Aberrations")]
public class LensAberrations : MonoBehaviour
{
#region Attributes
[AttributeUsage(AttributeTargets.Field)]
public class SettingsGroup : Attribute
{}
[AttributeUsage(AttributeTargets.Field)]
public class SimpleSetting : Attribute
{}
[AttributeUsage(AttributeTargets.Field)]
public class AdvancedSetting : Attribute
{}
#endregion
#region Settings
public enum SettingsMode
{
Simple,
Advanced
}
[Serializable]
public struct DistortionSettings
{
public bool enabled;
[Range(-100f, 100f), Tooltip("Distortion amount.")]
public float amount;
[Range(0f, 1f), Tooltip("Distortion center point (X axis).")]
public float centerX;
[Range(0f, 1f), Tooltip("Distortion center point (Y axis).")]
public float centerY;
[Range(0f, 2f), Tooltip("Amount multiplier on X axis.")]
public float amountX;
[Range(0f, 2f), Tooltip("Amount multiplier on Y axis.")]
public float amountY;
[Range(0.5f, 2f), Tooltip("Global screen scaling.")]
public float scale;
public static DistortionSettings defaultSettings
{
get
{
return new DistortionSettings
{
enabled = false,
amount = 0f,
centerX = 0.5f,
centerY = 0.5f,
amountX = 1f,
amountY = 1f,
scale = 1f
};
}
}
}
[Serializable]
public struct VignetteSettings
{
public bool enabled;
[Tooltip("Use the \"Advanced\" mode if you need more control over the vignette shape and smoothness at the expense of performances.")]
public SettingsMode mode;
[Tooltip("Vignette color. Use the alpha channel for transparency.")]
public Color color;
[SimpleSetting, Range(0f, 3f), Tooltip("Amount of vignetting on screen.")]
public float intensity;
[SimpleSetting, Range(0.1f, 3f), Tooltip("Smoothness of the vignette borders.")]
public float smoothness;
[AdvancedSetting, Range(0f, 1f), Tooltip("Vignette radius in screen coordinates.")]
public float radius;
[AdvancedSetting, Range(0f, 1f), Tooltip("Smoothness of the vignette border. Tweak this at the same time as \"Falloff\" to get more control over the vignette gradient.")]
public float spread;
[AdvancedSetting, Range(0f, 1f), Tooltip("Smoothness of the vignette border. Tweak this at the same time as \"Spread\" to get more control over the vignette gradient.")]
public float falloff;
[AdvancedSetting, Range(0f, 1f), Tooltip("Lower values will make a square-ish vignette.")]
public float roundness;
[Range(0f, 1f), Tooltip("Blurs the corners of the screen. Leave this at 0 to disable it.")]
public float blur;
[Range(0f, 1f), Tooltip("Desaturate the corners of the screen. Leave this to 0 to disable it.")]
public float desaturate;
public static VignetteSettings defaultSettings
{
get
{
return new VignetteSettings
{
enabled = false,
mode = SettingsMode.Simple,
color = Color.black,
intensity = 1.2f,
smoothness = 1.5f,
radius = 0.7f,
spread = 0.4f,
falloff = 0.5f,
roundness = 1f,
blur = 0f,
desaturate = 0f
};
}
}
}
[Serializable]
public struct ChromaticAberrationSettings
{
public bool enabled;
[Tooltip("Use the \"Advanced\" mode if you need more control over the chromatic aberrations at the expense of performances.")]
public SettingsMode mode;
[Range(-2f, 2f)]
public float tangential;
[AdvancedSetting, Range(0f, 2f)]
public float axial;
[AdvancedSetting, Range(0f, 2f)]
public float contrastDependency;
public static ChromaticAberrationSettings defaultSettings
{
get
{
return new ChromaticAberrationSettings
{
enabled = false,
mode = SettingsMode.Simple,
tangential = 0f,
axial = 0f,
contrastDependency = 0f
};
}
}
}
#endregion
[SettingsGroup]
public DistortionSettings distortion = DistortionSettings.defaultSettings;
[SettingsGroup]
public VignetteSettings vignette = VignetteSettings.defaultSettings;
[SettingsGroup]
public ChromaticAberrationSettings chromaticAberration = ChromaticAberrationSettings.defaultSettings;
private enum Pass
{
BlurPrePass,
Simple,
Desaturate,
Blur,
BlurDesaturate,
ChromaticAberrationOnly,
DistortOnly
}
[SerializeField]
private Shader m_Shader;
public Shader shader
{
get
{
if (m_Shader == null)
m_Shader = Shader.Find("Hidden/LensAberrations");
return m_Shader;
}
}
private Material m_Material;
public Material material
{
get
{
if (m_Material == null)
m_Material = ImageEffectHelper.CheckShaderAndCreateMaterial(shader);
return m_Material;
}
}
private void OnEnable()
{
if (!ImageEffectHelper.IsSupported(shader, false, false, this))
enabled = false;
}
private void OnDisable()
{
if (m_Material != null)
DestroyImmediate(m_Material);
m_Material = null;
}
private void OnRenderImage(RenderTexture source, RenderTexture destination)
{
if (!vignette.enabled && !chromaticAberration.enabled && !distortion.enabled)
{
Graphics.Blit(source, destination);
return;
}
material.DisableKeyword("DISTORT");
material.DisableKeyword("UNDISTORT");
if (distortion.enabled)
{
float amount = 1.6f * Math.Max(Mathf.Abs(distortion.amount), 1f);
float theta = 0.01745329251994f * Math.Min(160f, amount);
float sigma = 2f * Mathf.Tan(theta * 0.5f);
Vector4 p0 = new Vector4(2f * distortion.centerX - 1f, 2f * distortion.centerY - 1f, distortion.amountX, distortion.amountY);
Vector3 p1 = new Vector3(distortion.amount >= 0f ? theta : 1f / theta, sigma, 1f / distortion.scale);
material.SetVector("_DistCenterScale", p0);
material.SetVector("_DistAmount", p1);
if (distortion.amount >= 0f)
material.EnableKeyword("DISTORT");
else
material.EnableKeyword("UNDISTORT");
}
material.SetColor("_VignetteColor", vignette.color);
if (vignette.mode == SettingsMode.Simple)
{
material.SetVector("_Vignette1", new Vector4(vignette.intensity, vignette.smoothness, vignette.blur, 1f - vignette.desaturate));
material.DisableKeyword("VIGNETTE_ADVANCED");
}
else
{
float r1 = 0.5f * vignette.radius;
float r2 = r1 + vignette.spread;
float falloff = Math.Max(0.000001f, (1f - vignette.falloff) * 0.5f);
float roundness = (1f - vignette.roundness) * 6f + vignette.roundness * 2f;
material.SetVector("_Vignette1", new Vector4(r1, 1f / (r2 - r1), vignette.blur, 1f - vignette.desaturate));
material.SetVector("_Vignette2", new Vector3(falloff, 0.5f / falloff, roundness));
material.EnableKeyword("VIGNETTE_ADVANCED");
}
material.DisableKeyword("CHROMATIC_SIMPLE");
material.DisableKeyword("CHROMATIC_ADVANCED");
if (chromaticAberration.enabled && !Mathf.Approximately(chromaticAberration.tangential, 0f))
{
if (chromaticAberration.mode == SettingsMode.Advanced)
material.EnableKeyword("CHROMATIC_ADVANCED");
else
material.EnableKeyword("CHROMATIC_SIMPLE");
Vector4 chromaParams = new Vector4(2.5f * chromaticAberration.tangential, 5f * chromaticAberration.axial, 5f / Mathf.Max(Mathf.Epsilon, chromaticAberration.contrastDependency), 5f);
material.SetVector("_ChromaticAberration", chromaParams);
}
if (vignette.enabled && vignette.blur > 0f)
{
// Downscale + gaussian blur (2 passes)
int w = source.width / 2;
int h = source.height / 2;
RenderTexture tmp1 = RenderTexture.GetTemporary(w, h, 0, source.format);
RenderTexture tmp2 = RenderTexture.GetTemporary(w, h, 0, source.format);
material.SetVector("_BlurPass", new Vector2(1f / w, 0f));
Graphics.Blit(source, tmp1, material, (int)Pass.BlurPrePass);
material.SetVector("_BlurPass", new Vector2(0f, 1f / h));
Graphics.Blit(tmp1, tmp2, material, (int)Pass.BlurPrePass);
material.SetVector("_BlurPass", new Vector2(1f / w, 0f));
Graphics.Blit(tmp2, tmp1, material, (int)Pass.BlurPrePass);
material.SetVector("_BlurPass", new Vector2(0f, 1f / h));
Graphics.Blit(tmp1, tmp2, material, (int)Pass.BlurPrePass);
material.SetTexture("_BlurTex", tmp2);
if (vignette.desaturate > 0f)
Graphics.Blit(source, destination, material, (int)Pass.BlurDesaturate);
else
Graphics.Blit(source, destination, material, (int)Pass.Blur);
RenderTexture.ReleaseTemporary(tmp2);
RenderTexture.ReleaseTemporary(tmp1);
}
else if (vignette.enabled && vignette.desaturate > 0f)
{
Graphics.Blit(source, destination, material, (int)Pass.Desaturate);
}
else if (vignette.enabled)
{
Graphics.Blit(source, destination, material, (int)Pass.Simple);
}
else if (chromaticAberration.enabled)
{
Graphics.Blit(source, destination, material, (int)Pass.ChromaticAberrationOnly);
}
else // Distortion enabled
{
Graphics.Blit(source, destination, material, (int)Pass.DistortOnly);
}
}
}
}