You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

217 lines
8.3 KiB

// Copyright (c) <2015> <Playdead>
// This file is subject to the MIT License as seen in the root of this folder structure (LICENSE.TXT)
// AUTHOR: Lasse Jon Fuglsang Pedersen <lasse@playdead.com>
#if UNITY_5_5_OR_NEWER
#define SUPPORT_STEREO
#endif
using UnityEngine;
[ExecuteInEditMode]
[RequireComponent(typeof(Camera), typeof(FogVolumePlaydeadTAA.FrustumJitter), typeof(FogVolumePlaydeadTAA.VelocityBuffer))]
//[AddComponentMenu("Playdead/TemporalReprojection")]
public class FogVolumeTAA : FogVolumePlaydeadTAA.EffectBase
{
private static RenderBuffer[] mrt = new RenderBuffer[2];
private Camera _FogVolumeCamera;
private FogVolumePlaydeadTAA.FrustumJitter _frustumJitter;
private FogVolumePlaydeadTAA.VelocityBuffer _velocityBuffer;
public Shader reprojectionShader;
private Material reprojectionMaterial;
private RenderTexture[,] reprojectionBuffer;
private int[] reprojectionIndex = new int[2] { -1, -1 };
public enum Neighborhood
{
MinMax3x3,
MinMax3x3Rounded,
MinMax4TapVarying,
};
public Neighborhood neighborhood = Neighborhood.MinMax4TapVarying;
public bool unjitterColorSamples = true;
public bool unjitterNeighborhood = true;
public bool unjitterReprojection = true;
public bool useYCoCg = true;
public bool useClipping = true;
public bool useDilation = false;
public bool useMotionBlur = false;
public bool useOptimizations = false;
[Range(0.0f, 1.0f)]
public float feedbackMin = 0.88f;
[Range(0.0f, 1.0f)]
public float feedbackMax = 0.97f;
public float motionBlurStrength = 1.0f;
public bool motionBlurIgnoreFF = false;
void Reset()
{
_FogVolumeCamera = GetComponent<Camera>();
reprojectionShader = Shader.Find("Hidden/TAA");
_FogVolumeCamera = GetComponent<Camera>();
_frustumJitter = GetComponent<FogVolumePlaydeadTAA.FrustumJitter>();
//_frustumJitter.enabled = false;
_velocityBuffer = GetComponent<FogVolumePlaydeadTAA.VelocityBuffer>();
_velocityBuffer.velocityShader= Shader.Find("Hidden/VelocityBuffer");
}
void Clear()
{
EnsureArray(ref reprojectionIndex, 2);
reprojectionIndex[0] = -1;
reprojectionIndex[1] = -1;
}
void Awake()
{
Reset();
Clear();
}
void Resolve(RenderTexture source, RenderTexture destination)
{
_velocityBuffer.GenerateVelocityBuffer();
EnsureArray(ref reprojectionBuffer, 2, 2);
EnsureArray(ref reprojectionIndex, 2, initialValue: -1);
EnsureMaterial(ref reprojectionMaterial, reprojectionShader);
if (reprojectionMaterial == null)
{
Graphics.Blit(source, destination);
return;
}
#if SUPPORT_STEREO
int eyeIndex = (_FogVolumeCamera.stereoActiveEye == Camera.MonoOrStereoscopicEye.Right) ? 1 : 0;
#else
int eyeIndex = 0;
#endif
int bufferW = source.width;
int bufferH = source.height;
if (EnsureRenderTarget(ref reprojectionBuffer[eyeIndex, 0], bufferW, bufferH, source.format, FilterMode.Bilinear, antiAliasing: source.antiAliasing))
Clear();
if (EnsureRenderTarget(ref reprojectionBuffer[eyeIndex, 1], bufferW, bufferH, source.format, FilterMode.Bilinear, antiAliasing: source.antiAliasing))
Clear();
#if SUPPORT_STEREO
bool stereoEnabled = _FogVolumeCamera.stereoEnabled;
#else
bool stereoEnabled = false;
#endif
#if UNITY_EDITOR
bool allowMotionBlur = !stereoEnabled && Application.isPlaying;
#else
bool allowMotionBlur = !stereoEnabled;
#endif
EnsureKeyword(reprojectionMaterial, "CAMERA_PERSPECTIVE", !_FogVolumeCamera.orthographic);
EnsureKeyword(reprojectionMaterial, "CAMERA_ORTHOGRAPHIC", _FogVolumeCamera.orthographic);
EnsureKeyword(reprojectionMaterial, "MINMAX_3X3", neighborhood == Neighborhood.MinMax3x3);
EnsureKeyword(reprojectionMaterial, "MINMAX_3X3_ROUNDED", neighborhood == Neighborhood.MinMax3x3Rounded);
EnsureKeyword(reprojectionMaterial, "MINMAX_4TAP_VARYING", neighborhood == Neighborhood.MinMax4TapVarying);
EnsureKeyword(reprojectionMaterial, "UNJITTER_COLORSAMPLES", unjitterColorSamples);
EnsureKeyword(reprojectionMaterial, "UNJITTER_NEIGHBORHOOD", unjitterNeighborhood);
EnsureKeyword(reprojectionMaterial, "UNJITTER_REPROJECTION", unjitterReprojection);
EnsureKeyword(reprojectionMaterial, "USE_YCOCG", useYCoCg);
EnsureKeyword(reprojectionMaterial, "USE_CLIPPING", useClipping);
EnsureKeyword(reprojectionMaterial, "USE_DILATION", useDilation);
EnsureKeyword(reprojectionMaterial, "USE_MOTION_BLUR", useMotionBlur && allowMotionBlur);
EnsureKeyword(reprojectionMaterial, "USE_MOTION_BLUR_NEIGHBORMAX", _velocityBuffer.activeVelocityNeighborMax != null);
EnsureKeyword(reprojectionMaterial, "USE_OPTIMIZATIONS", useOptimizations);
if (reprojectionIndex[eyeIndex] == -1)// bootstrap
{
reprojectionIndex[eyeIndex] = 0;
reprojectionBuffer[eyeIndex, reprojectionIndex[eyeIndex]].DiscardContents();
Graphics.Blit(source, reprojectionBuffer[eyeIndex, reprojectionIndex[eyeIndex]]);
}
int indexRead = reprojectionIndex[eyeIndex];
int indexWrite = (reprojectionIndex[eyeIndex] + 1) % 2;
Vector4 jitterUV = _frustumJitter.activeSample;
jitterUV.x /= bufferW;
jitterUV.y /= bufferH;
jitterUV.z /= bufferW;
jitterUV.w /= bufferH;
reprojectionMaterial.SetVector("_JitterUV", jitterUV);
reprojectionMaterial.SetTexture("_VelocityBuffer", _velocityBuffer.activeVelocityBuffer);
reprojectionMaterial.SetTexture("_VelocityNeighborMax", _velocityBuffer.activeVelocityNeighborMax);
reprojectionMaterial.SetTexture("_MainTex", source);
reprojectionMaterial.SetTexture("_PrevTex", reprojectionBuffer[eyeIndex, indexRead]);
reprojectionMaterial.SetFloat("_FeedbackMin", feedbackMin);
reprojectionMaterial.SetFloat("_FeedbackMax", feedbackMax);
// reprojectionMaterial.SetFloat("_MotionScale", motionBlurStrength * (motionBlurIgnoreFF ? Mathf.Min(1.0f, 1.0f / _velocityBuffer.timeScale) : 1.0f));
// reproject frame n-1 into output + history buffer
{
mrt[0] = reprojectionBuffer[eyeIndex, indexWrite].colorBuffer;
mrt[1] = destination.colorBuffer;
Graphics.SetRenderTarget(mrt, source.depthBuffer);
reprojectionMaterial.SetPass(0);
reprojectionBuffer[eyeIndex, indexWrite].DiscardContents();
DrawFullscreenQuad();
reprojectionIndex[eyeIndex] = indexWrite;
}
}
/*
void OnRenderImage(RenderTexture source, RenderTexture destination)
{
//if (destination != null && source.antiAliasing == destination.antiAliasing)// resolve without additional blit when not end of chain
//{
// Resolve(source, destination);
//}
//else
//{
RenderTexture internalDestination = RenderTexture.GetTemporary(bufferW, bufferH, 0, _FogVolumeCamera.GetRTFormat(), RenderTextureReadWrite.Default, source.antiAliasing);
{
Resolve(source, internalDestination);
Graphics.Blit(internalDestination, destination);
}
RenderTexture.ReleaseTemporary(internalDestination);
// }
}
*/
public void TAA(ref RenderTexture source)
{
// _FogVolumeCamera.depthTextureMode = DepthTextureMode.Depth;
RenderTexture internalDestination = RenderTexture.GetTemporary(source.width, source.height, 0, source.format);
{
Resolve(source, internalDestination);
Graphics.Blit(internalDestination, source);
}
RenderTexture.ReleaseTemporary(internalDestination);
}
void OnDisable()
{
if (reprojectionBuffer != null)
{
ReleaseRenderTarget(ref reprojectionBuffer[0, 0]);
ReleaseRenderTarget(ref reprojectionBuffer[0, 1]);
ReleaseRenderTarget(ref reprojectionBuffer[1, 0]);
ReleaseRenderTarget(ref reprojectionBuffer[1, 1]);
}
}
}