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.

216 lines
8.3 KiB

5 years ago
  1. // Copyright (c) <2015> <Playdead>
  2. // This file is subject to the MIT License as seen in the root of this folder structure (LICENSE.TXT)
  3. // AUTHOR: Lasse Jon Fuglsang Pedersen <lasse@playdead.com>
  4. #if UNITY_5_5_OR_NEWER
  5. #define SUPPORT_STEREO
  6. #endif
  7. using UnityEngine;
  8. [ExecuteInEditMode]
  9. [RequireComponent(typeof(Camera), typeof(FogVolumePlaydeadTAA.FrustumJitter), typeof(FogVolumePlaydeadTAA.VelocityBuffer))]
  10. //[AddComponentMenu("Playdead/TemporalReprojection")]
  11. public class FogVolumeTAA : FogVolumePlaydeadTAA.EffectBase
  12. {
  13. private static RenderBuffer[] mrt = new RenderBuffer[2];
  14. private Camera _FogVolumeCamera;
  15. private FogVolumePlaydeadTAA.FrustumJitter _frustumJitter;
  16. private FogVolumePlaydeadTAA.VelocityBuffer _velocityBuffer;
  17. public Shader reprojectionShader;
  18. private Material reprojectionMaterial;
  19. private RenderTexture[,] reprojectionBuffer;
  20. private int[] reprojectionIndex = new int[2] { -1, -1 };
  21. public enum Neighborhood
  22. {
  23. MinMax3x3,
  24. MinMax3x3Rounded,
  25. MinMax4TapVarying,
  26. };
  27. public Neighborhood neighborhood = Neighborhood.MinMax4TapVarying;
  28. public bool unjitterColorSamples = true;
  29. public bool unjitterNeighborhood = true;
  30. public bool unjitterReprojection = true;
  31. public bool useYCoCg = true;
  32. public bool useClipping = true;
  33. public bool useDilation = false;
  34. public bool useMotionBlur = false;
  35. public bool useOptimizations = false;
  36. [Range(0.0f, 1.0f)]
  37. public float feedbackMin = 0.88f;
  38. [Range(0.0f, 1.0f)]
  39. public float feedbackMax = 0.97f;
  40. public float motionBlurStrength = 1.0f;
  41. public bool motionBlurIgnoreFF = false;
  42. void Reset()
  43. {
  44. _FogVolumeCamera = GetComponent<Camera>();
  45. reprojectionShader = Shader.Find("Hidden/TAA");
  46. _FogVolumeCamera = GetComponent<Camera>();
  47. _frustumJitter = GetComponent<FogVolumePlaydeadTAA.FrustumJitter>();
  48. //_frustumJitter.enabled = false;
  49. _velocityBuffer = GetComponent<FogVolumePlaydeadTAA.VelocityBuffer>();
  50. _velocityBuffer.velocityShader= Shader.Find("Hidden/VelocityBuffer");
  51. }
  52. void Clear()
  53. {
  54. EnsureArray(ref reprojectionIndex, 2);
  55. reprojectionIndex[0] = -1;
  56. reprojectionIndex[1] = -1;
  57. }
  58. void Awake()
  59. {
  60. Reset();
  61. Clear();
  62. }
  63. void Resolve(RenderTexture source, RenderTexture destination)
  64. {
  65. _velocityBuffer.GenerateVelocityBuffer();
  66. EnsureArray(ref reprojectionBuffer, 2, 2);
  67. EnsureArray(ref reprojectionIndex, 2, initialValue: -1);
  68. EnsureMaterial(ref reprojectionMaterial, reprojectionShader);
  69. if (reprojectionMaterial == null)
  70. {
  71. Graphics.Blit(source, destination);
  72. return;
  73. }
  74. #if SUPPORT_STEREO
  75. int eyeIndex = (_FogVolumeCamera.stereoActiveEye == Camera.MonoOrStereoscopicEye.Right) ? 1 : 0;
  76. #else
  77. int eyeIndex = 0;
  78. #endif
  79. int bufferW = source.width;
  80. int bufferH = source.height;
  81. if (EnsureRenderTarget(ref reprojectionBuffer[eyeIndex, 0], bufferW, bufferH, source.format, FilterMode.Bilinear, antiAliasing: source.antiAliasing))
  82. Clear();
  83. if (EnsureRenderTarget(ref reprojectionBuffer[eyeIndex, 1], bufferW, bufferH, source.format, FilterMode.Bilinear, antiAliasing: source.antiAliasing))
  84. Clear();
  85. #if SUPPORT_STEREO
  86. bool stereoEnabled = _FogVolumeCamera.stereoEnabled;
  87. #else
  88. bool stereoEnabled = false;
  89. #endif
  90. #if UNITY_EDITOR
  91. bool allowMotionBlur = !stereoEnabled && Application.isPlaying;
  92. #else
  93. bool allowMotionBlur = !stereoEnabled;
  94. #endif
  95. EnsureKeyword(reprojectionMaterial, "CAMERA_PERSPECTIVE", !_FogVolumeCamera.orthographic);
  96. EnsureKeyword(reprojectionMaterial, "CAMERA_ORTHOGRAPHIC", _FogVolumeCamera.orthographic);
  97. EnsureKeyword(reprojectionMaterial, "MINMAX_3X3", neighborhood == Neighborhood.MinMax3x3);
  98. EnsureKeyword(reprojectionMaterial, "MINMAX_3X3_ROUNDED", neighborhood == Neighborhood.MinMax3x3Rounded);
  99. EnsureKeyword(reprojectionMaterial, "MINMAX_4TAP_VARYING", neighborhood == Neighborhood.MinMax4TapVarying);
  100. EnsureKeyword(reprojectionMaterial, "UNJITTER_COLORSAMPLES", unjitterColorSamples);
  101. EnsureKeyword(reprojectionMaterial, "UNJITTER_NEIGHBORHOOD", unjitterNeighborhood);
  102. EnsureKeyword(reprojectionMaterial, "UNJITTER_REPROJECTION", unjitterReprojection);
  103. EnsureKeyword(reprojectionMaterial, "USE_YCOCG", useYCoCg);
  104. EnsureKeyword(reprojectionMaterial, "USE_CLIPPING", useClipping);
  105. EnsureKeyword(reprojectionMaterial, "USE_DILATION", useDilation);
  106. EnsureKeyword(reprojectionMaterial, "USE_MOTION_BLUR", useMotionBlur && allowMotionBlur);
  107. EnsureKeyword(reprojectionMaterial, "USE_MOTION_BLUR_NEIGHBORMAX", _velocityBuffer.activeVelocityNeighborMax != null);
  108. EnsureKeyword(reprojectionMaterial, "USE_OPTIMIZATIONS", useOptimizations);
  109. if (reprojectionIndex[eyeIndex] == -1)// bootstrap
  110. {
  111. reprojectionIndex[eyeIndex] = 0;
  112. reprojectionBuffer[eyeIndex, reprojectionIndex[eyeIndex]].DiscardContents();
  113. Graphics.Blit(source, reprojectionBuffer[eyeIndex, reprojectionIndex[eyeIndex]]);
  114. }
  115. int indexRead = reprojectionIndex[eyeIndex];
  116. int indexWrite = (reprojectionIndex[eyeIndex] + 1) % 2;
  117. Vector4 jitterUV = _frustumJitter.activeSample;
  118. jitterUV.x /= bufferW;
  119. jitterUV.y /= bufferH;
  120. jitterUV.z /= bufferW;
  121. jitterUV.w /= bufferH;
  122. reprojectionMaterial.SetVector("_JitterUV", jitterUV);
  123. reprojectionMaterial.SetTexture("_VelocityBuffer", _velocityBuffer.activeVelocityBuffer);
  124. reprojectionMaterial.SetTexture("_VelocityNeighborMax", _velocityBuffer.activeVelocityNeighborMax);
  125. reprojectionMaterial.SetTexture("_MainTex", source);
  126. reprojectionMaterial.SetTexture("_PrevTex", reprojectionBuffer[eyeIndex, indexRead]);
  127. reprojectionMaterial.SetFloat("_FeedbackMin", feedbackMin);
  128. reprojectionMaterial.SetFloat("_FeedbackMax", feedbackMax);
  129. // reprojectionMaterial.SetFloat("_MotionScale", motionBlurStrength * (motionBlurIgnoreFF ? Mathf.Min(1.0f, 1.0f / _velocityBuffer.timeScale) : 1.0f));
  130. // reproject frame n-1 into output + history buffer
  131. {
  132. mrt[0] = reprojectionBuffer[eyeIndex, indexWrite].colorBuffer;
  133. mrt[1] = destination.colorBuffer;
  134. Graphics.SetRenderTarget(mrt, source.depthBuffer);
  135. reprojectionMaterial.SetPass(0);
  136. reprojectionBuffer[eyeIndex, indexWrite].DiscardContents();
  137. DrawFullscreenQuad();
  138. reprojectionIndex[eyeIndex] = indexWrite;
  139. }
  140. }
  141. /*
  142. void OnRenderImage(RenderTexture source, RenderTexture destination)
  143. {
  144. //if (destination != null && source.antiAliasing == destination.antiAliasing)// resolve without additional blit when not end of chain
  145. //{
  146. // Resolve(source, destination);
  147. //}
  148. //else
  149. //{
  150. RenderTexture internalDestination = RenderTexture.GetTemporary(bufferW, bufferH, 0, _FogVolumeCamera.GetRTFormat(), RenderTextureReadWrite.Default, source.antiAliasing);
  151. {
  152. Resolve(source, internalDestination);
  153. Graphics.Blit(internalDestination, destination);
  154. }
  155. RenderTexture.ReleaseTemporary(internalDestination);
  156. // }
  157. }
  158. */
  159. public void TAA(ref RenderTexture source)
  160. {
  161. // _FogVolumeCamera.depthTextureMode = DepthTextureMode.Depth;
  162. RenderTexture internalDestination = RenderTexture.GetTemporary(source.width, source.height, 0, source.format);
  163. {
  164. Resolve(source, internalDestination);
  165. Graphics.Blit(internalDestination, source);
  166. }
  167. RenderTexture.ReleaseTemporary(internalDestination);
  168. }
  169. void OnDisable()
  170. {
  171. if (reprojectionBuffer != null)
  172. {
  173. ReleaseRenderTarget(ref reprojectionBuffer[0, 0]);
  174. ReleaseRenderTarget(ref reprojectionBuffer[0, 1]);
  175. ReleaseRenderTarget(ref reprojectionBuffer[1, 0]);
  176. ReleaseRenderTarget(ref reprojectionBuffer[1, 1]);
  177. }
  178. }
  179. }