123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216 |
- using System;
- namespace UnityEngine.PostProcessing
- {
- public sealed class TaaComponent : PostProcessingComponentRenderTexture<AntialiasingModel>
- {
- static class Uniforms
- {
- internal static int _Jitter = Shader.PropertyToID("_Jitter");
- internal static int _SharpenParameters = Shader.PropertyToID("_SharpenParameters");
- internal static int _FinalBlendParameters = Shader.PropertyToID("_FinalBlendParameters");
- internal static int _HistoryTex = Shader.PropertyToID("_HistoryTex");
- internal static int _MainTex = Shader.PropertyToID("_MainTex");
- }
- const string k_ShaderString = "Hidden/Post FX/Temporal Anti-aliasing";
- const int k_SampleCount = 8;
- readonly RenderBuffer[] m_MRT = new RenderBuffer[2];
- int m_SampleIndex = 0;
- bool m_ResetHistory = true;
- RenderTexture m_HistoryTexture;
- public override bool active
- {
- get
- {
- return model.enabled
- && model.settings.method == AntialiasingModel.Method.Taa
- && SystemInfo.supportsMotionVectors
- && SystemInfo.supportedRenderTargetCount >= 2
- && !context.interrupted;
- }
- }
- public override DepthTextureMode GetCameraFlags()
- {
- return DepthTextureMode.Depth | DepthTextureMode.MotionVectors;
- }
- public Vector2 jitterVector { get; private set; }
- public void ResetHistory()
- {
- m_ResetHistory = true;
- }
- public void SetProjectionMatrix(Func<Vector2, Matrix4x4> jitteredFunc)
- {
- var settings = model.settings.taaSettings;
- var jitter = GenerateRandomOffset();
- jitter *= settings.jitterSpread;
- context.camera.nonJitteredProjectionMatrix = context.camera.projectionMatrix;
- if (jitteredFunc != null)
- {
- context.camera.projectionMatrix = jitteredFunc(jitter);
- }
- else
- {
- context.camera.projectionMatrix = context.camera.orthographic
- ? GetOrthographicProjectionMatrix(jitter)
- : GetPerspectiveProjectionMatrix(jitter);
- }
- #if UNITY_5_5_OR_NEWER
- context.camera.useJitteredProjectionMatrixForTransparentRendering = false;
- #endif
- jitter.x /= context.width;
- jitter.y /= context.height;
- var material = context.materialFactory.Get(k_ShaderString);
- material.SetVector(Uniforms._Jitter, jitter);
- jitterVector = jitter;
- }
- public void Render(RenderTexture source, RenderTexture destination)
- {
- var material = context.materialFactory.Get(k_ShaderString);
- material.shaderKeywords = null;
- var settings = model.settings.taaSettings;
- if (m_ResetHistory || m_HistoryTexture == null || m_HistoryTexture.width != source.width || m_HistoryTexture.height != source.height)
- {
- if (m_HistoryTexture)
- RenderTexture.ReleaseTemporary(m_HistoryTexture);
- m_HistoryTexture = RenderTexture.GetTemporary(source.width, source.height, 0, source.format);
- m_HistoryTexture.name = "TAA History";
- Graphics.Blit(source, m_HistoryTexture, material, 2);
- }
- const float kMotionAmplification = 100f * 60f;
- material.SetVector(Uniforms._SharpenParameters, new Vector4(settings.sharpen, 0f, 0f, 0f));
- material.SetVector(Uniforms._FinalBlendParameters, new Vector4(settings.stationaryBlending, settings.motionBlending, kMotionAmplification, 0f));
- material.SetTexture(Uniforms._MainTex, source);
- material.SetTexture(Uniforms._HistoryTex, m_HistoryTexture);
- var tempHistory = RenderTexture.GetTemporary(source.width, source.height, 0, source.format);
- tempHistory.name = "TAA History";
- m_MRT[0] = destination.colorBuffer;
- m_MRT[1] = tempHistory.colorBuffer;
- Graphics.SetRenderTarget(m_MRT, source.depthBuffer);
- GraphicsUtils.Blit(material, context.camera.orthographic ? 1 : 0);
- RenderTexture.ReleaseTemporary(m_HistoryTexture);
- m_HistoryTexture = tempHistory;
- m_ResetHistory = false;
- }
- float GetHaltonValue(int index, int radix)
- {
- float result = 0f;
- float fraction = 1f / (float)radix;
- while (index > 0)
- {
- result += (float)(index % radix) * fraction;
- index /= radix;
- fraction /= (float)radix;
- }
- return result;
- }
- Vector2 GenerateRandomOffset()
- {
- var offset = new Vector2(
- GetHaltonValue(m_SampleIndex & 1023, 2),
- GetHaltonValue(m_SampleIndex & 1023, 3));
- if (++m_SampleIndex >= k_SampleCount)
- m_SampleIndex = 0;
- return offset;
- }
- // Adapted heavily from PlayDead's TAA code
- // https://github.com/playdeadgames/temporal/blob/master/Assets/Scripts/Extensions.cs
- Matrix4x4 GetPerspectiveProjectionMatrix(Vector2 offset)
- {
- float vertical = Mathf.Tan(0.5f * Mathf.Deg2Rad * context.camera.fieldOfView);
- float horizontal = vertical * context.camera.aspect;
- offset.x *= horizontal / (0.5f * context.width);
- offset.y *= vertical / (0.5f * context.height);
- float left = (offset.x - horizontal) * context.camera.nearClipPlane;
- float right = (offset.x + horizontal) * context.camera.nearClipPlane;
- float top = (offset.y + vertical) * context.camera.nearClipPlane;
- float bottom = (offset.y - vertical) * context.camera.nearClipPlane;
- var matrix = new Matrix4x4();
- matrix[0, 0] = (2f * context.camera.nearClipPlane) / (right - left);
- matrix[0, 1] = 0f;
- matrix[0, 2] = (right + left) / (right - left);
- matrix[0, 3] = 0f;
- matrix[1, 0] = 0f;
- matrix[1, 1] = (2f * context.camera.nearClipPlane) / (top - bottom);
- matrix[1, 2] = (top + bottom) / (top - bottom);
- matrix[1, 3] = 0f;
- matrix[2, 0] = 0f;
- matrix[2, 1] = 0f;
- matrix[2, 2] = -(context.camera.farClipPlane + context.camera.nearClipPlane) / (context.camera.farClipPlane - context.camera.nearClipPlane);
- matrix[2, 3] = -(2f * context.camera.farClipPlane * context.camera.nearClipPlane) / (context.camera.farClipPlane - context.camera.nearClipPlane);
- matrix[3, 0] = 0f;
- matrix[3, 1] = 0f;
- matrix[3, 2] = -1f;
- matrix[3, 3] = 0f;
- return matrix;
- }
- Matrix4x4 GetOrthographicProjectionMatrix(Vector2 offset)
- {
- float vertical = context.camera.orthographicSize;
- float horizontal = vertical * context.camera.aspect;
- offset.x *= horizontal / (0.5f * context.width);
- offset.y *= vertical / (0.5f * context.height);
- float left = offset.x - horizontal;
- float right = offset.x + horizontal;
- float top = offset.y + vertical;
- float bottom = offset.y - vertical;
- return Matrix4x4.Ortho(left, right, bottom, top, context.camera.nearClipPlane, context.camera.farClipPlane);
- }
- public override void OnDisable()
- {
- if (m_HistoryTexture != null)
- RenderTexture.ReleaseTemporary(m_HistoryTexture);
- m_HistoryTexture = null;
- m_SampleIndex = 0;
- ResetHistory();
- }
- }
- }
|