236 lines
6.6 KiB
C#
236 lines
6.6 KiB
C#
//LIVENDA CTAA - CINEMATIC TEMPORAL ANTI ALIASING
|
|
//Copyright Livenda Labs 2016
|
|
//pc-v2.5
|
|
|
|
|
|
using UnityEngine;
|
|
using System.Collections;
|
|
|
|
|
|
[RequireComponent (typeof(Camera))]
|
|
[AddComponentMenu("Image Effects/LIVENDA/CTAA_PC")]
|
|
public class CTAA_PC : MonoBehaviour {
|
|
|
|
//--------------------------------------------------------------
|
|
|
|
[Space(5)]
|
|
public bool CTAA_Enabled = true;
|
|
[Header("CTAA Settings")]
|
|
[Range(3, 20)] public int TemporalStability = 5;
|
|
[Space(5)]
|
|
[Range(0.0f, 1.0f)] public float AdaptiveEnhance = 0.5f;
|
|
[Space(5)]
|
|
[Range(0.4f, 1.4f)] public float TemporalJitterScale = 1.0f;
|
|
|
|
|
|
//--------------------------------------------------------------
|
|
|
|
private bool PreEnhanceEnabled = true;
|
|
private float preEnhanceStrength = 1.0f;
|
|
private float preEnhanceClamp = 0.005f;
|
|
private float AdaptiveResolve = 3000.0f;
|
|
private float jitterScale = 1.0f;
|
|
private float LumaContrastFactor = 1.0f;
|
|
private Material ctaaMat;
|
|
private Material mat_enhance;
|
|
private RenderTexture rtAccum0;
|
|
private RenderTexture rtAccum1;
|
|
private RenderTexture txaaOut;
|
|
private RenderTexture afterPreEnhace;
|
|
private bool firstFrame;
|
|
private bool swap;
|
|
private int frameCounter;
|
|
private float[] x_jit = new float[] { 0.5f, 0.25f, 0.75f, 0.125f, 0.625f, 0.375f, 0.875f, 0.0625f };
|
|
private float[] y_jit = new float[] { 0.3333333f, 0.6666667f, 0.1111111f, 0.4444444f, 0.7777778f, 0.2222222f, 0.5555556f, 0.8888889f };
|
|
|
|
|
|
void SetCTAA_Parameters()
|
|
{
|
|
//Temporal Enhancement
|
|
PreEnhanceEnabled = AdaptiveEnhance > 0.01 ? true : false;
|
|
preEnhanceStrength = Mathf.Lerp (0.2f, 2.0f, AdaptiveEnhance);
|
|
preEnhanceClamp = Mathf.Lerp (0.005f, 0.012f, AdaptiveEnhance);
|
|
jitterScale = TemporalJitterScale;
|
|
AdaptiveResolve = 3000.0f;
|
|
|
|
}
|
|
|
|
private static Material CreateMaterial(string shadername)
|
|
{
|
|
if (string.IsNullOrEmpty(shadername))
|
|
{
|
|
return null;
|
|
}
|
|
Material material = new Material(Shader.Find(shadername));
|
|
material.hideFlags = HideFlags.HideAndDontSave;
|
|
return material;
|
|
}
|
|
|
|
private static void DestroyMaterial(Material mat)
|
|
{
|
|
if (mat != null)
|
|
{
|
|
Object.DestroyImmediate(mat);
|
|
mat = null;
|
|
}
|
|
}
|
|
|
|
void Awake ()
|
|
{
|
|
if (ctaaMat == null) ctaaMat = CreateMaterial("Hidden/CTAA_PC");
|
|
if (mat_enhance == null) mat_enhance = CreateMaterial("Hidden/CTAA_Enhance_PC");
|
|
|
|
firstFrame = true;
|
|
swap = true;
|
|
frameCounter = 0;
|
|
|
|
SetCTAA_Parameters ();
|
|
}
|
|
|
|
|
|
void OnEnable ()
|
|
{
|
|
Camera mcam = GetComponent<Camera> ();
|
|
|
|
mcam.depthTextureMode |= DepthTextureMode.Depth;
|
|
mcam.depthTextureMode |= DepthTextureMode.MotionVectors;
|
|
|
|
}
|
|
|
|
|
|
private void OnDisable()
|
|
{
|
|
DestroyMaterial(ctaaMat);
|
|
DestroyMaterial(mat_enhance);
|
|
DestroyImmediate(rtAccum0); rtAccum0 = null;
|
|
DestroyImmediate(rtAccum1); rtAccum1 = null;
|
|
DestroyImmediate(txaaOut); txaaOut = null;
|
|
DestroyImmediate(afterPreEnhace); afterPreEnhace = null;
|
|
}
|
|
|
|
|
|
|
|
void OnPreCull()
|
|
{
|
|
jitterCam ();
|
|
}
|
|
|
|
|
|
void jitterCam()
|
|
{
|
|
|
|
base.GetComponent<Camera>().nonJitteredProjectionMatrix = base.GetComponent<Camera>().projectionMatrix;
|
|
|
|
base.GetComponent<Camera>().ResetProjectionMatrix();
|
|
|
|
Matrix4x4 matrixx = base.GetComponent<Camera>().projectionMatrix;
|
|
float num = this.x_jit[this.frameCounter]*jitterScale;
|
|
float num2 = this.y_jit[this.frameCounter]*jitterScale;
|
|
matrixx.m02 += ((num * 2f) - 1f) / base.GetComponent<Camera>().pixelRect.width;
|
|
matrixx.m12 += ((num2 * 2f) - 1f) / base.GetComponent<Camera>().pixelRect.height;
|
|
this.frameCounter++;
|
|
this.frameCounter = this.frameCounter % 8;
|
|
base.GetComponent<Camera>().projectionMatrix = matrixx;
|
|
|
|
}
|
|
|
|
|
|
//[ImageEffectOpaque]
|
|
void OnRenderImage (RenderTexture source, RenderTexture destination)
|
|
{
|
|
|
|
if (CTAA_Enabled) {
|
|
SetCTAA_Parameters ();
|
|
} else {
|
|
jitterScale = 0;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
if (((rtAccum0 == null) || (rtAccum0.width != source.width)) || (rtAccum0.height != source.height))
|
|
{
|
|
DestroyImmediate(rtAccum0);
|
|
rtAccum0 = new RenderTexture(source.width, source.height, 0, source.format);
|
|
rtAccum0.hideFlags = HideFlags.HideAndDontSave;
|
|
rtAccum0.filterMode = FilterMode.Bilinear;
|
|
rtAccum0.wrapMode = TextureWrapMode.Clamp;
|
|
|
|
}
|
|
|
|
if (((rtAccum1 == null) || (rtAccum1.width != source.width)) || (rtAccum1.height != source.height))
|
|
{
|
|
DestroyImmediate(rtAccum1);
|
|
rtAccum1 = new RenderTexture(source.width, source.height, 0, source.format);
|
|
rtAccum1.hideFlags = HideFlags.HideAndDontSave;
|
|
rtAccum1.filterMode = FilterMode.Bilinear;
|
|
rtAccum1.wrapMode = TextureWrapMode.Clamp;
|
|
}
|
|
|
|
if (((txaaOut == null) || (txaaOut.width != source.width)) || (txaaOut.height != source.height))
|
|
{
|
|
DestroyImmediate(txaaOut);
|
|
txaaOut = new RenderTexture(source.width, source.height, 0, source.format);
|
|
txaaOut.hideFlags = HideFlags.HideAndDontSave;
|
|
txaaOut.filterMode = FilterMode.Bilinear;
|
|
txaaOut.wrapMode = TextureWrapMode.Clamp;
|
|
}
|
|
|
|
|
|
if (((afterPreEnhace == null) || (afterPreEnhace.width != source.width)) || (afterPreEnhace.height != source.height))
|
|
{
|
|
DestroyImmediate(afterPreEnhace);
|
|
afterPreEnhace = new RenderTexture(source.width, source.height, 0, source.format);
|
|
afterPreEnhace.hideFlags = HideFlags.HideAndDontSave;
|
|
afterPreEnhace.filterMode = source.filterMode;
|
|
afterPreEnhace.wrapMode = TextureWrapMode.Clamp;
|
|
}
|
|
|
|
//-----------------------------------------------------------
|
|
|
|
if(PreEnhanceEnabled)
|
|
{
|
|
mat_enhance.SetFloat("_AEXCTAA", 1.0f / (float)Screen.width);
|
|
mat_enhance.SetFloat("_AEYCTAA", 1.0f / (float)Screen.height);
|
|
mat_enhance.SetFloat("_AESCTAA", preEnhanceStrength);
|
|
mat_enhance.SetFloat("_AEMAXCTAA", preEnhanceClamp);
|
|
Graphics.Blit(source, afterPreEnhace, mat_enhance, 1);
|
|
}
|
|
else
|
|
{
|
|
Graphics.Blit(source, afterPreEnhace);
|
|
}
|
|
|
|
|
|
if (CTAA_Enabled) {
|
|
|
|
if (firstFrame) {
|
|
Graphics.Blit (afterPreEnhace, rtAccum0);
|
|
firstFrame = false;
|
|
}
|
|
|
|
|
|
ctaaMat.SetFloat ("_AdaptiveResolve", AdaptiveResolve);
|
|
ctaaMat.SetVector ("_ControlParams", new Vector4 (0, (float)TemporalStability, LumaContrastFactor, 0));
|
|
|
|
if (swap) {
|
|
ctaaMat.SetTexture ("_Accum", rtAccum0);
|
|
Graphics.Blit (afterPreEnhace, rtAccum1, ctaaMat);
|
|
Graphics.Blit (rtAccum1, txaaOut);
|
|
} else {
|
|
ctaaMat.SetTexture ("_Accum", rtAccum1);
|
|
Graphics.Blit (afterPreEnhace, rtAccum0, ctaaMat);
|
|
Graphics.Blit (rtAccum0, txaaOut);
|
|
}
|
|
|
|
Graphics.Blit (txaaOut, destination);
|
|
|
|
} else {//End Of CTAA Enabled
|
|
|
|
Graphics.Blit(afterPreEnhace, destination);
|
|
}
|
|
|
|
swap = !swap;
|
|
|
|
}
|
|
|
|
}
|