Ei kuvausta
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.

TemporalAA.cs 25KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552
  1. using System;
  2. using UnityEngine.Experimental.Rendering;
  3. using UnityEngine.Rendering.RenderGraphModule;
  4. using UnityEngine.Serialization;
  5. namespace UnityEngine.Rendering.Universal
  6. {
  7. // All of TAA here, work on TAA == work on this file.
  8. /// <summary>
  9. /// Temporal Anti-aliasing quality setting.
  10. /// </summary>
  11. public enum TemporalAAQuality
  12. {
  13. // Quality options were tuned to give meaningful performance differences on mobile hardware.
  14. /// <summary>
  15. /// 5-tap RGB clamp. No motion dilation. Suitable for no/low motion scenes.
  16. /// </summary>
  17. VeryLow = 0,
  18. /// <summary>
  19. /// 5-tap RGB clamp. 5-tap motion dilation.
  20. /// </summary>
  21. Low,
  22. /// <summary>
  23. /// 9-tap YCoCg variance clamp. 9-tap motion dilation.
  24. /// </summary>
  25. Medium,
  26. /// <summary>
  27. /// 9-tap YCoCg variance clamp and bicubic history.
  28. /// </summary>
  29. High,
  30. // VeryHigh is a catch all option for enabling all the implemented features regardless of cost.
  31. // Currently, 9-tap YCoCg variance clip, bicubic history and center sample filtering.
  32. // In the future, VeryHigh mode could read additional buffers to improve the quality further.
  33. /// <summary>
  34. /// Best quality, everything enabled.
  35. /// </summary>
  36. VeryHigh
  37. }
  38. /// <summary>
  39. /// Temporal anti-aliasing.
  40. /// </summary>
  41. public static class TemporalAA
  42. {
  43. internal static class ShaderConstants
  44. {
  45. public static readonly int _TaaAccumulationTex = Shader.PropertyToID("_TaaAccumulationTex");
  46. public static readonly int _TaaMotionVectorTex = Shader.PropertyToID("_TaaMotionVectorTex");
  47. public static readonly int _TaaFilterWeights = Shader.PropertyToID("_TaaFilterWeights");
  48. public static readonly int _TaaFrameInfluence = Shader.PropertyToID("_TaaFrameInfluence");
  49. public static readonly int _TaaVarianceClampScale = Shader.PropertyToID("_TaaVarianceClampScale");
  50. public static readonly int _CameraDepthTexture = Shader.PropertyToID("_CameraDepthTexture");
  51. }
  52. internal static class ShaderKeywords
  53. {
  54. public static readonly string TAA_LOW_PRECISION_SOURCE = "TAA_LOW_PRECISION_SOURCE";
  55. }
  56. /// <summary>
  57. /// Temporal anti-aliasing settings.
  58. /// </summary>
  59. [Serializable]
  60. public struct Settings
  61. {
  62. [SerializeField]
  63. [FormerlySerializedAs("quality")]
  64. internal TemporalAAQuality m_Quality;
  65. [SerializeField]
  66. [FormerlySerializedAs("frameInfluence")]
  67. internal float m_FrameInfluence;
  68. [SerializeField]
  69. [FormerlySerializedAs("jitterScale")]
  70. internal float m_JitterScale;
  71. [SerializeField]
  72. [FormerlySerializedAs("mipBias")]
  73. internal float m_MipBias;
  74. [SerializeField]
  75. [FormerlySerializedAs("varianceClampScale")]
  76. internal float m_VarianceClampScale;
  77. [SerializeField]
  78. [FormerlySerializedAs("contrastAdaptiveSharpening")]
  79. internal float m_ContrastAdaptiveSharpening;
  80. // Internal API
  81. [NonSerialized] internal int resetHistoryFrames; // Number of frames the history is reset. 0 no reset, 1 normal reset, 2 XR reset, -1 infinite (toggle on)
  82. [NonSerialized] internal int jitterFrameCountOffset; // Jitter "seed" == Time.frameCount + jitterFrameCountOffset. Used for testing determinism.
  83. /// <summary>
  84. /// The quality level to use for the temporal anti-aliasing.
  85. /// </summary>
  86. public TemporalAAQuality quality
  87. {
  88. get => m_Quality;
  89. set => m_Quality = (TemporalAAQuality)Mathf.Clamp((int)value, (int)TemporalAAQuality.VeryLow, (int)TemporalAAQuality.VeryHigh);
  90. }
  91. /// <summary>
  92. /// Determines how much the history buffer is blended together with current frame result. Higher values means more history contribution, which leads to better anti aliasing, but also more prone to ghosting.
  93. /// Between 0.0 - 1.0.
  94. /// </summary>
  95. public float baseBlendFactor
  96. {
  97. // URP uses frame influence, amount of current frame to blend with history.
  98. // HDRP uses base blend factor, the amount of history to blend with current frame.
  99. // We flip the value here to match HDRP for consistent API/UI.
  100. get => 1.0f - m_FrameInfluence;
  101. set => m_FrameInfluence = Mathf.Clamp01(1.0f - value);
  102. }
  103. /// <summary>
  104. /// Determines the scale to the jitter applied when TAA is enabled. Lowering this value will lead to less visible flickering and jittering, but also will produce more aliased images.
  105. /// </summary>
  106. public float jitterScale
  107. {
  108. get => m_JitterScale;
  109. set => m_JitterScale = Mathf.Clamp01(value);
  110. }
  111. /// <summary>
  112. /// Determines how much texture mip map selection is biased when rendering. Lowering this can slightly reduce blur on textures at the cost of performance. Requires mip maps in textures.
  113. /// Between -1.0 - 0.0.
  114. /// </summary>
  115. public float mipBias
  116. {
  117. get => m_MipBias;
  118. set => m_MipBias = Mathf.Clamp(value, -1.0f, 0.0f);
  119. }
  120. /// <summary>
  121. /// Determines the strength of the history color rectification clamp. Lower values can reduce ghosting, but produce more flickering. Higher values reduce flickering, but are prone to blur and ghosting.
  122. /// Between 0.001 - 10.0.
  123. /// Good values around 1.0.
  124. /// </summary>
  125. public float varianceClampScale
  126. {
  127. get => m_VarianceClampScale;
  128. set => m_VarianceClampScale = Mathf.Clamp(value, 0.001f, 10.0f);
  129. }
  130. /// <summary>
  131. /// Enables high quality post sharpening to reduce TAA blur. The FSR upscaling overrides this setting if enabled.
  132. /// Between 0.0 - 1.0.
  133. /// Use 0.0 to disable.
  134. /// </summary>
  135. public float contrastAdaptiveSharpening
  136. {
  137. get => m_ContrastAdaptiveSharpening;
  138. set => m_ContrastAdaptiveSharpening = Mathf.Clamp01(value);
  139. }
  140. /// <summary>
  141. /// Creates a new instance of the settings with default values.
  142. /// </summary>
  143. /// <returns>Default settings.</returns>
  144. public static Settings Create()
  145. {
  146. Settings s;
  147. s.m_Quality = TemporalAAQuality.High;
  148. s.m_FrameInfluence = 0.1f;
  149. s.m_JitterScale = 1.0f;
  150. s.m_MipBias = 0.0f;
  151. s.m_VarianceClampScale = 0.9f;
  152. s.m_ContrastAdaptiveSharpening = 0.0f; // Disabled
  153. s.resetHistoryFrames = 0;
  154. s.jitterFrameCountOffset = 0;
  155. return s;
  156. }
  157. }
  158. /// <summary>
  159. /// A function delegate that returns a jitter offset for the provided frame
  160. /// This provides support for cases where a non-standard jitter pattern is desired
  161. /// </summary>
  162. /// <param name="frameIndex">index of the current frame</param>
  163. /// <param name="jitter">computed jitter offset</param>
  164. /// <param name="allowScaling">true if the jitter function's output supports scaling</param>
  165. internal delegate void JitterFunc(int frameIndex, out Vector2 jitter, out bool allowScaling);
  166. internal static Matrix4x4 CalculateJitterMatrix(UniversalCameraData cameraData, JitterFunc jitterFunc)
  167. {
  168. Matrix4x4 jitterMat = Matrix4x4.identity;
  169. bool isJitter = cameraData.IsTemporalAAEnabled();
  170. if (isJitter)
  171. {
  172. int taaFrameCountOffset = cameraData.taaSettings.jitterFrameCountOffset;
  173. int taaFrameIndex = Time.frameCount + taaFrameCountOffset;
  174. float actualWidth = cameraData.cameraTargetDescriptor.width;
  175. float actualHeight = cameraData.cameraTargetDescriptor.height;
  176. float jitterScale = cameraData.taaSettings.jitterScale;
  177. Vector2 jitter;
  178. bool allowScaling;
  179. jitterFunc(taaFrameIndex, out jitter, out allowScaling);
  180. if (allowScaling)
  181. jitter *= jitterScale;
  182. float offsetX = jitter.x * (2.0f / actualWidth);
  183. float offsetY = jitter.y * (2.0f / actualHeight);
  184. jitterMat = Matrix4x4.Translate(new Vector3(offsetX, offsetY, 0.0f));
  185. }
  186. return jitterMat;
  187. }
  188. internal static void CalculateJitter(int frameIndex, out Vector2 jitter, out bool allowScaling)
  189. {
  190. // The variance between 0 and the actual halton sequence values reveals noticeable
  191. // instability in Unity's shadow maps, so we avoid index 0.
  192. float jitterX = HaltonSequence.Get((frameIndex & 1023) + 1, 2) - 0.5f;
  193. float jitterY = HaltonSequence.Get((frameIndex & 1023) + 1, 3) - 0.5f;
  194. jitter = new Vector2(jitterX, jitterY);
  195. allowScaling = true;
  196. }
  197. // Static allocation of JitterFunc delegate to avoid GC
  198. internal static JitterFunc s_JitterFunc = CalculateJitter;
  199. private static readonly Vector2[] taaFilterOffsets = new Vector2[]
  200. {
  201. new Vector2(0.0f, 0.0f),
  202. new Vector2(0.0f, 1.0f),
  203. new Vector2(1.0f, 0.0f),
  204. new Vector2(-1.0f, 0.0f),
  205. new Vector2(0.0f, -1.0f),
  206. new Vector2(-1.0f, 1.0f),
  207. new Vector2(1.0f, -1.0f),
  208. new Vector2(1.0f, 1.0f),
  209. new Vector2(-1.0f, -1.0f)
  210. };
  211. private static readonly float[] taaFilterWeights = new float[taaFilterOffsets.Length + 1];
  212. internal static float[] CalculateFilterWeights(float jitterScale)
  213. {
  214. // Based on HDRP
  215. // Precompute weights used for the Blackman-Harris filter.
  216. float totalWeight = 0;
  217. for (int i = 0; i < 9; ++i)
  218. {
  219. // The internal jitter function used by TAA always allows scaling
  220. CalculateJitter(Time.frameCount, out var jitter, out var _);
  221. jitter *= jitterScale;
  222. // The rendered frame (pixel grid) is already jittered.
  223. // We sample 3x3 neighbors with int offsets, but weight the samples
  224. // relative to the distance to the non-jittered pixel center.
  225. // From the POV of offset[0] at (0,0), the original pixel center is at (-jitter.x, -jitter.y).
  226. float x = taaFilterOffsets[i].x - jitter.x;
  227. float y = taaFilterOffsets[i].y - jitter.y;
  228. float d2 = (x * x + y * y);
  229. taaFilterWeights[i] = Mathf.Exp((-0.5f / (0.22f)) * d2);
  230. totalWeight += taaFilterWeights[i];
  231. }
  232. // Normalize weights.
  233. for (int i = 0; i < 9; ++i)
  234. {
  235. taaFilterWeights[i] /= totalWeight;
  236. }
  237. return taaFilterWeights;
  238. }
  239. internal static GraphicsFormat[] AccumulationFormatList = new GraphicsFormat[]
  240. {
  241. GraphicsFormat.R16G16B16A16_SFloat,
  242. GraphicsFormat.B10G11R11_UFloatPack32,
  243. GraphicsFormat.R8G8B8A8_UNorm,
  244. GraphicsFormat.B8G8R8A8_UNorm,
  245. };
  246. internal static RenderTextureDescriptor TemporalAADescFromCameraDesc(ref RenderTextureDescriptor cameraDesc)
  247. {
  248. RenderTextureDescriptor taaDesc = cameraDesc;
  249. // Explicitly set from cameraDesc.* for clarity.
  250. taaDesc.width = cameraDesc.width;
  251. taaDesc.height = cameraDesc.height;
  252. taaDesc.msaaSamples = 1;
  253. taaDesc.volumeDepth = cameraDesc.volumeDepth;
  254. taaDesc.mipCount = 0;
  255. taaDesc.graphicsFormat = cameraDesc.graphicsFormat;
  256. taaDesc.sRGB = false;
  257. taaDesc.depthBufferBits = 0;
  258. taaDesc.dimension = cameraDesc.dimension;
  259. taaDesc.vrUsage = cameraDesc.vrUsage;
  260. taaDesc.memoryless = RenderTextureMemoryless.None;
  261. taaDesc.useMipMap = false;
  262. taaDesc.autoGenerateMips = false;
  263. taaDesc.enableRandomWrite = false;
  264. taaDesc.bindMS = false;
  265. taaDesc.useDynamicScale = false;
  266. if (!SystemInfo.IsFormatSupported(taaDesc.graphicsFormat, GraphicsFormatUsage.Render))
  267. {
  268. taaDesc.graphicsFormat = GraphicsFormat.None;
  269. for (int i = 0; i < AccumulationFormatList.Length; i++)
  270. if (SystemInfo.IsFormatSupported(AccumulationFormatList[i], GraphicsFormatUsage.Render))
  271. {
  272. taaDesc.graphicsFormat = AccumulationFormatList[i];
  273. break;
  274. }
  275. }
  276. return taaDesc;
  277. }
  278. static uint s_warnCounter = 0;
  279. internal static string ValidateAndWarn(UniversalCameraData cameraData)
  280. {
  281. string warning = null;
  282. if(warning == null && !cameraData.postProcessEnabled)
  283. warning = "Disabling TAA because camera has post-processing disabled.";
  284. if (cameraData.taaHistory == null)
  285. {
  286. warning = "Disabling TAA due to invalid persistent data.";
  287. }
  288. if (warning == null && cameraData.cameraTargetDescriptor.msaaSamples != 1)
  289. {
  290. if (cameraData.xr != null && cameraData.xr.enabled)
  291. warning = "Disabling TAA because MSAA is on. MSAA must be disabled globally for all cameras in XR mode.";
  292. else
  293. warning = "Disabling TAA because MSAA is on. Turn MSAA off on the camera or current URP Asset to enable TAA.";
  294. }
  295. if(warning == null && cameraData.camera.TryGetComponent<UniversalAdditionalCameraData>(out var additionalCameraData))
  296. {
  297. if (additionalCameraData.renderType == CameraRenderType.Overlay ||
  298. additionalCameraData.cameraStack.Count > 0)
  299. {
  300. warning = "Disabling TAA because camera is stacked.";
  301. }
  302. }
  303. if (warning == null && cameraData.camera.allowDynamicResolution)
  304. warning = "Disabling TAA because camera has dynamic resolution enabled. You can use a constant render scale instead.";
  305. if(warning == null && !cameraData.renderer.SupportsMotionVectors())
  306. warning = "Disabling TAA because the renderer does not implement motion vectors. Motion vectors are required for TAA.";
  307. const int warningThrottleFrames = 60 * 1; // 60 FPS * 1 sec
  308. if (s_warnCounter % warningThrottleFrames == 0)
  309. Debug.LogWarning(warning);
  310. s_warnCounter++;
  311. return warning;
  312. }
  313. internal static void ExecutePass(CommandBuffer cmd, Material taaMaterial, ref CameraData cameraData, RTHandle source, RTHandle destination, RenderTexture motionVectors)
  314. {
  315. using (new ProfilingScope(cmd, ProfilingSampler.Get(URPProfileId.TemporalAA)))
  316. {
  317. int multipassId = 0;
  318. #if ENABLE_VR && ENABLE_XR_MODULE
  319. multipassId = cameraData.xr.multipassId;
  320. #endif
  321. bool isNewFrame = cameraData.taaHistory.GetAccumulationVersion(multipassId) != Time.frameCount;
  322. RTHandle taaHistoryAccumulationTex = cameraData.taaHistory.GetAccumulationTexture(multipassId);
  323. taaMaterial.SetTexture(ShaderConstants._TaaAccumulationTex, taaHistoryAccumulationTex);
  324. // On frame rerender or pause, stop all motion using a black motion texture.
  325. // This is done to avoid blurring the Taa resolve due to motion and Taa history mismatch.
  326. //
  327. // Taa history copy is in sync with motion vectors and Time.frameCount, but we updated the TAA history
  328. // for the next frame, as we did not know that we're going render this frame again.
  329. // We would need history double buffering to solve this properly, but at the cost of memory.
  330. //
  331. // Frame #1: MotionVectors.Update: #1 Prev: #-1, Taa.Execute: #1 Prev: #-1, Taa.CopyHistory: #1 Prev: #-1
  332. // Frame #2: MotionVectors.Update: #2 Prev: #1, Taa.Execute: #2 Prev #1, Taa.CopyHistory: #2
  333. // <pause or render frame #2 again>
  334. // Frame #2: MotionVectors.Update: #2, Taa.Execute: #2 prev #2 (Ooops! Incorrect history for frame #2!)
  335. taaMaterial.SetTexture(ShaderConstants._TaaMotionVectorTex, isNewFrame ? motionVectors : Texture2D.blackTexture);
  336. ref var taa = ref cameraData.taaSettings;
  337. float taaInfluence = taa.resetHistoryFrames == 0 ? taa.m_FrameInfluence : 1.0f;
  338. taaMaterial.SetFloat(ShaderConstants._TaaFrameInfluence, taaInfluence);
  339. taaMaterial.SetFloat(ShaderConstants._TaaVarianceClampScale, taa.varianceClampScale);
  340. if (taa.quality == TemporalAAQuality.VeryHigh)
  341. taaMaterial.SetFloatArray(ShaderConstants._TaaFilterWeights, CalculateFilterWeights(taa.jitterScale));
  342. switch (taaHistoryAccumulationTex.rt.graphicsFormat)
  343. {
  344. // Avoid precision issues with YCoCg and low bit color formats.
  345. case GraphicsFormat.B10G11R11_UFloatPack32:
  346. case GraphicsFormat.R8G8B8A8_UNorm:
  347. case GraphicsFormat.B8G8R8A8_UNorm:
  348. taaMaterial.EnableKeyword(ShaderKeywords.TAA_LOW_PRECISION_SOURCE);
  349. break;
  350. default:
  351. taaMaterial.DisableKeyword(ShaderKeywords.TAA_LOW_PRECISION_SOURCE);
  352. break;
  353. }
  354. CoreUtils.SetKeyword(taaMaterial, ShaderKeywordStrings._ENABLE_ALPHA_OUTPUT, cameraData.isAlphaOutputEnabled);
  355. Blitter.BlitCameraTexture(cmd, source, destination, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store, taaMaterial, (int)taa.quality);
  356. if (isNewFrame)
  357. {
  358. int kHistoryCopyPass = taaMaterial.shader.passCount - 1;
  359. Blitter.BlitCameraTexture(cmd, destination, taaHistoryAccumulationTex, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store, taaMaterial, kHistoryCopyPass);
  360. cameraData.taaHistory.SetAccumulationVersion(multipassId, Time.frameCount);
  361. }
  362. }
  363. }
  364. private class TaaPassData
  365. {
  366. internal TextureHandle dstTex;
  367. internal TextureHandle srcColorTex;
  368. internal TextureHandle srcDepthTex;
  369. internal TextureHandle srcMotionVectorTex;
  370. internal TextureHandle srcTaaAccumTex;
  371. internal Material material;
  372. internal int passIndex;
  373. internal float taaFrameInfluence;
  374. internal float taaVarianceClampScale;
  375. internal float[] taaFilterWeights;
  376. internal bool taaLowPrecisionSource;
  377. internal bool taaAlphaOutput;
  378. }
  379. internal static void Render(RenderGraph renderGraph, Material taaMaterial, UniversalCameraData cameraData, ref TextureHandle srcColor, ref TextureHandle srcDepth, ref TextureHandle srcMotionVectors, ref TextureHandle dstColor)
  380. {
  381. int multipassId = 0;
  382. #if ENABLE_VR && ENABLE_XR_MODULE
  383. multipassId = cameraData.xr.multipassId;
  384. #endif
  385. ref var taa = ref cameraData.taaSettings;
  386. bool isNewFrame = cameraData.taaHistory.GetAccumulationVersion(multipassId) != Time.frameCount;
  387. float taaInfluence = taa.resetHistoryFrames == 0 ? taa.m_FrameInfluence : 1.0f;
  388. RTHandle accumulationTexture = cameraData.taaHistory.GetAccumulationTexture(multipassId);
  389. TextureHandle srcAccumulation = renderGraph.ImportTexture(accumulationTexture);
  390. // On frame rerender or pause, stop all motion using a black motion texture.
  391. // This is done to avoid blurring the Taa resolve due to motion and Taa history mismatch.
  392. // The TAA history was updated for the next frame, as we did not know yet that we're going render this frame again.
  393. // We would need to keep the both the current and previous history (double buffering) in order to resolve
  394. // either this frame (again) or the next frame correctly, but it would cost more memory.
  395. TextureHandle activeMotionVectors = isNewFrame ? srcMotionVectors : renderGraph.defaultResources.blackTexture;
  396. using (var builder = renderGraph.AddRasterRenderPass<TaaPassData>("Temporal Anti-aliasing", out var passData, ProfilingSampler.Get(URPProfileId.RG_TAA)))
  397. {
  398. passData.dstTex = dstColor;
  399. builder.SetRenderAttachment(dstColor, 0, AccessFlags.Write);
  400. passData.srcColorTex = srcColor;
  401. builder.UseTexture(srcColor, AccessFlags.Read);
  402. passData.srcDepthTex = srcDepth;
  403. builder.UseTexture(srcDepth, AccessFlags.Read);
  404. passData.srcMotionVectorTex = activeMotionVectors;
  405. builder.UseTexture(activeMotionVectors, AccessFlags.Read);
  406. passData.srcTaaAccumTex = srcAccumulation;
  407. builder.UseTexture(srcAccumulation, AccessFlags.Read);
  408. passData.material = taaMaterial;
  409. passData.passIndex = (int)taa.quality;
  410. passData.taaFrameInfluence = taaInfluence;
  411. passData.taaVarianceClampScale = taa.varianceClampScale;
  412. if (taa.quality == TemporalAAQuality.VeryHigh)
  413. passData.taaFilterWeights = CalculateFilterWeights(taa.jitterScale);
  414. else
  415. passData.taaFilterWeights = null;
  416. switch (accumulationTexture.rt.graphicsFormat)
  417. {
  418. // Avoid precision issues with YCoCg and low bit color formats.
  419. case GraphicsFormat.B10G11R11_UFloatPack32:
  420. case GraphicsFormat.R8G8B8A8_UNorm:
  421. case GraphicsFormat.B8G8R8A8_UNorm:
  422. passData.taaLowPrecisionSource = true;
  423. break;
  424. default:
  425. passData.taaLowPrecisionSource = false;
  426. break;
  427. }
  428. passData.taaAlphaOutput = cameraData.isAlphaOutputEnabled;
  429. builder.SetRenderFunc(static (TaaPassData data, RasterGraphContext context) =>
  430. {
  431. data.material.SetFloat(ShaderConstants._TaaFrameInfluence, data.taaFrameInfluence);
  432. data.material.SetFloat(ShaderConstants._TaaVarianceClampScale, data.taaVarianceClampScale);
  433. data.material.SetTexture(ShaderConstants._TaaAccumulationTex, data.srcTaaAccumTex);
  434. data.material.SetTexture(ShaderConstants._TaaMotionVectorTex, data.srcMotionVectorTex);
  435. data.material.SetTexture(ShaderConstants._CameraDepthTexture, data.srcDepthTex);
  436. CoreUtils.SetKeyword(data.material, ShaderKeywords.TAA_LOW_PRECISION_SOURCE, data.taaLowPrecisionSource);
  437. CoreUtils.SetKeyword(data.material, ShaderKeywordStrings._ENABLE_ALPHA_OUTPUT, data.taaAlphaOutput);
  438. if(data.taaFilterWeights != null)
  439. data.material.SetFloatArray(ShaderConstants._TaaFilterWeights, data.taaFilterWeights);
  440. Blitter.BlitTexture(context.cmd, data.srcColorTex, Vector2.one, data.material, data.passIndex);
  441. });
  442. }
  443. if (isNewFrame)
  444. {
  445. int kHistoryCopyPass = taaMaterial.shader.passCount - 1;
  446. using (var builder = renderGraph.AddRasterRenderPass<TaaPassData>("Temporal Anti-aliasing Copy History", out var passData, ProfilingSampler.Get(URPProfileId.RG_TAACopyHistory)))
  447. {
  448. passData.dstTex = srcAccumulation;
  449. builder.SetRenderAttachment(srcAccumulation, 0, AccessFlags.Write);
  450. passData.srcColorTex = dstColor;
  451. builder.UseTexture(dstColor, AccessFlags.Read); // Resolved color is the new history
  452. passData.material = taaMaterial;
  453. passData.passIndex = kHistoryCopyPass;
  454. builder.SetRenderFunc((TaaPassData data, RasterGraphContext context) => { Blitter.BlitTexture(context.cmd, data.srcColorTex, Vector2.one, data.material, data.passIndex); });
  455. }
  456. cameraData.taaHistory.SetAccumulationVersion(multipassId, Time.frameCount);
  457. }
  458. }
  459. }
  460. }