├── LICENSE ├── README.md ├── TemporalAA ├── TemporalAACamera.cs ├── TemporalAACamera.cs.meta ├── TemporalAAFeature.cs ├── TemporalAAFeature.cs.meta ├── TemporalAAMaterial.mat ├── TemporalAAMaterial.mat.meta ├── TemporalAAShader.shader └── TemporalAAShader.shader.meta └── res └── comp.png /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Pascal Zwick 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Unity URP Temporal Anti-Aliasing 2 | This is a Temporal Anti-Aliasing (TAA) solution for Unity's Universal render pipeline. URP does not have a TAA solution yet, so this may solve aliasing issues for devs using URP. 3 | 4 | NOTE: URP does not support true motion vectors, so we rely on Neighborhood Clipping to deal with objects in motion. It should be fine though when the game runs at 60+ FPS, but this can definately depend on the use case. 5 | 6 | This implementation is based on the Siggraph2014 talk by Brian Karis: 7 | High Quality Temporal Supersampling 8 | https://de45xmedrsdbp.cloudfront.net/Resources/files/TemporalAA_small-59732822.pdf 9 | 10 | ## Limitations 11 | - Some pixel flickering at thin lines 12 | - Does not work with active MSAA 13 | - Only one camera with TAA is supported at the moment 14 | 15 | ## Comparison 16 | ![Anti-Aliasing comparison](https://github.com/CMDRSpirit/URPTemporalAA/blob/main/res/comp.png?raw=true) 17 | 18 | You can easily see that FXAA is more or less a blurry mess everywhere. SMAA is much cleaner but still has issues with very thin details, like the rope. 19 | TAA fixes those issues and efficiently super samples the details of the image. 20 | 21 | A Video is available on my youtube channel: 22 | https://www.youtube.com/watch?v=0D_8q_3q0_s 23 | 24 | ## Usage 25 | - Render Pipeline Asset: 26 | - Make sure MSAA is disabled 27 | - Enable Depth / Opaque Textures 28 | - Camera: 29 | - Disable any anti-aliasing method on your camera 30 | - Renderer Asset: 31 | - Add Temporal AA Feature to your renderer 32 | - Done! 33 | 34 | ### Suggested Settings 35 | - TemporalFade: 0.95 -> Lower leads to the current value being more represented in the final image, but more jittering is visible. 36 | - MovementBlending: 100 -> Higher leads to more aggressive pixel rejection 37 | - UseFlipUV: Sometimes, post processing and other settings flip the image. Toggle this to fix upside down results. 38 | 39 | A Halton length of 8 should be enough (roughly 8x super sampling), larger values seem to make the jittering more obvious. 40 | 41 | ## Requirements 42 | - Unity 2021.2+ with URP 12 -> Should also work with most other versions, I just didn't test it. 43 | - Unity.Mathematics (https://docs.unity3d.com/Packages/com.unity.mathematics@1.1/) 44 | -------------------------------------------------------------------------------- /TemporalAA/TemporalAACamera.cs: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2022 Pascal Zwick 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | using System; 26 | using System.Collections.Generic; 27 | using UnityEngine; 28 | using Unity.Mathematics; 29 | using UnityEngine.Rendering; 30 | using UnityEngine.Rendering.Universal; 31 | 32 | [Obsolete("You may remove this component. Its logic has been moved into the TAA RenderFeature")] 33 | public class TemporalAACamera : MonoBehaviour 34 | { 35 | } 36 | 37 | -------------------------------------------------------------------------------- /TemporalAA/TemporalAACamera.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 22b5e11dc23ffd547b4b095294767b5a 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /TemporalAA/TemporalAAFeature.cs: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2022 Pascal Zwick 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | using UnityEngine; 26 | using UnityEngine.Rendering; 27 | using UnityEngine.Rendering.Universal; 28 | using Unity.Mathematics; 29 | 30 | public class TemporalAAFeature : ScriptableRendererFeature 31 | { 32 | static readonly double2[] Halton2364Seq = { new(0, 0), new(0.5, 0.3333333333333333), new(0.25, 0.6666666666666666), new(0.75, 0.1111111111111111), new double2(0.125, 0.4444444444444444), new double2(0.625, 0.7777777777777777), new double2(0.375, 0.2222222222222222), new double2(0.875, 0.5555555555555556), new double2(0.0625, 0.8888888888888888), new double2(0.5625, 0.037037037037037035), new double2(0.3125, 0.37037037037037035), new double2(0.8125, 0.7037037037037037), new double2(0.1875, 0.14814814814814814), new double2(0.6875, 0.48148148148148145), new double2(0.4375, 0.8148148148148147), new double2(0.9375, 0.25925925925925924), new double2(0.03125, 0.5925925925925926), new double2(0.53125, 0.9259259259259258), new double2(0.28125, 0.07407407407407407), new double2(0.78125, 0.4074074074074074), new double2(0.15625, 0.7407407407407407), new double2(0.65625, 0.18518518518518517), new double2(0.40625, 0.5185185185185185), new double2(0.90625, 0.8518518518518517), new double2(0.09375, 0.2962962962962963), new double2(0.59375, 0.6296296296296297), new double2(0.34375, 0.9629629629629629), new double2(0.84375, 0.012345679012345678), new double2(0.21875, 0.345679012345679), new double2(0.71875, 0.6790123456790123), new double2(0.46875, 0.12345679012345678), new double2(0.96875, 0.4567901234567901), new double2(0.015625, 0.7901234567901234), new double2(0.515625, 0.2345679012345679), new double2(0.265625, 0.5679012345679013), new double2(0.765625, 0.9012345679012346), new double2(0.140625, 0.04938271604938271), new double2(0.640625, 0.38271604938271603), new double2(0.390625, 0.7160493827160495), new double2(0.890625, 0.16049382716049382), new double2(0.078125, 0.49382716049382713), new double2(0.578125, 0.8271604938271604), new double2(0.328125, 0.2716049382716049), new double2(0.828125, 0.6049382716049383), new double2(0.203125, 0.9382716049382716), new double2(0.703125, 0.08641975308641975), new double2(0.453125, 0.41975308641975306), new double2(0.953125, 0.7530864197530864), new double2(0.046875, 0.19753086419753085), new double2(0.546875, 0.5308641975308641), new double2(0.296875, 0.8641975308641974), new double2(0.796875, 0.30864197530864196), new double2(0.171875, 0.6419753086419753), new double2(0.671875, 0.9753086419753085), new double2(0.421875, 0.024691358024691357), new double2(0.921875, 0.35802469135802467), new double2(0.109375, 0.691358024691358), new double2(0.609375, 0.13580246913580246), new double2(0.359375, 0.4691358024691358), new double2(0.859375, 0.802469135802469), new double2(0.234375, 0.24691358024691357), new double2(0.734375, 0.5802469135802469), new double2(0.484375, 0.9135802469135802), new double2(0.984375, 0.06172839506172839), new double2(0.0078125, 0.3950617283950617), new double2(0.5078125, 0.7283950617283951), new double2(0.2578125, 0.1728395061728395), new double2(0.7578125, 0.5061728395061729), new double2(0.1328125, 0.839506172839506), new double2(0.6328125, 0.2839506172839506), new double2(0.3828125, 0.6172839506172839), new double2(0.8828125, 0.9506172839506172), new double2(0.0703125, 0.09876543209876543), new double2(0.5703125, 0.43209876543209874), new double2(0.3203125, 0.7654320987654321), new double2(0.8203125, 0.20987654320987653), new double2(0.1953125, 0.5432098765432098), new double2(0.6953125, 0.8765432098765431), new double2(0.4453125, 0.32098765432098764), new double2(0.9453125, 0.654320987654321), new double2(0.0390625, 0.9876543209876543), new double2(0.5390625, 0.004115226337448559), new double2(0.2890625, 0.33744855967078186), new double2(0.7890625, 0.6707818930041152), new double2(0.1640625, 0.11522633744855966), new double2(0.6640625, 0.44855967078189296), new double2(0.4140625, 0.7818930041152262), new double2(0.9140625, 0.22633744855967078), new double2(0.1015625, 0.5596707818930041), new double2(0.6015625, 0.8930041152263374), new double2(0.3515625, 0.0411522633744856), new double2(0.8515625, 0.3744855967078189), new double2(0.2265625, 0.7078189300411523), new double2(0.7265625, 0.1522633744855967), new double2(0.4765625, 0.48559670781893), new double2(0.9765625, 0.8189300411522632), new double2(0.0234375, 0.2633744855967078), new double2(0.5234375, 0.5967078189300411), new double2(0.2734375, 0.9300411522633744), new double2(0.7734375, 0.07818930041152262), new double2(0.1484375, 0.4115226337448559), new double2(0.6484375, 0.7448559670781892), new double2(0.3984375, 0.18930041152263374), new double2(0.8984375, 0.522633744855967), new double2(0.0859375, 0.8559670781893003), new double2(0.5859375, 0.3004115226337448), new double2(0.3359375, 0.6337448559670782), new double2(0.8359375, 0.9670781893004115), new double2(0.2109375, 0.016460905349794237), new double2(0.7109375, 0.34979423868312753), new double2(0.4609375, 0.6831275720164608), new double2(0.9609375, 0.12757201646090535), new double2(0.0546875, 0.46090534979423864), new double2(0.5546875, 0.794238683127572), new double2(0.3046875, 0.23868312757201646), new double2(0.8046875, 0.5720164609053499), new double2(0.1796875, 0.9053497942386831), new double2(0.6796875, 0.053497942386831275), new double2(0.4296875, 0.38683127572016457), new double2(0.9296875, 0.720164609053498), new double2(0.1171875, 0.1646090534979424), new double2(0.6171875, 0.4979423868312757), new double2(0.3671875, 0.8312757201646089), new double2(0.8671875, 0.27572016460905346), new double2(0.2421875, 0.6090534979423868), new double2(0.7421875, 0.9423868312757201), new double2(0.4921875, 0.0905349794238683), new double2(0.9921875, 0.4238683127572016), new double2(0.00390625, 0.757201646090535), new double2(0.50390625, 0.20164609053497942), new double2(0.25390625, 0.5349794238683127), new double2(0.75390625, 0.8683127572016459), new double2(0.12890625, 0.3127572016460905), new double2(0.62890625, 0.6460905349794238), new double2(0.37890625, 0.9794238683127571), new double2(0.87890625, 0.028806584362139915), new double2(0.06640625, 0.3621399176954732), new double2(0.56640625, 0.6954732510288065), new double2(0.31640625, 0.13991769547325103), new double2(0.81640625, 0.4732510288065843), new double2(0.19140625, 0.8065843621399176), new double2(0.69140625, 0.2510288065843621), new double2(0.44140625, 0.5843621399176955), new double2(0.94140625, 0.9176954732510287), new double2(0.03515625, 0.06584362139917695), new double2(0.53515625, 0.39917695473251025), new double2(0.28515625, 0.7325102880658436), new double2(0.78515625, 0.17695473251028807), new double2(0.16015625, 0.5102880658436214), new double2(0.66015625, 0.8436213991769546), new double2(0.41015625, 0.28806584362139914), new double2(0.91015625, 0.6213991769547325), new double2(0.09765625, 0.9547325102880657), new double2(0.59765625, 0.10288065843621398), new double2(0.34765625, 0.4362139917695473), new double2(0.84765625, 0.7695473251028806), new double2(0.22265625, 0.2139917695473251), new double2(0.72265625, 0.5473251028806584), new double2(0.47265625, 0.8806584362139916), new double2(0.97265625, 0.3251028806584362), new double2(0.01953125, 0.6584362139917695), new double2(0.51953125, 0.9917695473251028), new double2(0.26953125, 0.008230452674897118), new double2(0.76953125, 0.34156378600823045), new double2(0.14453125, 0.6748971193415637), new double2(0.64453125, 0.11934156378600823), new double2(0.39453125, 0.45267489711934156), new double2(0.89453125, 0.7860082304526748), new double2(0.08203125, 0.23045267489711932), new double2(0.58203125, 0.5637860082304527), new double2(0.33203125, 0.8971193415637859), new double2(0.83203125, 0.04526748971193415), new double2(0.20703125, 0.3786008230452675), new double2(0.70703125, 0.7119341563786008), new double2(0.45703125, 0.15637860082304525), new double2(0.95703125, 0.4897119341563786), new double2(0.05078125, 0.8230452674897117), new double2(0.55078125, 0.2674897119341564), new double2(0.30078125, 0.6008230452674896), new double2(0.80078125, 0.9341563786008229), new double2(0.17578125, 0.0823045267489712), new double2(0.67578125, 0.4156378600823045), new double2(0.42578125, 0.7489711934156378), new double2(0.92578125, 0.19341563786008228), new double2(0.11328125, 0.5267489711934156), new double2(0.61328125, 0.8600823045267488), new double2(0.36328125, 0.3045267489711934), new double2(0.86328125, 0.6378600823045267), new double2(0.23828125, 0.97119341563786), new double2(0.73828125, 0.020576131687242795), new double2(0.48828125, 0.35390946502057613), new double2(0.98828125, 0.6872427983539093), new double2(0.01171875, 0.1316872427983539), new double2(0.51171875, 0.46502057613168724), new double2(0.26171875, 0.7983539094650205), new double2(0.76171875, 0.242798353909465), new double2(0.13671875, 0.5761316872427984), new double2(0.63671875, 0.9094650205761317), new double2(0.38671875, 0.05761316872427983), new double2(0.88671875, 0.39094650205761317), new double2(0.07421875, 0.7242798353909465), new double2(0.57421875, 0.16872427983539093), new double2(0.32421875, 0.5020576131687242), new double2(0.82421875, 0.8353909465020575), new double2(0.19921875, 0.27983539094650206), new double2(0.69921875, 0.6131687242798354), new double2(0.44921875, 0.9465020576131686), new double2(0.94921875, 0.09465020576131687), new double2(0.04296875, 0.4279835390946502), new double2(0.54296875, 0.7613168724279835), new double2(0.29296875, 0.20576131687242796), new double2(0.79296875, 0.5390946502057612), new double2(0.16796875, 0.8724279835390945), new double2(0.66796875, 0.3168724279835391), new double2(0.41796875, 0.6502057613168724), new double2(0.91796875, 0.9835390946502056), new double2(0.10546875, 0.03292181069958847), new double2(0.60546875, 0.3662551440329218), new double2(0.35546875, 0.6995884773662551), new double2(0.85546875, 0.14403292181069957), new double2(0.23046875, 0.4773662551440329), new double2(0.73046875, 0.8106995884773661), new double2(0.48046875, 0.2551440329218107), new double2(0.98046875, 0.588477366255144), new double2(0.02734375, 0.9218106995884773), new double2(0.52734375, 0.06995884773662552), new double2(0.27734375, 0.40329218106995884), new double2(0.77734375, 0.7366255144032922), new double2(0.15234375, 0.1810699588477366), new double2(0.65234375, 0.51440329218107), new double2(0.40234375, 0.8477366255144031), new double2(0.90234375, 0.29218106995884774), new double2(0.08984375, 0.625514403292181), new double2(0.58984375, 0.9588477366255143), new double2(0.33984375, 0.10699588477366255), new double2(0.83984375, 0.4403292181069959), new double2(0.21484375, 0.7736625514403291), new double2(0.71484375, 0.21810699588477364), new double2(0.46484375, 0.5514403292181069), new double2(0.96484375, 0.8847736625514402), new double2(0.05859375, 0.3292181069958848), new double2(0.55859375, 0.6625514403292181), new double2(0.30859375, 0.9958847736625513), new double2(0.80859375, 0.0013717421124828531), new double2(0.18359375, 0.3347050754458162), new double2(0.68359375, 0.6680384087791494), new double2(0.43359375, 0.11248285322359396), new double2(0.93359375, 0.4458161865569273), new double2(0.12109375, 0.7791495198902605), new double2(0.62109375, 0.22359396433470508), new double2(0.37109375, 0.5569272976680384), new double2(0.87109375, 0.8902606310013716), new(0.24609375, 0.03840877914951989), new(0.74609375, 0.3717421124828532), new(0.49609375, 0.7050754458161865), new(0.99609375, 0.149519890260631) }; 33 | 34 | [Range(0, 1)] 35 | public float TemporalFade = 0.95f; 36 | public float MovementBlending = 100; 37 | 38 | [Tooltip("If the resulting image appears upside down. Toggle this variable to unflip the image.")] 39 | public bool UseFlipUV = false; 40 | 41 | public Material TAAMaterial; 42 | 43 | public float JitterSpread = 1; 44 | [Range(1, 256)] 45 | public int HaltonLength = 8; 46 | 47 | class TemporalAAPass : ScriptableRenderPass 48 | { 49 | 50 | [Range(0, 1)] 51 | public float TemporalFade; 52 | public float MovementBlending; 53 | public bool UseFlipUV; 54 | 55 | public Material TAAMaterial; 56 | 57 | public float JitterSpread = 1; 58 | [Range(1, 256)] 59 | public int HaltonLength = 8; 60 | 61 | public static RenderTexture temp, temp1; 62 | 63 | private Matrix4x4 prevViewProjectionMatrix; 64 | 65 | private UnityEngine.Camera prevRenderCamera; 66 | 67 | private TemporalAAFeature feature; 68 | 69 | public TemporalAAPass(TemporalAAFeature inFeature) : base() 70 | { 71 | if (temp) 72 | { 73 | temp.Release(); 74 | temp1.Release(); 75 | temp = null; 76 | } 77 | 78 | feature = inFeature; 79 | } 80 | 81 | public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData) 82 | { 83 | base.OnCameraSetup(cmd, ref renderingData); 84 | 85 | if (renderingData.cameraData.cameraType != CameraType.Game) 86 | return; 87 | 88 | prevRenderCamera = renderingData.cameraData.camera; 89 | 90 | ConfigureInput(ScriptableRenderPassInput.Color); 91 | ConfigureInput(ScriptableRenderPassInput.Depth); 92 | 93 | RenderTextureDescriptor currentCameraDescriptor = renderingData.cameraData.cameraTargetDescriptor; 94 | 95 | if (temp && (currentCameraDescriptor.width != temp.width || currentCameraDescriptor.height != temp.height)) 96 | { 97 | Debug.Log("Deleting Render Target: " + currentCameraDescriptor.width + " " + temp.width); 98 | 99 | temp.Release(); 100 | temp1.Release(); 101 | temp = null; 102 | } 103 | 104 | if (!temp) 105 | { 106 | temp = new RenderTexture(currentCameraDescriptor.width, currentCameraDescriptor.height, UnityEngine.Experimental.Rendering.GraphicsFormat.R16G16B16A16_SFloat, 0); 107 | temp1 = new RenderTexture(currentCameraDescriptor.width, currentCameraDescriptor.height, UnityEngine.Experimental.Rendering.GraphicsFormat.R16G16B16A16_SFloat, 0); 108 | 109 | Debug.Log("Allocating new Render Target"); 110 | } 111 | } 112 | 113 | // Here you can implement the rendering logic. 114 | // Use ScriptableRenderContext to issue drawing commands or execute command buffers 115 | // https://docs.unity3d.com/ScriptReference/Rendering.ScriptableRenderContext.html 116 | // You don't have to call ScriptableRenderContext.submit, the render pipeline will call it at specific points in the pipeline. 117 | public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) 118 | { 119 | 120 | if (renderingData.cameraData.cameraType != CameraType.Game) 121 | return; 122 | 123 | UpdateValuesFromFeature(); 124 | CommandBuffer cmd = CommandBufferPool.Get("TemporalAAPass"); 125 | 126 | 127 | TAAMaterial.SetTexture("_TemporalAATexture", temp); 128 | 129 | 130 | Matrix4x4 mt = renderingData.cameraData.camera.nonJitteredProjectionMatrix.inverse; 131 | TAAMaterial.SetMatrix("_invP", mt); 132 | 133 | mt = this.prevViewProjectionMatrix * renderingData.cameraData.camera.cameraToWorldMatrix; 134 | TAAMaterial.SetMatrix("_FrameMatrix", mt); 135 | 136 | TAAMaterial.SetFloat("_TemporalFade", TemporalFade); 137 | TAAMaterial.SetFloat("_MovementBlending", MovementBlending); 138 | TAAMaterial.SetInt("_UseFlipUV", UseFlipUV ? 1 : 0); 139 | 140 | Blit(cmd, BuiltinRenderTextureType.CurrentActive, temp1, TAAMaterial); 141 | 142 | Blit(cmd, temp1, renderingData.cameraData.renderer.cameraColorTarget); 143 | 144 | 145 | //Ping pong 146 | RenderTexture temp2 = temp; 147 | temp = temp1; 148 | temp1 = temp2; 149 | 150 | context.ExecuteCommandBuffer(cmd); 151 | CommandBufferPool.Release(cmd); 152 | 153 | 154 | this.prevViewProjectionMatrix = renderingData.cameraData.camera.nonJitteredProjectionMatrix * renderingData.cameraData.camera.worldToCameraMatrix; 155 | 156 | renderingData.cameraData.camera.ResetProjectionMatrix(); 157 | } 158 | 159 | private void UpdateValuesFromFeature() 160 | { 161 | TemporalFade = feature.TemporalFade; 162 | MovementBlending = feature.MovementBlending; 163 | HaltonLength = feature.HaltonLength; 164 | JitterSpread = feature.JitterSpread; 165 | } 166 | 167 | /// Cleanup any allocated resources that were created during the execution of this render pass. 168 | public override void FrameCleanup(CommandBuffer cmd) 169 | { 170 | base.FrameCleanup(cmd); 171 | var cam = prevRenderCamera; 172 | if (!cam) { 173 | return; 174 | } 175 | 176 | cam.ResetWorldToCameraMatrix(); 177 | cam.ResetProjectionMatrix(); 178 | 179 | cam.nonJitteredProjectionMatrix = cam.projectionMatrix; 180 | 181 | Matrix4x4 p = cam.projectionMatrix; 182 | float2 jitter = (float2)(2 * Halton2364Seq[Time.frameCount % HaltonLength] - 1) * JitterSpread; 183 | p.m02 = jitter.x / (float)Screen.width; 184 | p.m12 = jitter.y / (float)Screen.height; 185 | cam.projectionMatrix = p; 186 | } 187 | } 188 | 189 | TemporalAAPass m_temporalPass; 190 | 191 | public override void Create() 192 | { 193 | m_temporalPass = new TemporalAAPass(this); 194 | m_temporalPass.TemporalFade = TemporalFade; 195 | m_temporalPass.MovementBlending = MovementBlending; 196 | m_temporalPass.TAAMaterial = TAAMaterial; 197 | m_temporalPass.HaltonLength = HaltonLength; 198 | m_temporalPass.JitterSpread = JitterSpread; 199 | m_temporalPass.UseFlipUV = this.UseFlipUV; 200 | 201 | // Configures where the render pass should be injected. 202 | m_temporalPass.renderPassEvent = RenderPassEvent.BeforeRenderingPostProcessing; 203 | } 204 | 205 | // Here you can inject one or multiple render passes in the renderer. 206 | // This method is called when setting up the renderer once per-camera. 207 | public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) 208 | { 209 | renderer.EnqueuePass(m_temporalPass); 210 | } 211 | } 212 | -------------------------------------------------------------------------------- /TemporalAA/TemporalAAFeature.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b49db325366a51e408a57f6588940f70 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: 7 | - TAAMaterial: {fileID: 2100000, guid: 2b9d611108abd0047abdd27d7ca47e21, type: 2} 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /TemporalAA/TemporalAAMaterial.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!114 &-5271933894944911715 4 | MonoBehaviour: 5 | m_ObjectHideFlags: 11 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | m_GameObject: {fileID: 0} 10 | m_Enabled: 1 11 | m_EditorHideFlags: 0 12 | m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3} 13 | m_Name: 14 | m_EditorClassIdentifier: 15 | version: 5 16 | --- !u!21 &2100000 17 | Material: 18 | serializedVersion: 8 19 | m_ObjectHideFlags: 0 20 | m_CorrespondingSourceObject: {fileID: 0} 21 | m_PrefabInstance: {fileID: 0} 22 | m_PrefabAsset: {fileID: 0} 23 | m_Name: TemporalAAMaterial 24 | m_Shader: {fileID: 4800000, guid: e70e79769116bcb459267c30398727c4, type: 3} 25 | m_Parent: {fileID: 0} 26 | m_ModifiedSerializedProperties: 0 27 | m_ValidKeywords: [] 28 | m_InvalidKeywords: [] 29 | m_LightmapFlags: 4 30 | m_EnableInstancingVariants: 0 31 | m_DoubleSidedGI: 0 32 | m_CustomRenderQueue: -1 33 | stringTagMap: {} 34 | disabledShaderPasses: [] 35 | m_LockedProperties: 36 | m_SavedProperties: 37 | serializedVersion: 3 38 | m_TexEnvs: 39 | - _BaseMap: 40 | m_Texture: {fileID: 0} 41 | m_Scale: {x: 1, y: 1} 42 | m_Offset: {x: 0, y: 0} 43 | - _BumpMap: 44 | m_Texture: {fileID: 0} 45 | m_Scale: {x: 1, y: 1} 46 | m_Offset: {x: 0, y: 0} 47 | - _DetailAlbedoMap: 48 | m_Texture: {fileID: 0} 49 | m_Scale: {x: 1, y: 1} 50 | m_Offset: {x: 0, y: 0} 51 | - _DetailMask: 52 | m_Texture: {fileID: 0} 53 | m_Scale: {x: 1, y: 1} 54 | m_Offset: {x: 0, y: 0} 55 | - _DetailNormalMap: 56 | m_Texture: {fileID: 0} 57 | m_Scale: {x: 1, y: 1} 58 | m_Offset: {x: 0, y: 0} 59 | - _EmissionMap: 60 | m_Texture: {fileID: 0} 61 | m_Scale: {x: 1, y: 1} 62 | m_Offset: {x: 0, y: 0} 63 | - _MainTex: 64 | m_Texture: {fileID: 0} 65 | m_Scale: {x: 1, y: 1} 66 | m_Offset: {x: 0, y: 0} 67 | - _MetallicGlossMap: 68 | m_Texture: {fileID: 0} 69 | m_Scale: {x: 1, y: 1} 70 | m_Offset: {x: 0, y: 0} 71 | - _OcclusionMap: 72 | m_Texture: {fileID: 0} 73 | m_Scale: {x: 1, y: 1} 74 | m_Offset: {x: 0, y: 0} 75 | - _ParallaxMap: 76 | m_Texture: {fileID: 0} 77 | m_Scale: {x: 1, y: 1} 78 | m_Offset: {x: 0, y: 0} 79 | - _SpecGlossMap: 80 | m_Texture: {fileID: 0} 81 | m_Scale: {x: 1, y: 1} 82 | m_Offset: {x: 0, y: 0} 83 | - _TemporalAATexture: 84 | m_Texture: {fileID: 0} 85 | m_Scale: {x: 1, y: 1} 86 | m_Offset: {x: 0, y: 0} 87 | - unity_Lightmaps: 88 | m_Texture: {fileID: 0} 89 | m_Scale: {x: 1, y: 1} 90 | m_Offset: {x: 0, y: 0} 91 | - unity_LightmapsInd: 92 | m_Texture: {fileID: 0} 93 | m_Scale: {x: 1, y: 1} 94 | m_Offset: {x: 0, y: 0} 95 | - unity_ShadowMasks: 96 | m_Texture: {fileID: 0} 97 | m_Scale: {x: 1, y: 1} 98 | m_Offset: {x: 0, y: 0} 99 | m_Ints: [] 100 | m_Floats: 101 | - _AlphaClip: 0 102 | - _Blend: 0 103 | - _BumpScale: 1 104 | - _ClearCoatMask: 0 105 | - _ClearCoatSmoothness: 0 106 | - _Cull: 2 107 | - _Cutoff: 0.5 108 | - _DetailAlbedoMapScale: 1 109 | - _DetailNormalMapScale: 1 110 | - _DstBlend: 0 111 | - _EnvironmentReflections: 1 112 | - _GlossMapScale: 0 113 | - _Glossiness: 0 114 | - _GlossyReflections: 0 115 | - _Metallic: 0 116 | - _OcclusionStrength: 1 117 | - _Parallax: 0.005 118 | - _QueueOffset: 0 119 | - _ReceiveShadows: 1 120 | - _Smoothness: 0.5 121 | - _SmoothnessTextureChannel: 0 122 | - _SpecularHighlights: 1 123 | - _SrcBlend: 1 124 | - _Surface: 0 125 | - _TemporalFade: 0.95 126 | - _WorkflowMode: 1 127 | - _ZWrite: 1 128 | m_Colors: 129 | - _BaseColor: {r: 1, g: 1, b: 1, a: 1} 130 | - _Color: {r: 1, g: 1, b: 1, a: 1} 131 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 132 | - _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1} 133 | m_BuildTextureStacks: [] 134 | -------------------------------------------------------------------------------- /TemporalAA/TemporalAAMaterial.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2b9d611108abd0047abdd27d7ca47e21 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 2100000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /TemporalAA/TemporalAAShader.shader: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2022 Pascal Zwick 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | Shader "Hidden/TemporalAAShader" 26 | { 27 | Properties 28 | { 29 | _MainTex ("Main Texture", 2D) = "white" {} 30 | _TemporalFade("Temporal Fade", Range(0, 1)) = 0.0 31 | } 32 | SubShader 33 | { 34 | // No culling or depth 35 | Cull Back ZWrite Off ZTest Always 36 | 37 | Pass 38 | { 39 | CGPROGRAM 40 | #pragma vertex vert 41 | #pragma fragment frag 42 | 43 | #include "UnityCG.cginc" 44 | 45 | struct appdata 46 | { 47 | float4 vertex : POSITION; 48 | float2 uv : TEXCOORD0; 49 | }; 50 | 51 | struct v2f 52 | { 53 | float2 uv : TEXCOORD0; 54 | float4 vertex : SV_POSITION; 55 | }; 56 | 57 | v2f vert (appdata v) 58 | { 59 | v2f o; 60 | o.vertex = UnityObjectToClipPos(v.vertex); 61 | o.uv = v.uv; 62 | return o; 63 | } 64 | 65 | sampler2D _MainTex; 66 | 67 | //sampler2D _MotionVectorTexture; 68 | sampler2D _CameraDepthTexture; 69 | 70 | sampler2D _TemporalAATexture; 71 | 72 | float _TemporalFade; 73 | float _MovementBlending; 74 | bool _UseFlipUV; 75 | 76 | float4x4 _invP; 77 | float4x4 _FrameMatrix; 78 | 79 | 80 | float sampleDepth(float2 uv) { 81 | //float rd = _CameraDepthTexture.Load(int3(pix, 0)).x; 82 | float rd = tex2D(_CameraDepthTexture, uv).x; 83 | return Linear01Depth(rd); 84 | } 85 | 86 | /* 87 | Box intersection by IQ, modified for neighbourhood clamping 88 | https://www.iquilezles.org/www/articles/boxfunctions/boxfunctions.htm 89 | */ 90 | float2 boxIntersection(in float3 ro, in float3 rd, in float3 rad) 91 | { 92 | float3 m = 1.0 / rd; 93 | float3 n = m * ro; 94 | float3 k = abs(m) * rad; 95 | float3 t1 = -n - k; 96 | float3 t2 = -n + k; 97 | 98 | float tN = max(max(t1.x, t1.y), t1.z); 99 | float tF = min(min(t2.x, t2.y), t2.z); 100 | 101 | return float2(tN, tF); 102 | } 103 | 104 | /* 105 | * GLSL Color Spaces by tobspr 106 | * https://github.com/tobspr/GLSL-Color-Spaces 107 | */ 108 | // RGB to YCbCr, ranges [0, 1] 109 | float3 rgb_to_ycbcr(float3 rgb) { 110 | float y = 0.299 * rgb.r + 0.587 * rgb.g + 0.114 * rgb.b; 111 | float cb = (rgb.b - y) * 0.565; 112 | float cr = (rgb.r - y) * 0.713; 113 | 114 | return float3(y, cb, cr); 115 | } 116 | 117 | // YCbCr to RGB 118 | float3 ycbcr_to_rgb(float3 yuv) { 119 | return float3( 120 | yuv.x + 1.403 * yuv.z, 121 | yuv.x - 0.344 * yuv.y - 0.714 * yuv.z, 122 | yuv.x + 1.770 * yuv.y 123 | ); 124 | } 125 | //### 126 | 127 | float3 clipLuminance(float3 col, float3 minCol, float3 maxCol){ 128 | float3 c0 = rgb_to_ycbcr(col); 129 | //float3 c1 = rgb_to_ycbcr(minCol); 130 | //float3 c2 = rgb_to_ycbcr(maxCol); 131 | 132 | //c0 = clamp(c0, c1, c2); 133 | c0 = clamp(c0, minCol, maxCol); 134 | 135 | return ycbcr_to_rgb(c0); 136 | } 137 | 138 | fixed4 frag(v2f i) : SV_Target 139 | { 140 | 141 | float2 baseUV = i.uv; 142 | if (_UseFlipUV) 143 | i.uv.y = 1 - i.uv.y; 144 | 145 | float4 curCol = tex2D(_MainTex, i.uv); 146 | 147 | //temporal reprojection 148 | float d0 = sampleDepth(i.uv); 149 | float d01 = (d0 * (_ProjectionParams.z - _ProjectionParams.y) + _ProjectionParams.y) / _ProjectionParams.z; 150 | float3 pos = float3(baseUV * 2.0 - 1.0, 1.0); 151 | float4 rd = mul(_invP, float4(pos, 1)); 152 | rd.xyz /= rd.w; 153 | 154 | float4 temporalUV = mul(_FrameMatrix, float4(rd.xyz * d01, 1)); 155 | temporalUV /= temporalUV.w; 156 | 157 | //float2 temporalUV = i.uv - tex2D(_MotionVectorTexture, i.uv).xy; 158 | float3 lastCol = tex2D(_TemporalAATexture, temporalUV*0.5+0.5).xyz; 159 | if (abs(temporalUV.x) > 1 || abs(temporalUV.y) > 1) 160 | lastCol = curCol; 161 | // 162 | 163 | // Neighbourhood clipping 164 | //float3 ya = rgb_to_ycbcr(curCol); 165 | float3 ya = curCol; 166 | float3 minCol = ya; 167 | float3 maxCol = ya; 168 | 169 | for (int x = -1; x <= 1; ++x) { 170 | for (int y = -1; y <= 1; ++y) { 171 | float2 duv = float2(x, y) / _ScreenParams.xy; 172 | //float3 s = rgb_to_ycbcr(tex2D(_MainTex, i.uv + duv).xyz); 173 | float3 s = tex2D(_MainTex, i.uv + duv).xyz; 174 | 175 | minCol = min(minCol, s); 176 | maxCol = max(maxCol, s); 177 | } 178 | } 179 | //lastCol = mul(YCoCgToRGBMatrix, clamp(mul(RGBToYCoCgMatrix, lastCol), minCol, maxCol)); 180 | lastCol = clamp(lastCol, minCol, maxCol); 181 | //lastCol = clipLuminance(lastCol, minCol, maxCol); 182 | // 183 | 184 | float temporalMultiplier = exp(-_MovementBlending * length(pos.xy - temporalUV)); 185 | float3 finalCol = lerp(curCol, lastCol, _TemporalFade * temporalMultiplier); 186 | //finalCol = length(minCol - maxCol).xxx; 187 | 188 | return float4(finalCol, 1); 189 | } 190 | ENDCG 191 | } 192 | } 193 | } 194 | -------------------------------------------------------------------------------- /TemporalAA/TemporalAAShader.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e70e79769116bcb459267c30398727c4 3 | ShaderImporter: 4 | externalObjects: {} 5 | defaultTextures: [] 6 | nonModifiableTextures: [] 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /res/comp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CMDRSpirit/URPTemporalAA/86f4d28bc5ee8115bff87ee61afe398a6b03f61a/res/comp.png --------------------------------------------------------------------------------