diff --git a/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime.meta b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime.meta
new file mode 100644
index 0000000..3e15b23
--- /dev/null
+++ b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 6bbfbdd9fd482bd4ea5e998953ae9972
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/Asr.cs b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/Asr.cs
new file mode 100644
index 0000000..a75fab0
--- /dev/null
+++ b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/Asr.cs
@@ -0,0 +1,292 @@
+// Copyright (c) 2024 Nico de Poel
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+using System;
+using System.Runtime.InteropServices;
+using UnityEngine;
+
+namespace ArmASR
+{
+ ///
+ /// A collection of helper functions and data structures required by the ASR process.
+ ///
+ public static class Asr
+ {
+ ///
+ /// Creates a new ASR context with standard parameters that are appropriate for the current platform.
+ ///
+ public static AsrContext CreateContext(Vector2Int displaySize, Vector2Int maxRenderSize, AsrShaders shaders, InitializationFlags flags = 0)
+ {
+ if (SystemInfo.usesReversedZBuffer)
+ flags |= InitializationFlags.EnableDepthInverted;
+ else
+ flags &= ~InitializationFlags.EnableDepthInverted;
+
+#if UNITY_EDITOR || DEVELOPMENT_BUILD
+ flags |= InitializationFlags.EnableDebugChecking;
+#endif
+
+ Debug.Log($"Setting up Arm ASR with render size: {maxRenderSize.x}x{maxRenderSize.y}, display size: {displaySize.x}x{displaySize.y}, flags: {flags}");
+
+ var contextDescription = new ContextDescription
+ {
+ Flags = flags,
+ DisplaySize = displaySize,
+ MaxRenderSize = maxRenderSize,
+ Shaders = shaders,
+ };
+
+ var context = new AsrContext();
+ context.Create(contextDescription);
+ return context;
+ }
+
+ public static float GetUpscaleRatioFromQualityMode(QualityMode qualityMode)
+ {
+ switch (qualityMode)
+ {
+ case QualityMode.NativeAA:
+ return 1.0f;
+ case QualityMode.UltraQuality:
+ return 1.2f;
+ case QualityMode.Quality:
+ return 1.5f;
+ case QualityMode.Balanced:
+ return 1.7f;
+ case QualityMode.Performance:
+ return 2.0f;
+ case QualityMode.UltraPerformance:
+ return 3.0f;
+ default:
+ return 1.0f;
+ }
+ }
+
+ public static void GetRenderResolutionFromQualityMode(
+ out int renderWidth, out int renderHeight,
+ int displayWidth, int displayHeight, QualityMode qualityMode)
+ {
+ float ratio = GetUpscaleRatioFromQualityMode(qualityMode);
+ renderWidth = Mathf.RoundToInt(displayWidth / ratio);
+ renderHeight = Mathf.RoundToInt(displayHeight / ratio);
+ }
+
+ public static float GetMipmapBiasOffset(int renderWidth, int displayWidth)
+ {
+ return Mathf.Log((float)renderWidth / displayWidth, 2.0f) - 1.0f;
+ }
+
+ public static int GetJitterPhaseCount(int renderWidth, int displayWidth)
+ {
+ const float basePhaseCount = 8.0f;
+ int jitterPhaseCount = (int)(basePhaseCount * Mathf.Pow((float)displayWidth / renderWidth, 2.0f));
+ return jitterPhaseCount;
+ }
+
+ public static void GetJitterOffset(out float outX, out float outY, int index, int phaseCount)
+ {
+ outX = Halton((index % phaseCount) + 1, 2) - 0.5f;
+ outY = Halton((index % phaseCount) + 1, 3) - 0.5f;
+ }
+
+ // Calculate halton number for index and base.
+ private static float Halton(int index, int @base)
+ {
+ float f = 1.0f, result = 0.0f;
+
+ for (int currentIndex = index; currentIndex > 0;) {
+
+ f /= @base;
+ result += f * (currentIndex % @base);
+ currentIndex = (int)Mathf.Floor((float)currentIndex / @base);
+ }
+
+ return result;
+ }
+
+ public static float Lanczos2(float value)
+ {
+ return Mathf.Abs(value) < Mathf.Epsilon ? 1.0f : Mathf.Sin(Mathf.PI * value) / (Mathf.PI * value) * (Mathf.Sin(0.5f * Mathf.PI * value) / (0.5f * Mathf.PI * value));
+ }
+
+#if !UNITY_2021_1_OR_NEWER
+ internal static void SetBufferData(this CommandBuffer commandBuffer, ComputeBuffer computeBuffer, Array data)
+ {
+ commandBuffer.SetComputeBufferData(computeBuffer, data);
+ }
+#endif
+
+ public enum QualityMode
+ {
+ NativeAA = 0,
+ UltraQuality = 1,
+ Quality = 2,
+ Balanced = 3,
+ Performance = 4,
+ UltraPerformance = 5,
+ }
+
+ [Flags]
+ public enum InitializationFlags
+ {
+ EnableHighDynamicRange = 1 << 0,
+ EnableDisplayResolutionMotionVectors = 1 << 1,
+ EnableMotionVectorsJitterCancellation = 1 << 2,
+ EnableDepthInverted = 1 << 3,
+ EnableDepthInfinite = 1 << 4,
+ EnableAutoExposure = 1 << 5,
+ EnableDynamicResolution = 1 << 6,
+ EnableFP16Usage = 1 << 7,
+ EnableDebugChecking = 1 << 8,
+ }
+
+ ///
+ /// A structure encapsulating the parameters required to initialize FidelityFX Super Resolution 2 upscaling.
+ ///
+ public struct ContextDescription
+ {
+ public InitializationFlags Flags;
+ public Vector2Int MaxRenderSize;
+ public Vector2Int DisplaySize;
+ public AsrShaders Shaders;
+ }
+
+ ///
+ /// A structure encapsulating the parameters for dispatching the various passes of FidelityFX Super Resolution 2.
+ ///
+ public class DispatchDescription
+ {
+ public ResourceView Color;
+ public ResourceView Depth;
+ public ResourceView MotionVectors;
+ public ResourceView Exposure; // optional
+ public ResourceView Reactive; // optional
+ public ResourceView TransparencyAndComposition; // optional
+ public ResourceView Output;
+ public Vector2 JitterOffset;
+ public Vector2 MotionVectorScale;
+ public Vector2Int RenderSize;
+ public Vector2Int InputResourceSize;
+ public bool EnableSharpening;
+ public float Sharpness;
+ public float FrameTimeDelta; // in seconds
+ public float PreExposure;
+ public bool Reset;
+ public float CameraNear;
+ public float CameraFar;
+ public float CameraFovAngleVertical;
+ public float ViewSpaceToMetersFactor;
+ public bool UseTextureArrays; // Enable texture array bindings, primarily used for HDRP and XR
+ }
+
+ ///
+ /// A structure encapsulating the parameters for automatic generation of a reactive mask.
+ ///
+ public class GenerateReactiveDescription
+ {
+ public ResourceView ColorOpaqueOnly;
+ public ResourceView ColorPreUpscale;
+ public ResourceView OutReactive;
+ public Vector2Int RenderSize;
+ public float Scale = 0.5f;
+ public float CutoffThreshold = 0.2f;
+ public float BinaryValue = 0.9f;
+ public GenerateReactiveFlags Flags = GenerateReactiveFlags.ApplyTonemap | GenerateReactiveFlags.ApplyThreshold | GenerateReactiveFlags.UseComponentsMax;
+ }
+
+ [Flags]
+ public enum GenerateReactiveFlags
+ {
+ ApplyTonemap = 1 << 0,
+ ApplyInverseTonemap = 1 << 1,
+ ApplyThreshold = 1 << 2,
+ UseComponentsMax = 1 << 3,
+ }
+
+ [Serializable, StructLayout(LayoutKind.Sequential)]
+ internal struct UpscalerConstants
+ {
+ public Vector2Int renderSize;
+ public Vector2Int maxRenderSize;
+ public Vector2Int displaySize;
+ public Vector2Int inputColorResourceDimensions;
+ public Vector2Int lumaMipDimensions;
+ public int lumaMipLevelToUse;
+ public int frameIndex;
+
+ public Vector4 deviceToViewDepth;
+ public Vector2 jitterOffset;
+ public Vector2 motionVectorScale;
+ public Vector2 downscaleFactor;
+ public Vector2 motionVectorJitterCancellation;
+ public float preExposure;
+ public float previousFramePreExposure;
+ public float tanHalfFOV;
+ public float jitterPhaseCount;
+ public float deltaTime;
+ public float dynamicResChangeFactor;
+ public float viewSpaceToMetersFactor;
+ public float padding;
+ }
+
+ [Serializable, StructLayout(LayoutKind.Sequential)]
+ internal struct SpdConstants
+ {
+ public uint mips;
+ public uint numWorkGroups;
+ public uint workGroupOffsetX, workGroupOffsetY;
+ public uint renderSizeX, renderSizeY;
+ }
+
+ [Serializable, StructLayout(LayoutKind.Sequential)]
+ internal struct GenerateReactiveConstants
+ {
+ public float scale;
+ public float threshold;
+ public float binaryValue;
+ public uint flags;
+ }
+
+ [Serializable, StructLayout(LayoutKind.Sequential)]
+ internal struct GenerateReactiveConstants2
+ {
+ public float autoTcThreshold;
+ public float autoTcScale;
+ public float autoReactiveScale;
+ public float autoReactiveMax;
+ }
+
+ [Serializable, StructLayout(LayoutKind.Sequential)]
+ internal struct RcasConstants
+ {
+ public RcasConstants(uint sharpness, uint halfSharp)
+ {
+ this.sharpness = sharpness;
+ this.halfSharp = halfSharp;
+ dummy0 = dummy1 = 0;
+ }
+
+ public readonly uint sharpness;
+ public readonly uint halfSharp;
+ public readonly uint dummy0;
+ public readonly uint dummy1;
+ }
+ }
+}
diff --git a/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/Asr.cs.meta b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/Asr.cs.meta
new file mode 100644
index 0000000..e36c358
--- /dev/null
+++ b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/Asr.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: c7350363c6d8a2b4096a9ed97dc4ed95
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/AsrAssets.cs b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/AsrAssets.cs
new file mode 100644
index 0000000..95ff401
--- /dev/null
+++ b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/AsrAssets.cs
@@ -0,0 +1,152 @@
+// Copyright (c) 2024 Nico de Poel
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+using UnityEngine;
+
+namespace ArmASR
+{
+ ///
+ /// Scriptable object containing all shader resources required by Arm Accuracy Super Resolution (ASR).
+ /// These can be stored in an asset file and referenced from a scene or prefab, avoiding the need to load the shaders from a Resources folder.
+ ///
+ [CreateAssetMenu(fileName = "ASR Assets", menuName = "ARM/ASR Assets", order = 1102)]
+ public class AsrAssets : ScriptableObject
+ {
+ public AsrShaders shaders;
+
+#if UNITY_EDITOR
+ private void Reset()
+ {
+ shaders = new AsrShaders
+ {
+ computeLuminancePyramidPass = FindComputeShader("ffxm_fsr2_compute_luminance_pyramid_pass"),
+ reconstructPreviousDepthPass = FindComputeShader("ffx_fsr2_reconstruct_previous_depth_pass"),
+ depthClipPass = FindComputeShader("ffx_fsr2_depth_clip_pass"),
+ lockPass = FindComputeShader("ffxm_fsr2_lock_pass"),
+ accumulatePass = FindComputeShader("ffx_fsr2_accumulate_pass"),
+ sharpenPass = FindComputeShader("ffx_fsr2_rcas_pass"),
+ autoGenReactivePass = FindComputeShader("ffx_fsr2_autogen_reactive_pass"),
+ tcrAutoGenPass = FindComputeShader("ffx_fsr2_tcr_autogen_pass"),
+ };
+ }
+
+ private static ComputeShader FindComputeShader(string name)
+ {
+ string[] assetGuids = UnityEditor.AssetDatabase.FindAssets($"t:ComputeShader {name}");
+ if (assetGuids == null || assetGuids.Length == 0)
+ return null;
+
+ string assetPath = UnityEditor.AssetDatabase.GUIDToAssetPath(assetGuids[0]);
+ return UnityEditor.AssetDatabase.LoadAssetAtPath(assetPath);
+ }
+#endif
+ }
+
+ ///
+ /// All the compute shaders used by ASR.
+ ///
+ [System.Serializable]
+ public class AsrShaders
+ {
+ ///
+ /// The compute shader used by the luminance pyramid computation pass.
+ ///
+ public ComputeShader computeLuminancePyramidPass;
+
+ ///
+ /// The compute shader used by the previous depth reconstruction pass.
+ ///
+ public ComputeShader reconstructPreviousDepthPass;
+
+ ///
+ /// The compute shader used by the depth clip pass.
+ ///
+ public ComputeShader depthClipPass;
+
+ ///
+ /// The compute shader used by the lock pass.
+ ///
+ public ComputeShader lockPass;
+
+ ///
+ /// The compute shader used by the accumulation pass.
+ ///
+ public ComputeShader accumulatePass;
+
+ ///
+ /// The compute shader used by the RCAS sharpening pass.
+ ///
+ public ComputeShader sharpenPass;
+
+ ///
+ /// The compute shader used to auto-generate a reactive mask.
+ ///
+ public ComputeShader autoGenReactivePass;
+
+ ///
+ /// The compute shader used to auto-generate a transparency & composition mask.
+ ///
+ public ComputeShader tcrAutoGenPass;
+
+ ///
+ /// Returns a copy of this class and its contents.
+ ///
+ public AsrShaders Clone()
+ {
+ return (AsrShaders)MemberwiseClone();
+ }
+
+ ///
+ /// Returns a copy of this class with clones of all its shaders.
+ /// This can be useful if you're running multiple ASR instances with different shader configurations.
+ /// Be sure to clean up these clones through Dispose once you're done with them.
+ ///
+ public AsrShaders DeepCopy()
+ {
+ return new AsrShaders
+ {
+ computeLuminancePyramidPass = Object.Instantiate(computeLuminancePyramidPass),
+ reconstructPreviousDepthPass = Object.Instantiate(reconstructPreviousDepthPass),
+ depthClipPass = Object.Instantiate(depthClipPass),
+ lockPass = Object.Instantiate(lockPass),
+ accumulatePass = Object.Instantiate(accumulatePass),
+ sharpenPass = Object.Instantiate(sharpenPass),
+ autoGenReactivePass = Object.Instantiate(autoGenReactivePass),
+ tcrAutoGenPass = Object.Instantiate(tcrAutoGenPass),
+ };
+ }
+
+ ///
+ /// Destroy all the shaders within this instance.
+ /// Use this only on clones created through DeepCopy.
+ ///
+ public void Dispose()
+ {
+ Object.Destroy(computeLuminancePyramidPass);
+ Object.Destroy(reconstructPreviousDepthPass);
+ Object.Destroy(depthClipPass);
+ Object.Destroy(lockPass);
+ Object.Destroy(accumulatePass);
+ Object.Destroy(sharpenPass);
+ Object.Destroy(autoGenReactivePass);
+ Object.Destroy(tcrAutoGenPass);
+ }
+ }
+}
diff --git a/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/AsrAssets.cs.meta b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/AsrAssets.cs.meta
new file mode 100644
index 0000000..022b8ab
--- /dev/null
+++ b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/AsrAssets.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 7a41695239eb36740847744b34c5af43
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/AsrCallbacks.cs b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/AsrCallbacks.cs
new file mode 100644
index 0000000..50fe7a6
--- /dev/null
+++ b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/AsrCallbacks.cs
@@ -0,0 +1,81 @@
+// Copyright (c) 2024 Nico de Poel
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+using UnityEngine;
+
+namespace ArmASR
+{
+ ///
+ /// A collection of callbacks required by the ASR process.
+ /// This allows some customization by the game dev on how to integrate ASR upscaling into their own game setup.
+ ///
+ public interface IAsrCallbacks
+ {
+ ///
+ /// Apply a mipmap bias to in-game textures to prevent them from becoming blurry as the internal rendering resolution lowers.
+ /// This will need to be customized on a per-game basis, as there is no clear universal way to determine what are "in-game" textures.
+ /// The default implementation will simply apply a mipmap bias to all 2D textures, which will include things like UI textures and which might miss things like terrain texture arrays.
+ ///
+ /// Depending on how your game organizes its assets, you will want to create a filter that more specifically selects the textures that need to have this mipmap bias applied.
+ /// You may also want to store the bias offset value and apply it to any assets that are loaded in on demand.
+ ///
+ void ApplyMipmapBias(float biasOffset);
+
+ void UndoMipmapBias();
+ }
+
+ ///
+ /// Default implementation of IAsrCallbacks.
+ /// These are fine for testing but a proper game will want to extend and override these methods.
+ ///
+ public class AsrCallbacksBase: IAsrCallbacks
+ {
+ protected float CurrentBiasOffset = 0;
+
+ public virtual void ApplyMipmapBias(float biasOffset)
+ {
+ if (float.IsNaN(biasOffset) || float.IsInfinity(biasOffset))
+ return;
+
+ CurrentBiasOffset += biasOffset;
+
+ if (Mathf.Approximately(CurrentBiasOffset, 0f))
+ {
+ CurrentBiasOffset = 0f;
+ }
+
+ foreach (var texture in Resources.FindObjectsOfTypeAll())
+ {
+ if (texture.mipmapCount <= 1)
+ continue;
+
+ texture.mipMapBias += biasOffset;
+ }
+ }
+
+ public virtual void UndoMipmapBias()
+ {
+ if (CurrentBiasOffset == 0f)
+ return;
+
+ ApplyMipmapBias(-CurrentBiasOffset);
+ }
+ }
+}
diff --git a/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/AsrCallbacks.cs.meta b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/AsrCallbacks.cs.meta
new file mode 100644
index 0000000..2724280
--- /dev/null
+++ b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/AsrCallbacks.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 78f16fcb80e6325429dfa567a4ed5d4a
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/AsrContext.cs b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/AsrContext.cs
new file mode 100644
index 0000000..245a87b
--- /dev/null
+++ b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/AsrContext.cs
@@ -0,0 +1,570 @@
+// Copyright (c) 2024 Nico de Poel
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+using System;
+using System.Runtime.InteropServices;
+using UnityEngine;
+using UnityEngine.Rendering;
+
+namespace ArmASR
+{
+ ///
+ /// This class loosely matches the FfxFsr2Context struct from the original FSR2 codebase.
+ /// It manages the various resources and compute passes required by the ASR process.
+ /// Note that this class does not know anything about Unity render pipelines; all it knows is CommandBuffers and RenderTargetIdentifiers.
+ /// This should make it suitable for integration with any of the available Unity render pipelines.
+ ///
+ public class AsrContext
+ {
+ private const int MaxQueuedFrames = 16;
+
+ private Asr.ContextDescription _contextDescription;
+ private CommandBuffer _commandBuffer;
+
+ private AsrPass _computeLuminancePyramidPass;
+ private AsrPass _reconstructPreviousDepthPass;
+ private AsrPass _depthClipPass;
+ private AsrPass _lockPass;
+ private AsrPass _accumulatePass;
+ private AsrPass _sharpenPass;
+ private AsrPass _generateReactivePass;
+ private AsrPass _tcrAutogeneratePass;
+
+ private readonly AsrResources _resources = new AsrResources();
+
+ private ComputeBuffer _upscalerConstantsBuffer;
+ private readonly Asr.UpscalerConstants[] _upscalerConstantsArray = { new Asr.UpscalerConstants() };
+ private ref Asr.UpscalerConstants UpscalerConsts => ref _upscalerConstantsArray[0];
+
+ private ComputeBuffer _spdConstantsBuffer;
+ private readonly Asr.SpdConstants[] _spdConstantsArray = { new Asr.SpdConstants() };
+ private ref Asr.SpdConstants SpdConsts => ref _spdConstantsArray[0];
+
+ private ComputeBuffer _rcasConstantsBuffer;
+ private readonly Asr.RcasConstants[] _rcasConstantsArray = new Asr.RcasConstants[1];
+ private ref Asr.RcasConstants RcasConsts => ref _rcasConstantsArray[0];
+
+ private ComputeBuffer _generateReactiveConstantsBuffer;
+ private readonly Asr.GenerateReactiveConstants[] _generateReactiveConstantsArray = { new Asr.GenerateReactiveConstants() };
+ private ref Asr.GenerateReactiveConstants GenReactiveConsts => ref _generateReactiveConstantsArray[0];
+
+ private bool _firstExecution;
+ private Vector2 _previousJitterOffset;
+ private int _resourceFrameIndex;
+
+ public void Create(Asr.ContextDescription contextDescription)
+ {
+ _contextDescription = contextDescription;
+ _commandBuffer = new CommandBuffer { name = "Arm ASR" };
+
+ _upscalerConstantsBuffer = CreateConstantBuffer();
+ _spdConstantsBuffer = CreateConstantBuffer();
+ _rcasConstantsBuffer = CreateConstantBuffer();
+ _generateReactiveConstantsBuffer = CreateConstantBuffer();
+
+ // Set defaults
+ _firstExecution = true;
+ _resourceFrameIndex = 0;
+
+ UpscalerConsts.displaySize = _contextDescription.DisplaySize;
+
+ _resources.Create(_contextDescription);
+ CreatePasses();
+ }
+
+ private void CreatePasses()
+ {
+ _computeLuminancePyramidPass = new AsrComputeLuminancePyramidPass(_contextDescription, _resources, _upscalerConstantsBuffer, _spdConstantsBuffer);
+ _reconstructPreviousDepthPass = new AsrReconstructPreviousDepthPass(_contextDescription, _resources, _upscalerConstantsBuffer);
+ _depthClipPass = new AsrDepthClipPass(_contextDescription, _resources, _upscalerConstantsBuffer);
+ _lockPass = new AsrLockPass(_contextDescription, _resources, _upscalerConstantsBuffer);
+ _accumulatePass = new AsrAccumulatePass(_contextDescription, _resources, _upscalerConstantsBuffer);
+ _sharpenPass = new AsrSharpenPass(_contextDescription, _resources, _upscalerConstantsBuffer, _rcasConstantsBuffer);
+ _generateReactivePass = new AsrGenerateReactivePass(_contextDescription, _resources, _generateReactiveConstantsBuffer);
+ }
+
+ public void Destroy()
+ {
+ DestroyPass(ref _tcrAutogeneratePass);
+ DestroyPass(ref _generateReactivePass);
+ DestroyPass(ref _sharpenPass);
+ DestroyPass(ref _accumulatePass);
+ DestroyPass(ref _lockPass);
+ DestroyPass(ref _depthClipPass);
+ DestroyPass(ref _reconstructPreviousDepthPass);
+ DestroyPass(ref _computeLuminancePyramidPass);
+
+ _resources.Destroy();
+
+ DestroyConstantBuffer(ref _generateReactiveConstantsBuffer);
+ DestroyConstantBuffer(ref _rcasConstantsBuffer);
+ DestroyConstantBuffer(ref _spdConstantsBuffer);
+ DestroyConstantBuffer(ref _upscalerConstantsBuffer);
+
+ if (_commandBuffer != null)
+ {
+ _commandBuffer.Dispose();
+ _commandBuffer = null;
+ }
+ }
+
+ public void Dispatch(Asr.DispatchDescription dispatchParams)
+ {
+ _commandBuffer.Clear();
+ Dispatch(dispatchParams, _commandBuffer);
+ Graphics.ExecuteCommandBuffer(_commandBuffer);
+ }
+
+ public void Dispatch(Asr.DispatchDescription dispatchParams, CommandBuffer commandBuffer)
+ {
+ if ((_contextDescription.Flags & Asr.InitializationFlags.EnableDebugChecking) != 0)
+ {
+ DebugCheckDispatch(dispatchParams);
+ }
+
+ if (dispatchParams.UseTextureArrays)
+ commandBuffer.EnableShaderKeyword("UNITY_FFXM_TEXTURE2D_X_ARRAY");
+
+ if (_firstExecution)
+ {
+ commandBuffer.SetRenderTarget(_resources.LockStatus[0]);
+ commandBuffer.ClearRenderTarget(false, true, Color.clear);
+ commandBuffer.SetRenderTarget(_resources.LockStatus[1]);
+ commandBuffer.ClearRenderTarget(false, true, Color.clear);
+ }
+
+ int frameIndex = _resourceFrameIndex % 2;
+ bool resetAccumulation = dispatchParams.Reset || _firstExecution;
+ _firstExecution = false;
+
+ // If auto exposure is enabled use the auto exposure SRV, otherwise what the app sends
+ if ((_contextDescription.Flags & Asr.InitializationFlags.EnableAutoExposure) != 0)
+ dispatchParams.Exposure = new ResourceView(_resources.AutoExposure);
+ else if (!dispatchParams.Exposure.IsValid)
+ dispatchParams.Exposure = new ResourceView(_resources.DefaultExposure);
+
+ if (!dispatchParams.Reactive.IsValid) dispatchParams.Reactive = new ResourceView(_resources.DefaultReactive);
+ if (!dispatchParams.TransparencyAndComposition.IsValid) dispatchParams.TransparencyAndComposition = new ResourceView(_resources.DefaultReactive);
+ AsrResources.CreateAliasableResources(commandBuffer, _contextDescription, dispatchParams);
+
+ SetupConstants(dispatchParams, resetAccumulation);
+
+ // Reactive mask bias
+ const int threadGroupWorkRegionDim = 8;
+ int dispatchSrcX = (UpscalerConsts.renderSize.x + (threadGroupWorkRegionDim - 1)) / threadGroupWorkRegionDim;
+ int dispatchSrcY = (UpscalerConsts.renderSize.y + (threadGroupWorkRegionDim - 1)) / threadGroupWorkRegionDim;
+ int dispatchDstX = (_contextDescription.DisplaySize.x + (threadGroupWorkRegionDim - 1)) / threadGroupWorkRegionDim;
+ int dispatchDstY = (_contextDescription.DisplaySize.y + (threadGroupWorkRegionDim - 1)) / threadGroupWorkRegionDim;
+
+ // Clear reconstructed depth for max depth store
+ if (resetAccumulation)
+ {
+ commandBuffer.SetRenderTarget(_resources.LockStatus[frameIndex ^ 1]);
+ commandBuffer.ClearRenderTarget(false, true, Color.clear);
+
+ commandBuffer.SetRenderTarget(_resources.InternalUpscaled[frameIndex ^ 1]);
+ commandBuffer.ClearRenderTarget(false, true, Color.clear);
+
+ commandBuffer.SetRenderTarget(_resources.SceneLuminance);
+ commandBuffer.ClearRenderTarget(false, true, Color.clear);
+
+ // Auto exposure always used to track luma changes in locking logic
+ commandBuffer.SetRenderTarget(_resources.AutoExposure);
+ commandBuffer.ClearRenderTarget(false, true, new Color(0f, 1e8f, 0f, 0f));
+
+ // Reset atomic counter to 0
+ commandBuffer.SetRenderTarget(_resources.SpdAtomicCounter);
+ commandBuffer.ClearRenderTarget(false, true, Color.clear);
+ }
+
+ // FSR3: need to clear here since we need the content of this surface for frame interpolation, so clearing in the lock pass is not an option
+ bool depthInverted = (_contextDescription.Flags & Asr.InitializationFlags.EnableDepthInverted) == Asr.InitializationFlags.EnableDepthInverted;
+ commandBuffer.SetRenderTarget(AsrShaderIDs.UavReconstructedPrevNearestDepth);
+ commandBuffer.ClearRenderTarget(false, true, depthInverted ? Color.clear : Color.white);
+
+ // Auto exposure
+ SetupSpdConstants(dispatchParams, out var dispatchThreadGroupCount);
+
+ // Initialize constant buffers data
+ commandBuffer.SetBufferData(_upscalerConstantsBuffer, _upscalerConstantsArray);
+ commandBuffer.SetBufferData(_spdConstantsBuffer, _spdConstantsArray);
+
+ // Compute luminance pyramid
+ _computeLuminancePyramidPass.ScheduleDispatch(commandBuffer, dispatchParams, frameIndex, dispatchThreadGroupCount.x, dispatchThreadGroupCount.y);
+
+ // Reconstruct previous depth
+ _reconstructPreviousDepthPass.ScheduleDispatch(commandBuffer, dispatchParams, frameIndex, dispatchSrcX, dispatchSrcY);
+
+ // Depth clip
+ _depthClipPass.ScheduleDispatch(commandBuffer, dispatchParams, frameIndex, dispatchSrcX, dispatchSrcY);
+
+ // Create locks
+ _lockPass.ScheduleDispatch(commandBuffer, dispatchParams, frameIndex, dispatchSrcX, dispatchSrcY);
+
+ // Accumulate
+ _accumulatePass.ScheduleDispatch(commandBuffer, dispatchParams, frameIndex, dispatchDstX, dispatchDstY);
+
+ if (dispatchParams.EnableSharpening)
+ {
+ // Compute the constants
+ SetupRcasConstants(dispatchParams);
+ commandBuffer.SetBufferData(_rcasConstantsBuffer, _rcasConstantsArray);
+
+ // Dispatch RCAS
+ const int threadGroupWorkRegionDimRcas = 16;
+ int threadGroupsX = (Screen.width + threadGroupWorkRegionDimRcas - 1) / threadGroupWorkRegionDimRcas;
+ int threadGroupsY = (Screen.height + threadGroupWorkRegionDimRcas - 1) / threadGroupWorkRegionDimRcas;
+ _sharpenPass.ScheduleDispatch(commandBuffer, dispatchParams, frameIndex, threadGroupsX, threadGroupsY);
+ }
+
+ _resourceFrameIndex = (_resourceFrameIndex + 1) % MaxQueuedFrames;
+
+ AsrResources.DestroyAliasableResources(commandBuffer);
+
+ commandBuffer.DisableShaderKeyword("UNITY_FFXM_TEXTURE2D_X_ARRAY");
+ }
+
+ public void GenerateReactiveMask(Asr.GenerateReactiveDescription dispatchParams)
+ {
+ _commandBuffer.Clear();
+ GenerateReactiveMask(dispatchParams, _commandBuffer);
+ Graphics.ExecuteCommandBuffer(_commandBuffer);
+ }
+
+ public void GenerateReactiveMask(Asr.GenerateReactiveDescription dispatchParams, CommandBuffer commandBuffer)
+ {
+ const int threadGroupWorkRegionDim = 8;
+ int dispatchSrcX = (dispatchParams.RenderSize.x + (threadGroupWorkRegionDim - 1)) / threadGroupWorkRegionDim;
+ int dispatchSrcY = (dispatchParams.RenderSize.y + (threadGroupWorkRegionDim - 1)) / threadGroupWorkRegionDim;
+
+ GenReactiveConsts.scale = dispatchParams.Scale;
+ GenReactiveConsts.threshold = dispatchParams.CutoffThreshold;
+ GenReactiveConsts.binaryValue = dispatchParams.BinaryValue;
+ GenReactiveConsts.flags = (uint)dispatchParams.Flags;
+ commandBuffer.SetBufferData(_generateReactiveConstantsBuffer, _generateReactiveConstantsArray);
+
+ ((AsrGenerateReactivePass)_generateReactivePass).ScheduleDispatch(commandBuffer, dispatchParams, dispatchSrcX, dispatchSrcY);
+ }
+
+ private void SetupConstants(Asr.DispatchDescription dispatchParams, bool resetAccumulation)
+ {
+ ref Asr.UpscalerConstants constants = ref UpscalerConsts;
+
+ constants.jitterOffset = dispatchParams.JitterOffset;
+ constants.renderSize = dispatchParams.RenderSize;
+ constants.maxRenderSize = _contextDescription.MaxRenderSize;
+ constants.inputColorResourceDimensions = dispatchParams.InputResourceSize;
+
+ // Compute the horizontal FOV for the shader from the vertical one
+ float aspectRatio = (float)dispatchParams.RenderSize.x / dispatchParams.RenderSize.y;
+ float cameraAngleHorizontal = Mathf.Atan(Mathf.Tan(dispatchParams.CameraFovAngleVertical / 2.0f) * aspectRatio) * 2.0f;
+ constants.tanHalfFOV = Mathf.Tan(cameraAngleHorizontal * 0.5f);
+ constants.viewSpaceToMetersFactor = (dispatchParams.ViewSpaceToMetersFactor > 0.0f) ? dispatchParams.ViewSpaceToMetersFactor : 1.0f;
+
+ // Compute params to enable device depth to view space depth computation in shader
+ constants.deviceToViewDepth = SetupDeviceDepthToViewSpaceDepthParams(dispatchParams);
+
+ // To be updated if resource is larger than the actual image size
+ constants.downscaleFactor = new Vector2((float)constants.renderSize.x / _contextDescription.DisplaySize.x, (float)constants.renderSize.y / _contextDescription.DisplaySize.y);
+ constants.previousFramePreExposure = constants.preExposure;
+ constants.preExposure = (dispatchParams.PreExposure != 0) ? dispatchParams.PreExposure : 1.0f;
+
+ // Motion vector data
+ Vector2Int motionVectorsTargetSize = (_contextDescription.Flags & Asr.InitializationFlags.EnableDisplayResolutionMotionVectors) != 0 ? constants.displaySize : constants.renderSize;
+ constants.motionVectorScale = dispatchParams.MotionVectorScale / motionVectorsTargetSize;
+
+ // Compute jitter cancellation
+ if ((_contextDescription.Flags & Asr.InitializationFlags.EnableMotionVectorsJitterCancellation) != 0)
+ {
+ constants.motionVectorJitterCancellation = (_previousJitterOffset - constants.jitterOffset) / motionVectorsTargetSize;
+ _previousJitterOffset = constants.jitterOffset;
+ }
+
+ int jitterPhaseCount = Asr.GetJitterPhaseCount(dispatchParams.RenderSize.x, _contextDescription.DisplaySize.x);
+ if (resetAccumulation || constants.jitterPhaseCount == 0)
+ {
+ constants.jitterPhaseCount = jitterPhaseCount;
+ }
+ else
+ {
+ int jitterPhaseCountDelta = (int)(jitterPhaseCount - constants.jitterPhaseCount);
+ if (jitterPhaseCountDelta > 0)
+ constants.jitterPhaseCount++;
+ else if (jitterPhaseCountDelta < 0)
+ constants.jitterPhaseCount--;
+ }
+
+ // Convert delta time to seconds and clamp to [0, 1]
+ constants.deltaTime = Mathf.Clamp01(dispatchParams.FrameTimeDelta);
+
+ if (resetAccumulation)
+ constants.frameIndex = 0;
+ else
+ constants.frameIndex++;
+
+ // Shading change usage of the SPD mip levels
+ constants.lumaMipLevelToUse = AsrPass.ShadingChangeMipLevel;
+
+ float mipDiv = 2 << constants.lumaMipLevelToUse;
+ constants.lumaMipDimensions.x = (int)(constants.maxRenderSize.x / mipDiv);
+ constants.lumaMipDimensions.y = (int)(constants.maxRenderSize.y / mipDiv);
+ }
+
+ private Vector4 SetupDeviceDepthToViewSpaceDepthParams(Asr.DispatchDescription dispatchParams)
+ {
+ bool inverted = (_contextDescription.Flags & Asr.InitializationFlags.EnableDepthInverted) != 0;
+ bool infinite = (_contextDescription.Flags & Asr.InitializationFlags.EnableDepthInfinite) != 0;
+
+ // make sure it has no impact if near and far plane values are swapped in dispatch params
+ // the flags "inverted" and "infinite" will decide what transform to use
+ float min = Mathf.Min(dispatchParams.CameraNear, dispatchParams.CameraFar);
+ float max = Mathf.Max(dispatchParams.CameraNear, dispatchParams.CameraFar);
+
+ if (inverted)
+ {
+ (min, max) = (max, min);
+ }
+
+ float q = max / (min - max);
+ float d = -1.0f;
+
+ Vector4 matrixElemC = new Vector4(q, -1.0f - Mathf.Epsilon, q, 0.0f + Mathf.Epsilon);
+ Vector4 matrixElemE = new Vector4(q * min, -min - Mathf.Epsilon, q * min, max);
+
+ // Revert x and y coords
+ float aspect = (float)dispatchParams.RenderSize.x / dispatchParams.RenderSize.y;
+ float cotHalfFovY = Mathf.Cos(0.5f * dispatchParams.CameraFovAngleVertical) / Mathf.Sin(0.5f * dispatchParams.CameraFovAngleVertical);
+
+ int matrixIndex = (inverted ? 2 : 0) + (infinite ? 1 : 0);
+ return new Vector4(
+ d * matrixElemC[matrixIndex],
+ matrixElemE[matrixIndex],
+ aspect / cotHalfFovY,
+ 1.0f / cotHalfFovY);
+ }
+
+ private void SetupRcasConstants(Asr.DispatchDescription dispatchParams)
+ {
+ int sharpnessIndex = Mathf.RoundToInt(Mathf.Clamp01(dispatchParams.Sharpness) * (RcasConfigs.Length - 1));
+ RcasConsts = RcasConfigs[sharpnessIndex];
+ }
+
+ private void SetupSpdConstants(Asr.DispatchDescription dispatchParams, out Vector2Int dispatchThreadGroupCount)
+ {
+ RectInt rectInfo = new RectInt(0, 0, dispatchParams.RenderSize.x, dispatchParams.RenderSize.y);
+ SpdSetup(rectInfo, out dispatchThreadGroupCount, out var workGroupOffset, out var numWorkGroupsAndMips);
+
+ // Downsample
+ ref Asr.SpdConstants spdConstants = ref SpdConsts;
+ spdConstants.numWorkGroups = (uint)numWorkGroupsAndMips.x;
+ spdConstants.mips = (uint)numWorkGroupsAndMips.y;
+ spdConstants.workGroupOffsetX = (uint)workGroupOffset.x;
+ spdConstants.workGroupOffsetY = (uint)workGroupOffset.y;
+ spdConstants.renderSizeX = (uint)dispatchParams.RenderSize.x;
+ spdConstants.renderSizeY = (uint)dispatchParams.RenderSize.y;
+ }
+
+ private static void SpdSetup(RectInt rectInfo, out Vector2Int dispatchThreadGroupCount, out Vector2Int workGroupOffset, out Vector2Int numWorkGroupsAndMips, int mips = -1)
+ {
+ workGroupOffset = new Vector2Int(rectInfo.x / 64, rectInfo.y / 64);
+
+ int endIndexX = (rectInfo.x + rectInfo.width - 1) / 64;
+ int endIndexY = (rectInfo.y + rectInfo.height - 1) / 64;
+
+ dispatchThreadGroupCount = new Vector2Int(endIndexX + 1 - workGroupOffset.x, endIndexY + 1 - workGroupOffset.y);
+
+ numWorkGroupsAndMips = new Vector2Int(dispatchThreadGroupCount.x * dispatchThreadGroupCount.y, mips);
+ if (mips < 0)
+ {
+ float resolution = Math.Max(rectInfo.width, rectInfo.height);
+ numWorkGroupsAndMips.y = Math.Min(Mathf.FloorToInt(Mathf.Log(resolution, 2.0f)), 12);
+ }
+ }
+
+ private void DebugCheckDispatch(Asr.DispatchDescription dispatchParams)
+ {
+ if (!dispatchParams.Color.IsValid)
+ {
+ Debug.LogError("Color resource is null");
+ }
+
+ if (!dispatchParams.Depth.IsValid)
+ {
+ Debug.LogError("Depth resource is null");
+ }
+
+ if (!dispatchParams.MotionVectors.IsValid)
+ {
+ Debug.LogError("MotionVectors resource is null");
+ }
+
+ if (!dispatchParams.Output.IsValid)
+ {
+ Debug.LogError("Output resource is null");
+ }
+
+ if (dispatchParams.Exposure.IsValid && (_contextDescription.Flags & Asr.InitializationFlags.EnableAutoExposure) != 0)
+ {
+ Debug.LogWarning("Exposure resource provided, however auto exposure flag is present");
+ }
+
+ if (Mathf.Abs(dispatchParams.JitterOffset.x) > 1.0f || Mathf.Abs(dispatchParams.JitterOffset.y) > 1.0f)
+ {
+ Debug.LogWarning("JitterOffset contains value outside of expected range [-1.0, 1.0]");
+ }
+
+ if (dispatchParams.MotionVectorScale.x > _contextDescription.MaxRenderSize.x || dispatchParams.MotionVectorScale.y > _contextDescription.MaxRenderSize.y)
+ {
+ Debug.LogWarning("MotionVectorScale contains scale value greater than MaxRenderSize");
+ }
+
+ if (dispatchParams.MotionVectorScale.x == 0.0f || dispatchParams.MotionVectorScale.y == 0.0f)
+ {
+ Debug.LogWarning("MotionVectorScale contains zero scale value");
+ }
+
+ if (dispatchParams.RenderSize.x > _contextDescription.MaxRenderSize.x || dispatchParams.RenderSize.y > _contextDescription.MaxRenderSize.y)
+ {
+ Debug.LogWarning("RenderSize is greater than context MaxRenderSize");
+ }
+
+ if (dispatchParams.RenderSize.x == 0 || dispatchParams.RenderSize.y == 0)
+ {
+ Debug.LogWarning("RenderSize contains zero dimension");
+ }
+
+ if (dispatchParams.FrameTimeDelta > 1.0f)
+ {
+ Debug.LogWarning("FrameTimeDelta is greater than 1.0f - this value should be seconds (~0.0166 for 60fps)");
+ }
+
+ if (dispatchParams.PreExposure == 0.0f)
+ {
+ Debug.LogError("PreExposure provided as 0.0f which is invalid");
+ }
+
+ bool infiniteDepth = (_contextDescription.Flags & Asr.InitializationFlags.EnableDepthInfinite) != 0;
+ bool inverseDepth = (_contextDescription.Flags & Asr.InitializationFlags.EnableDepthInverted) != 0;
+
+ if (inverseDepth)
+ {
+ if (dispatchParams.CameraNear < dispatchParams.CameraFar)
+ {
+ Debug.LogWarning("EnableDepthInverted flag is present yet CameraNear is less than CameraFar");
+ }
+
+ if (infiniteDepth)
+ {
+ if (dispatchParams.CameraNear < float.MaxValue)
+ {
+ Debug.LogWarning("EnableDepthInfinite and EnableDepthInverted present, yet CameraNear != float.MaxValue");
+ }
+ }
+
+ if (dispatchParams.CameraFar < 0.075f)
+ {
+ Debug.LogWarning("EnableDepthInverted present, CameraFar value is very low which may result in depth separation artefacting");
+ }
+ }
+ else
+ {
+ if (dispatchParams.CameraNear > dispatchParams.CameraFar)
+ {
+ Debug.LogWarning("CameraNear is greater than CameraFar in non-inverted-depth context");
+ }
+
+ if (infiniteDepth)
+ {
+ if (dispatchParams.CameraFar < float.MaxValue)
+ {
+ Debug.LogWarning("EnableDepthInfinite present, yet CameraFar != float.MaxValue");
+ }
+ }
+
+ if (dispatchParams.CameraNear < 0.075f)
+ {
+ Debug.LogWarning("CameraNear value is very low which may result in depth separation artefacting");
+ }
+ }
+
+ if (dispatchParams.CameraFovAngleVertical <= 0.0f)
+ {
+ Debug.LogError("CameraFovAngleVertical is 0.0f - this value should be > 0.0f");
+ }
+
+ if (dispatchParams.CameraFovAngleVertical > Mathf.PI)
+ {
+ Debug.LogError("CameraFovAngleVertical is greater than 180 degrees/PI");
+ }
+ }
+
+ ///
+ /// The ASR C++ codebase uses floats bitwise converted to ints to pass sharpness parameters to the RCAS shader.
+ /// This is not possible in C# without enabling unsafe code compilation, so to avoid that we instead use a table of precomputed values.
+ ///
+ private static readonly Asr.RcasConstants[] RcasConfigs = new []
+ {
+ new Asr.RcasConstants(1048576000u, 872428544u),
+ new Asr.RcasConstants(1049178080u, 877212745u),
+ new Asr.RcasConstants(1049823372u, 882390168u),
+ new Asr.RcasConstants(1050514979u, 887895276u),
+ new Asr.RcasConstants(1051256227u, 893859143u),
+ new Asr.RcasConstants(1052050675u, 900216232u),
+ new Asr.RcasConstants(1052902144u, 907032080u),
+ new Asr.RcasConstants(1053814727u, 914306687u),
+ new Asr.RcasConstants(1054792807u, 922105590u),
+ new Asr.RcasConstants(1055841087u, 930494326u),
+ new Asr.RcasConstants(1056964608u, 939538432u),
+ new Asr.RcasConstants(1057566688u, 944322633u),
+ new Asr.RcasConstants(1058211980u, 949500056u),
+ new Asr.RcasConstants(1058903587u, 955005164u),
+ new Asr.RcasConstants(1059644835u, 960969031u),
+ new Asr.RcasConstants(1060439283u, 967326120u),
+ new Asr.RcasConstants(1061290752u, 974141968u),
+ new Asr.RcasConstants(1062203335u, 981416575u),
+ new Asr.RcasConstants(1063181415u, 989215478u),
+ new Asr.RcasConstants(1064229695u, 997604214u),
+ new Asr.RcasConstants(1065353216u, 1006648320),
+ };
+
+ private static ComputeBuffer CreateConstantBuffer() where TConstants: struct
+ {
+ return new ComputeBuffer(1, Marshal.SizeOf(), ComputeBufferType.Constant);
+ }
+
+ private static void DestroyConstantBuffer(ref ComputeBuffer bufferRef)
+ {
+ if (bufferRef == null)
+ return;
+
+ bufferRef.Release();
+ bufferRef = null;
+ }
+
+ private static void DestroyPass(ref AsrPass pass)
+ {
+ if (pass == null)
+ return;
+
+ pass.Dispose();
+ pass = null;
+ }
+ }
+}
diff --git a/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/AsrContext.cs.meta b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/AsrContext.cs.meta
new file mode 100644
index 0000000..3a18521
--- /dev/null
+++ b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/AsrContext.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: c348b7c44539db74994c5846caec5871
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/AsrPass.cs b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/AsrPass.cs
new file mode 100644
index 0000000..5a76b16
--- /dev/null
+++ b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/AsrPass.cs
@@ -0,0 +1,339 @@
+// Copyright (c) 2024 Nico de Poel
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+using System;
+using UnityEngine;
+using UnityEngine.Profiling;
+using UnityEngine.Rendering;
+
+namespace ArmASR
+{
+ ///
+ /// Base class for all the compute passes that make up the ASR process.
+ /// This loosely matches the FfxPipelineState struct from the original ASR codebase, wrapped in an object-oriented blanket.
+ /// These classes are responsible for loading compute shaders, managing temporary resources, binding resources to shader kernels and dispatching said shaders.
+ ///
+ internal abstract class AsrPass: IDisposable
+ {
+ internal const int ShadingChangeMipLevel = 4; // This matches the FFXM_FSR2_SHADING_CHANGE_MIP_LEVEL define
+
+ protected readonly Asr.ContextDescription ContextDescription;
+ protected readonly AsrResources Resources;
+ protected readonly ComputeBuffer Constants;
+
+ protected ComputeShader ComputeShader;
+ protected int KernelIndex;
+
+ protected CustomSampler Sampler;
+
+ protected AsrPass(Asr.ContextDescription contextDescription, AsrResources resources, ComputeBuffer constants)
+ {
+ ContextDescription = contextDescription;
+ Resources = resources;
+ Constants = constants;
+ }
+
+ public virtual void Dispose()
+ {
+ }
+
+ public void ScheduleDispatch(CommandBuffer commandBuffer, Asr.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY)
+ {
+ commandBuffer.BeginSample(Sampler);
+ DoScheduleDispatch(commandBuffer, dispatchParams, frameIndex, dispatchX, dispatchY);
+ commandBuffer.EndSample(Sampler);
+ }
+
+ protected abstract void DoScheduleDispatch(CommandBuffer commandBuffer, Asr.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY);
+
+ protected void InitComputeShader(string passName, ComputeShader shader)
+ {
+ InitComputeShader(passName, shader, ContextDescription.Flags);
+ }
+
+ private void InitComputeShader(string passName, ComputeShader shader, Asr.InitializationFlags flags)
+ {
+ if (shader == null)
+ {
+ throw new MissingReferenceException($"Shader for ASR pass '{passName}' could not be loaded! Please ensure it is included in the project correctly.");
+ }
+
+ ComputeShader = shader;
+ KernelIndex = ComputeShader.FindKernel("main");
+ Sampler = CustomSampler.Create(passName);
+
+ bool useLut = false;
+#if UNITY_2022_1_OR_NEWER // This will also work in 2020.3.43+ and 2021.3.14+
+ if (SystemInfo.computeSubGroupSize == 64)
+ {
+ useLut = true;
+ }
+#endif
+
+ // This matches the permutation rules from the CreatePipeline* functions
+ if ((flags & Asr.InitializationFlags.EnableHighDynamicRange) != 0) ComputeShader.EnableKeyword("FFXM_FSR2_OPTION_HDR_COLOR_INPUT");
+ if ((flags & Asr.InitializationFlags.EnableDisplayResolutionMotionVectors) == 0) ComputeShader.EnableKeyword("FFXM_FSR2_OPTION_LOW_RESOLUTION_MOTION_VECTORS");
+ if ((flags & Asr.InitializationFlags.EnableMotionVectorsJitterCancellation) != 0) ComputeShader.EnableKeyword("FFXM_FSR2_OPTION_JITTERED_MOTION_VECTORS");
+ if ((flags & Asr.InitializationFlags.EnableDepthInverted) != 0) ComputeShader.EnableKeyword("FFXM_FSR2_OPTION_INVERTED_DEPTH");
+ if (useLut) ComputeShader.EnableKeyword("FFXM_FSR2_OPTION_REPROJECT_USE_LANCZOS_TYPE");
+ if ((flags & Asr.InitializationFlags.EnableFP16Usage) != 0) ComputeShader.EnableKeyword("FFXM_HALF");
+ }
+ }
+
+ internal class AsrComputeLuminancePyramidPass : AsrPass
+ {
+ private readonly ComputeBuffer _spdConstants;
+
+ public AsrComputeLuminancePyramidPass(Asr.ContextDescription contextDescription, AsrResources resources, ComputeBuffer constants, ComputeBuffer spdConstants)
+ : base(contextDescription, resources, constants)
+ {
+ _spdConstants = spdConstants;
+
+ InitComputeShader("Compute Luminance Pyramid", contextDescription.Shaders.computeLuminancePyramidPass);
+ }
+
+ protected override void DoScheduleDispatch(CommandBuffer commandBuffer, Asr.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY)
+ {
+ ref var color = ref dispatchParams.Color;
+ commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvInputColor, color.RenderTarget, color.MipLevel, color.SubElement);
+
+ commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.UavSpdAtomicCount, Resources.SpdAtomicCounter);
+ commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.UavExposureMipLumaChange, Resources.SceneLuminance, ShadingChangeMipLevel);
+ commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.UavExposureMip5, Resources.SceneLuminance, 5);
+ commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.UavAutoExposure, Resources.AutoExposure);
+
+ commandBuffer.SetComputeConstantBufferParam(ComputeShader, AsrShaderIDs.CbFsr2, Constants, 0, Constants.stride);
+ commandBuffer.SetComputeConstantBufferParam(ComputeShader, AsrShaderIDs.CbSpd, _spdConstants, 0, _spdConstants.stride);
+
+ commandBuffer.DispatchCompute(ComputeShader, KernelIndex, dispatchX, dispatchY, 1);
+ }
+ }
+
+ internal class AsrReconstructPreviousDepthPass : AsrPass
+ {
+ public AsrReconstructPreviousDepthPass(Asr.ContextDescription contextDescription, AsrResources resources, ComputeBuffer constants)
+ : base(contextDescription, resources, constants)
+ {
+ InitComputeShader("Reconstruct & Dilate", contextDescription.Shaders.reconstructPreviousDepthPass);
+ }
+
+ protected override void DoScheduleDispatch(CommandBuffer commandBuffer, Asr.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY)
+ {
+ ref var color = ref dispatchParams.Color;
+ ref var depth = ref dispatchParams.Depth;
+ ref var motionVectors = ref dispatchParams.MotionVectors;
+ ref var exposure = ref dispatchParams.Exposure;
+
+ commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvInputColor, color.RenderTarget, color.MipLevel, color.SubElement);
+ commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvInputDepth, depth.RenderTarget, depth.MipLevel, depth.SubElement);
+ commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvInputMotionVectors, motionVectors.RenderTarget, motionVectors.MipLevel, motionVectors.SubElement);
+ commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvInputExposure, exposure.RenderTarget, exposure.MipLevel, exposure.SubElement);
+
+ commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.UavDilatedMotionVectors, Resources.DilatedMotionVectors[frameIndex]);
+
+ commandBuffer.SetComputeConstantBufferParam(ComputeShader, AsrShaderIDs.CbFsr2, Constants, 0, Constants.stride);
+
+ commandBuffer.DispatchCompute(ComputeShader, KernelIndex, dispatchX, dispatchY, 1);
+ }
+ }
+
+ internal class AsrDepthClipPass : AsrPass
+ {
+ public AsrDepthClipPass(Asr.ContextDescription contextDescription, AsrResources resources, ComputeBuffer constants)
+ : base(contextDescription, resources, constants)
+ {
+ InitComputeShader("Depth Clip", contextDescription.Shaders.depthClipPass);
+ }
+
+ protected override void DoScheduleDispatch(CommandBuffer commandBuffer, Asr.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY)
+ {
+ ref var color = ref dispatchParams.Color;
+ ref var depth = ref dispatchParams.Depth;
+ ref var motionVectors = ref dispatchParams.MotionVectors;
+ ref var exposure = ref dispatchParams.Exposure;
+ ref var reactive = ref dispatchParams.Reactive;
+ ref var tac = ref dispatchParams.TransparencyAndComposition;
+
+ commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvInputColor, color.RenderTarget, color.MipLevel, color.SubElement);
+ commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvInputDepth, depth.RenderTarget, depth.MipLevel, depth.SubElement);
+ commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvInputMotionVectors, motionVectors.RenderTarget, motionVectors.MipLevel, motionVectors.SubElement);
+ commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvInputExposure, exposure.RenderTarget, exposure.MipLevel, exposure.SubElement);
+ commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvReactiveMask, reactive.RenderTarget, reactive.MipLevel, reactive.SubElement);
+ commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvTransparencyAndCompositionMask, tac.RenderTarget, tac.MipLevel, tac.SubElement);
+
+ commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvReconstructedPrevNearestDepth, AsrShaderIDs.UavReconstructedPrevNearestDepth);
+ commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvDilatedMotionVectors, Resources.DilatedMotionVectors[frameIndex]);
+ commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvDilatedDepth, AsrShaderIDs.UavDilatedDepth);
+ commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvPrevDilatedMotionVectors, Resources.DilatedMotionVectors[frameIndex ^ 1]);
+
+ commandBuffer.SetComputeConstantBufferParam(ComputeShader, AsrShaderIDs.CbFsr2, Constants, 0, Constants.stride);
+
+ commandBuffer.DispatchCompute(ComputeShader, KernelIndex, dispatchX, dispatchY, 1);
+ }
+ }
+
+ internal class AsrLockPass : AsrPass
+ {
+ public AsrLockPass(Asr.ContextDescription contextDescription, AsrResources resources, ComputeBuffer constants)
+ : base(contextDescription, resources, constants)
+ {
+ InitComputeShader("Create Locks", contextDescription.Shaders.lockPass);
+ }
+
+ protected override void DoScheduleDispatch(CommandBuffer commandBuffer, Asr.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY)
+ {
+ commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvLockInputLuma, AsrShaderIDs.UavLockInputLuma);
+ commandBuffer.SetComputeConstantBufferParam(ComputeShader, AsrShaderIDs.CbFsr2, Constants, 0, Constants.stride);
+
+ commandBuffer.DispatchCompute(ComputeShader, KernelIndex, dispatchX, dispatchY, 1);
+ }
+ }
+
+ internal class AsrAccumulatePass : AsrPass
+ {
+ private const string SharpeningKeyword = "FFXM_FSR2_OPTION_APPLY_SHARPENING";
+
+#if UNITY_2021_2_OR_NEWER
+ private readonly LocalKeyword _sharpeningKeyword;
+#endif
+
+ public AsrAccumulatePass(Asr.ContextDescription contextDescription, AsrResources resources, ComputeBuffer constants)
+ : base(contextDescription, resources, constants)
+ {
+ InitComputeShader("Reproject & Accumulate", contextDescription.Shaders.accumulatePass);
+#if UNITY_2021_2_OR_NEWER
+ _sharpeningKeyword = new LocalKeyword(ComputeShader, SharpeningKeyword);
+#endif
+ }
+
+ protected override void DoScheduleDispatch(CommandBuffer commandBuffer, Asr.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY)
+ {
+#if UNITY_2021_2_OR_NEWER
+ if (dispatchParams.EnableSharpening)
+ commandBuffer.EnableKeyword(ComputeShader, _sharpeningKeyword);
+ else
+ commandBuffer.DisableKeyword(ComputeShader, _sharpeningKeyword);
+#else
+ if (dispatchParams.EnableSharpening)
+ commandBuffer.EnableShaderKeyword(SharpeningKeyword);
+ else
+ commandBuffer.DisableShaderKeyword(SharpeningKeyword);
+#endif
+
+ if ((ContextDescription.Flags & Asr.InitializationFlags.EnableDisplayResolutionMotionVectors) == 0)
+ {
+ commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvDilatedMotionVectors, Resources.DilatedMotionVectors[frameIndex]);
+ }
+ else
+ {
+ ref var motionVectors = ref dispatchParams.MotionVectors;
+ commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvInputMotionVectors, motionVectors.RenderTarget, motionVectors.MipLevel, motionVectors.SubElement);
+ }
+
+ ref var exposure = ref dispatchParams.Exposure;
+ commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvInputExposure, exposure.RenderTarget, exposure.MipLevel, exposure.SubElement);
+
+ commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvDilatedReactiveMasks, AsrShaderIDs.UavDilatedReactiveMasks);
+ commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvInternalUpscaled, Resources.InternalUpscaled[frameIndex ^ 1]);
+ commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvLockStatus, Resources.LockStatus[frameIndex ^ 1]);
+ commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvPreparedInputColor, AsrShaderIDs.UavPreparedInputColor);
+ commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvLanczosLut, Resources.LanczosLut);
+ commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvUpscaleMaximumBiasLut, Resources.MaximumBiasLut);
+ commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvSceneLuminanceMips, Resources.SceneLuminance);
+ commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvAutoExposure, Resources.AutoExposure);
+ commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvLumaHistory, Resources.LumaHistory[frameIndex ^ 1]);
+
+ commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.UavInternalUpscaled, Resources.InternalUpscaled[frameIndex]);
+ commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.UavLockStatus, Resources.LockStatus[frameIndex]);
+ commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.UavLumaHistory, Resources.LumaHistory[frameIndex]);
+
+ ref var output = ref dispatchParams.Output;
+ commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.UavUpscaledOutput, output.RenderTarget, output.MipLevel, output.SubElement);
+
+ commandBuffer.SetComputeConstantBufferParam(ComputeShader, AsrShaderIDs.CbFsr2, Constants, 0, Constants.stride);
+
+ commandBuffer.DispatchCompute(ComputeShader, KernelIndex, dispatchX, dispatchY, 1);
+ }
+ }
+
+ internal class AsrSharpenPass : AsrPass
+ {
+ private readonly ComputeBuffer _rcasConstants;
+
+ public AsrSharpenPass(Asr.ContextDescription contextDescription, AsrResources resources, ComputeBuffer constants, ComputeBuffer rcasConstants)
+ : base(contextDescription, resources, constants)
+ {
+ _rcasConstants = rcasConstants;
+
+ InitComputeShader("RCAS Sharpening", contextDescription.Shaders.sharpenPass);
+ }
+
+ protected override void DoScheduleDispatch(CommandBuffer commandBuffer, Asr.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY)
+ {
+ ref var exposure = ref dispatchParams.Exposure;
+ commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvInputExposure, exposure.RenderTarget, exposure.MipLevel, exposure.SubElement);
+ commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvRcasInput, Resources.InternalUpscaled[frameIndex]);
+
+ ref var output = ref dispatchParams.Output;
+ commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.UavUpscaledOutput, output.RenderTarget, output.MipLevel, output.SubElement);
+
+ commandBuffer.SetComputeConstantBufferParam(ComputeShader, AsrShaderIDs.CbFsr2, Constants, 0, Constants.stride);
+ commandBuffer.SetComputeConstantBufferParam(ComputeShader, AsrShaderIDs.CbRcas, _rcasConstants, 0, _rcasConstants.stride);
+
+ commandBuffer.DispatchCompute(ComputeShader, KernelIndex, dispatchX, dispatchY, 1);
+ }
+ }
+
+ internal class AsrGenerateReactivePass : AsrPass
+ {
+ private readonly ComputeBuffer _generateReactiveConstants;
+
+ public AsrGenerateReactivePass(Asr.ContextDescription contextDescription, AsrResources resources, ComputeBuffer generateReactiveConstants)
+ : base(contextDescription, resources, null)
+ {
+ _generateReactiveConstants = generateReactiveConstants;
+
+ InitComputeShader("Auto-Generate Reactive Mask", contextDescription.Shaders.autoGenReactivePass);
+ }
+
+ protected override void DoScheduleDispatch(CommandBuffer commandBuffer, Asr.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY)
+ {
+ }
+
+ public void ScheduleDispatch(CommandBuffer commandBuffer, Asr.GenerateReactiveDescription dispatchParams, int dispatchX, int dispatchY)
+ {
+ commandBuffer.BeginSample(Sampler);
+
+ ref var opaqueOnly = ref dispatchParams.ColorOpaqueOnly;
+ ref var color = ref dispatchParams.ColorPreUpscale;
+ ref var reactive = ref dispatchParams.OutReactive;
+
+ commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvOpaqueOnly, opaqueOnly.RenderTarget, opaqueOnly.MipLevel, opaqueOnly.SubElement);
+ commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.SrvInputColor, color.RenderTarget, color.MipLevel, color.SubElement);
+ commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, AsrShaderIDs.UavAutoReactive, reactive.RenderTarget, reactive.MipLevel, reactive.SubElement);
+
+ commandBuffer.SetComputeConstantBufferParam(ComputeShader, AsrShaderIDs.CbGenReactive, _generateReactiveConstants, 0, _generateReactiveConstants.stride);
+
+ commandBuffer.DispatchCompute(ComputeShader, KernelIndex, dispatchX, dispatchY, 1);
+
+ commandBuffer.EndSample(Sampler);
+ }
+ }
+}
diff --git a/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/AsrPass.cs.meta b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/AsrPass.cs.meta
new file mode 100644
index 0000000..5b01d20
--- /dev/null
+++ b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/AsrPass.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 7fb53d9f929886c4ab35be8d9010b9c3
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/AsrResources.cs b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/AsrResources.cs
new file mode 100644
index 0000000..44dd65a
--- /dev/null
+++ b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/AsrResources.cs
@@ -0,0 +1,227 @@
+// Copyright (c) 2024 Nico de Poel
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+using System;
+using UnityEngine;
+using UnityEngine.Experimental.Rendering;
+using UnityEngine.Rendering;
+
+namespace ArmASR
+{
+ ///
+ /// Helper class for bundling and managing persistent resources required by the ASR process.
+ /// This includes lookup tables, default fallback resources and double-buffered resources that get swapped between frames.
+ ///
+ internal class AsrResources
+ {
+ public Texture2D DefaultExposure;
+ public Texture2D DefaultReactive;
+ public Texture2D LanczosLut;
+ public Texture2D MaximumBiasLut;
+ public RenderTexture SpdAtomicCounter;
+ public RenderTexture AutoExposure;
+ public RenderTexture SceneLuminance;
+ public readonly RenderTexture[] DilatedMotionVectors = new RenderTexture[2];
+ public readonly RenderTexture[] LockStatus = new RenderTexture[2];
+ public readonly RenderTexture[] InternalUpscaled = new RenderTexture[2];
+ public readonly RenderTexture[] LumaHistory = new RenderTexture[2];
+
+ public void Create(Asr.ContextDescription contextDescription)
+ {
+ // Generate the data for the LUT
+ const int lanczos2LutWidth = 128;
+ float[] lanczos2Weights = new float[lanczos2LutWidth];
+ for (int currentLanczosWidthIndex = 0; currentLanczosWidthIndex < lanczos2LutWidth; ++currentLanczosWidthIndex)
+ {
+ float x = 2.0f * currentLanczosWidthIndex / (lanczos2LutWidth - 1);
+ float y = Asr.Lanczos2(x);
+ lanczos2Weights[currentLanczosWidthIndex] = y;
+ }
+
+ float[] maximumBias = new float[MaximumBiasTextureWidth * MaximumBiasTextureHeight];
+ for (int i = 0; i < maximumBias.Length; ++i)
+ {
+ maximumBias[i] = MaximumBias[i] / 2.0f;
+ }
+
+ // Resource FSR2_LanczosLutData: FFX_RESOURCE_USAGE_READ_ONLY, FFX_SURFACE_FORMAT_R16_SNORM, FFX_RESOURCE_FLAGS_NONE
+ // R16_SNorm textures are not supported by Unity on most platforms, strangely enough. So instead we use R32_SFloat and upload pre-normalized float data.
+ LanczosLut = new Texture2D(lanczos2LutWidth, 1, GraphicsFormat.R32_SFloat, TextureCreationFlags.None) { name = "ASR_LanczosLutData" };
+ LanczosLut.SetPixelData(lanczos2Weights, 0);
+ LanczosLut.Apply();
+
+ // Resource FSR2_MaximumUpsampleBias: FFX_RESOURCE_USAGE_READ_ONLY, FFX_SURFACE_FORMAT_R16_SNORM, FFX_RESOURCE_FLAGS_NONE
+ MaximumBiasLut = new Texture2D(MaximumBiasTextureWidth, MaximumBiasTextureHeight, GraphicsFormat.R32_SFloat, TextureCreationFlags.None) { name = "ASR_MaximumUpsampleBias" };
+ MaximumBiasLut.SetPixelData(maximumBias, 0);
+ MaximumBiasLut.Apply();
+
+ // Resource FSR2_DefaultExposure: FFX_RESOURCE_USAGE_READ_ONLY, FFX_SURFACE_FORMAT_R32G32_FLOAT, FFX_RESOURCE_FLAGS_NONE
+ DefaultExposure = new Texture2D(1, 1, GraphicsFormat.R32G32_SFloat, TextureCreationFlags.None) { name = "ASR_DefaultExposure" };
+ DefaultExposure.SetPixel(0, 0, Color.clear);
+ DefaultExposure.Apply();
+
+ // Resource FSR2_DefaultReactivityMask: FFX_RESOURCE_USAGE_READ_ONLY, FFX_SURFACE_FORMAT_R8_UNORM, FFX_RESOURCE_FLAGS_NONE
+ DefaultReactive = new Texture2D(1, 1, GraphicsFormat.R8_UNorm, TextureCreationFlags.None) { name = "ASR_DefaultReactivityMask" };
+ DefaultReactive.SetPixel(0, 0, Color.clear);
+ DefaultReactive.Apply();
+
+ // Resource FSR2_SpdAtomicCounter: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R32_UINT, FFX_RESOURCE_FLAGS_ALIASABLE
+ // Despite what the original FSR2 codebase says, this resource really isn't aliasable. Resetting this counter to 0 every frame breaks auto-exposure on MacOS Metal.
+ SpdAtomicCounter = new RenderTexture(1, 1, 0, GraphicsFormat.R32_UInt) { name = "ASR_SpdAtomicCounter", enableRandomWrite = true };
+ SpdAtomicCounter.Create();
+
+ // Resource FSR2_AutoExposure: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R32G32_FLOAT, FFX_RESOURCE_FLAGS_NONE
+ AutoExposure = new RenderTexture(1, 1, 0, GraphicsFormat.R32G32_SFloat) { name = "ASR_AutoExposure", enableRandomWrite = true };
+ AutoExposure.Create();
+
+ // Resource FSR2_ExposureMips: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R16_FLOAT, FFX_RESOURCE_FLAGS_ALIASABLE
+ // This is a rather special case: it's an aliasable resource, but because we require a mipmap chain and bind specific mip levels per shader, we can't easily use temporary RTs for this.
+ int w = contextDescription.MaxRenderSize.x / 2, h = contextDescription.MaxRenderSize.y / 2;
+ int mipCount = 1 + Mathf.FloorToInt(Mathf.Log(Math.Max(w, h), 2.0f));
+ SceneLuminance = new RenderTexture(w, h, 0, GraphicsFormat.R16_SFloat, mipCount) { name = "ASR_ExposureMips", enableRandomWrite = true, useMipMap = true, autoGenerateMips = false };
+ SceneLuminance.Create();
+
+ // Resources FSR2_InternalDilatedVelocity1/2: FFX_RESOURCE_USAGE_RENDERTARGET | FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R16G16_FLOAT, FFX_RESOURCE_FLAGS_NONE
+ CreateDoubleBufferedResource(DilatedMotionVectors, "ASR_InternalDilatedVelocity", contextDescription.MaxRenderSize, GraphicsFormat.R16G16_SFloat);
+
+ // Resources FSR2_LockStatus1/2: FFX_RESOURCE_USAGE_RENDERTARGET | FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R16G16_FLOAT, FFX_RESOURCE_FLAGS_NONE
+ CreateDoubleBufferedResource(LockStatus, "ASR_LockStatus", contextDescription.DisplaySize, GraphicsFormat.R16G16_SFloat);
+
+ // Resources FSR2_InternalUpscaled1/2: FFX_RESOURCE_USAGE_RENDERTARGET | FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R16G16B16A16_FLOAT, FFX_RESOURCE_FLAGS_NONE
+ CreateDoubleBufferedResource(InternalUpscaled, "ASR_InternalUpscaled", contextDescription.DisplaySize, GraphicsFormat.R16G16B16A16_SFloat);
+
+ // Resources FSR2_LumaHistory1/2: FFX_RESOURCE_USAGE_RENDERTARGET | FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R8G8B8A8_UNORM, FFX_RESOURCE_FLAGS_NONE
+ CreateDoubleBufferedResource(LumaHistory, "ASR_LumaHistory", contextDescription.DisplaySize, GraphicsFormat.R8G8B8A8_UNorm);
+ }
+
+ // Set up shared aliasable resources, i.e. temporary render textures
+ // These do not need to persist between frames, but they do need to be available between passes
+ public static void CreateAliasableResources(CommandBuffer commandBuffer, Asr.ContextDescription contextDescription, Asr.DispatchDescription dispatchParams)
+ {
+ Vector2Int displaySize = contextDescription.DisplaySize;
+ Vector2Int maxRenderSize = contextDescription.MaxRenderSize;
+
+ // FSR2_ReconstructedPrevNearestDepth: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R32_UINT, FFX_RESOURCE_FLAGS_ALIASABLE
+ commandBuffer.GetTemporaryRT(AsrShaderIDs.UavReconstructedPrevNearestDepth, maxRenderSize.x, maxRenderSize.y, 0, default, GraphicsFormat.R32_UInt, 1, true);
+
+ // FSR2_DilatedDepth: FFX_RESOURCE_USAGE_RENDERTARGET | FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R32_FLOAT, FFX_RESOURCE_FLAGS_ALIASABLE
+ commandBuffer.GetTemporaryRT(AsrShaderIDs.UavDilatedDepth, maxRenderSize.x, maxRenderSize.y, 0, default, GraphicsFormat.R32_SFloat, 1, true);
+
+ // FSR2_LockInputLuma: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R16_FLOAT, FFX_RESOURCE_FLAGS_ALIASABLE
+ commandBuffer.GetTemporaryRT(AsrShaderIDs.UavLockInputLuma, maxRenderSize.x, maxRenderSize.y, 0, default, GraphicsFormat.R16_SFloat, 1, true);
+
+ // FSR2_DilatedReactiveMasks: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R8G8_UNORM, FFX_RESOURCE_FLAGS_ALIASABLE
+ commandBuffer.GetTemporaryRT(AsrShaderIDs.UavDilatedReactiveMasks, maxRenderSize.x, maxRenderSize.y, 0, default, GraphicsFormat.R8G8_UNorm, 1, true);
+
+ // FSR2_PreparedInputColor: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R16G16B16A16_FLOAT, FFX_RESOURCE_FLAGS_ALIASABLE
+ commandBuffer.GetTemporaryRT(AsrShaderIDs.UavPreparedInputColor, maxRenderSize.x, maxRenderSize.y, 0, default, GraphicsFormat.R16G16B16A16_SFloat, 1, true);
+
+ // FSR2_NewLocks: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R8_UNORM, FFX_RESOURCE_FLAGS_ALIASABLE
+ commandBuffer.GetTemporaryRT(AsrShaderIDs.UavNewLocks, displaySize.x, displaySize.y, 0, default, GraphicsFormat.R8_UNorm, 1, true);
+ }
+
+ public static void DestroyAliasableResources(CommandBuffer commandBuffer)
+ {
+ // Release all of the aliasable resources used this frame
+ commandBuffer.ReleaseTemporaryRT(AsrShaderIDs.UavReconstructedPrevNearestDepth);
+ commandBuffer.ReleaseTemporaryRT(AsrShaderIDs.UavDilatedDepth);
+ commandBuffer.ReleaseTemporaryRT(AsrShaderIDs.UavLockInputLuma);
+ commandBuffer.ReleaseTemporaryRT(AsrShaderIDs.UavDilatedReactiveMasks);
+ commandBuffer.ReleaseTemporaryRT(AsrShaderIDs.UavPreparedInputColor);
+ commandBuffer.ReleaseTemporaryRT(AsrShaderIDs.UavNewLocks);
+ }
+
+ private static void CreateDoubleBufferedResource(RenderTexture[] resource, string name, Vector2Int size, GraphicsFormat format)
+ {
+ for (int i = 0; i < 2; ++i)
+ {
+ resource[i] = new RenderTexture(size.x, size.y, 0, format) { name = name + (i + 1), enableRandomWrite = true };
+ resource[i].Create();
+ }
+ }
+
+ public void Destroy()
+ {
+ DestroyResource(LumaHistory);
+ DestroyResource(InternalUpscaled);
+ DestroyResource(LockStatus);
+ DestroyResource(DilatedMotionVectors);
+ DestroyResource(ref SceneLuminance);
+ DestroyResource(ref AutoExposure);
+ DestroyResource(ref DefaultReactive);
+ DestroyResource(ref DefaultExposure);
+ DestroyResource(ref MaximumBiasLut);
+ DestroyResource(ref LanczosLut);
+ }
+
+ private static void DestroyResource(ref Texture2D resource)
+ {
+ if (resource == null)
+ return;
+
+#if UNITY_EDITOR
+ if (Application.isPlaying && !UnityEditor.EditorApplication.isPaused)
+ UnityEngine.Object.Destroy(resource);
+ else
+ UnityEngine.Object.DestroyImmediate(resource);
+#else
+ UnityEngine.Object.Destroy(resource);
+#endif
+ resource = null;
+ }
+
+ private static void DestroyResource(ref RenderTexture resource)
+ {
+ if (resource == null)
+ return;
+
+ resource.Release();
+ resource = null;
+ }
+
+ private static void DestroyResource(RenderTexture[] resource)
+ {
+ for (int i = 0; i < resource.Length; ++i)
+ DestroyResource(ref resource[i]);
+ }
+
+ private const int MaximumBiasTextureWidth = 16;
+ private const int MaximumBiasTextureHeight = 16;
+ private static readonly float[] MaximumBias =
+ {
+ 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 1.876f, 1.809f, 1.772f, 1.753f, 1.748f,
+ 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 1.869f, 1.801f, 1.764f, 1.745f, 1.739f,
+ 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 1.976f, 1.841f, 1.774f, 1.737f, 1.716f, 1.71f,
+ 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 1.914f, 1.784f, 1.716f, 1.673f, 1.649f, 1.641f,
+ 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 1.793f, 1.676f, 1.604f, 1.562f, 1.54f, 1.533f,
+ 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 1.802f, 1.619f, 1.536f, 1.492f, 1.467f, 1.454f, 1.449f,
+ 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 1.812f, 1.575f, 1.496f, 1.456f, 1.432f, 1.416f, 1.408f, 1.405f,
+ 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 1.555f, 1.479f, 1.438f, 1.413f, 1.398f, 1.387f, 1.381f, 1.379f,
+ 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 1.812f, 1.555f, 1.474f, 1.43f, 1.404f, 1.387f, 1.376f, 1.368f, 1.363f, 1.362f,
+ 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 1.802f, 1.575f, 1.479f, 1.43f, 1.401f, 1.382f, 1.369f, 1.36f, 1.354f, 1.351f, 1.35f,
+ 2.0f, 2.0f, 1.976f, 1.914f, 1.793f, 1.619f, 1.496f, 1.438f, 1.404f, 1.382f, 1.367f, 1.357f, 1.349f, 1.344f, 1.341f, 1.34f,
+ 1.876f, 1.869f, 1.841f, 1.784f, 1.676f, 1.536f, 1.456f, 1.413f, 1.387f, 1.369f, 1.357f, 1.347f, 1.341f, 1.336f, 1.333f, 1.332f,
+ 1.809f, 1.801f, 1.774f, 1.716f, 1.604f, 1.492f, 1.432f, 1.398f, 1.376f, 1.36f, 1.349f, 1.341f, 1.335f, 1.33f, 1.328f, 1.327f,
+ 1.772f, 1.764f, 1.737f, 1.673f, 1.562f, 1.467f, 1.416f, 1.387f, 1.368f, 1.354f, 1.344f, 1.336f, 1.33f, 1.326f, 1.323f, 1.323f,
+ 1.753f, 1.745f, 1.716f, 1.649f, 1.54f, 1.454f, 1.408f, 1.381f, 1.363f, 1.351f, 1.341f, 1.333f, 1.328f, 1.323f, 1.321f, 1.32f,
+ 1.748f, 1.739f, 1.71f, 1.641f, 1.533f, 1.449f, 1.405f, 1.379f, 1.362f, 1.35f, 1.34f, 1.332f, 1.327f, 1.323f, 1.32f, 1.319f,
+ };
+ }
+}
diff --git a/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/AsrResources.cs.meta b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/AsrResources.cs.meta
new file mode 100644
index 0000000..b0f5f23
--- /dev/null
+++ b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/AsrResources.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 538f6eefa95c8ee4d9f6a9bc4bb3188e
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/AsrShaderIDs.cs b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/AsrShaderIDs.cs
new file mode 100644
index 0000000..8f829bb
--- /dev/null
+++ b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/AsrShaderIDs.cs
@@ -0,0 +1,75 @@
+// Copyright (c) 2024 Nico de Poel
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+using UnityEngine;
+
+namespace ArmASR
+{
+ public static class AsrShaderIDs
+ {
+ // Shader resource views, i.e. read-only bindings
+ public static readonly int SrvInputColor = Shader.PropertyToID("r_input_color_jittered");
+ public static readonly int SrvOpaqueOnly = Shader.PropertyToID("r_input_opaque_only");
+ public static readonly int SrvInputMotionVectors = Shader.PropertyToID("r_input_motion_vectors");
+ public static readonly int SrvInputDepth = Shader.PropertyToID("r_input_depth");
+ public static readonly int SrvInputExposure = Shader.PropertyToID("r_input_exposure");
+ public static readonly int SrvAutoExposure = Shader.PropertyToID("r_auto_exposure");
+ public static readonly int SrvReactiveMask = Shader.PropertyToID("r_reactive_mask");
+ public static readonly int SrvTransparencyAndCompositionMask = Shader.PropertyToID("r_transparency_and_composition_mask");
+ public static readonly int SrvReconstructedPrevNearestDepth = Shader.PropertyToID("r_reconstructed_previous_nearest_depth");
+ public static readonly int SrvDilatedMotionVectors = Shader.PropertyToID("r_dilated_motion_vectors");
+ public static readonly int SrvPrevDilatedMotionVectors = Shader.PropertyToID("r_previous_dilated_motion_vectors");
+ public static readonly int SrvDilatedDepth = Shader.PropertyToID("r_dilatedDepth");
+ public static readonly int SrvInternalUpscaled = Shader.PropertyToID("r_internal_upscaled_color");
+ public static readonly int SrvLockStatus = Shader.PropertyToID("r_lock_status");
+ public static readonly int SrvLockInputLuma = Shader.PropertyToID("r_lock_input_luma");
+ public static readonly int SrvPreparedInputColor = Shader.PropertyToID("r_prepared_input_color");
+ public static readonly int SrvLumaHistory = Shader.PropertyToID("r_luma_history");
+ public static readonly int SrvRcasInput = Shader.PropertyToID("r_rcas_input");
+ public static readonly int SrvLanczosLut = Shader.PropertyToID("r_lanczos_lut");
+ public static readonly int SrvSceneLuminanceMips = Shader.PropertyToID("r_imgMips");
+ public static readonly int SrvUpscaleMaximumBiasLut = Shader.PropertyToID("r_upsample_maximum_bias_lut");
+ public static readonly int SrvDilatedReactiveMasks = Shader.PropertyToID("r_dilated_reactive_masks");
+
+ // Unordered access views, i.e. random read/write bindings
+ public static readonly int UavReconstructedPrevNearestDepth = Shader.PropertyToID("rw_reconstructed_previous_nearest_depth");
+ public static readonly int UavDilatedMotionVectors = Shader.PropertyToID("rw_dilated_motion_vectors");
+ public static readonly int UavDilatedDepth = Shader.PropertyToID("rw_dilatedDepth");
+ public static readonly int UavInternalUpscaled = Shader.PropertyToID("rw_internal_upscaled_color");
+ public static readonly int UavLockStatus = Shader.PropertyToID("rw_lock_status");
+ public static readonly int UavLockInputLuma = Shader.PropertyToID("rw_lock_input_luma");
+ public static readonly int UavNewLocks = Shader.PropertyToID("rw_new_locks");
+ public static readonly int UavPreparedInputColor = Shader.PropertyToID("rw_prepared_input_color");
+ public static readonly int UavLumaHistory = Shader.PropertyToID("rw_luma_history");
+ public static readonly int UavUpscaledOutput = Shader.PropertyToID("rw_upscaled_output");
+ public static readonly int UavExposureMipLumaChange = Shader.PropertyToID("rw_img_mip_shading_change");
+ public static readonly int UavExposureMip5 = Shader.PropertyToID("rw_img_mip_5");
+ public static readonly int UavDilatedReactiveMasks = Shader.PropertyToID("rw_dilated_reactive_masks");
+ public static readonly int UavAutoExposure = Shader.PropertyToID("rw_auto_exposure");
+ public static readonly int UavSpdAtomicCount = Shader.PropertyToID("rw_spd_global_atomic");
+ public static readonly int UavAutoReactive = Shader.PropertyToID("rw_output_autoreactive");
+
+ // Constant buffer bindings
+ public static readonly int CbFsr2 = Shader.PropertyToID("cbFSR2");
+ public static readonly int CbSpd = Shader.PropertyToID("cbSPD");
+ public static readonly int CbRcas = Shader.PropertyToID("cbRCAS");
+ public static readonly int CbGenReactive = Shader.PropertyToID("cbGenerateReactive");
+ }
+}
diff --git a/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/AsrShaderIDs.cs.meta b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/AsrShaderIDs.cs.meta
new file mode 100644
index 0000000..c65dbb6
--- /dev/null
+++ b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/AsrShaderIDs.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: e0173241f8bd75e419590b43a3739e0e
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/ResourceView.cs b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/ResourceView.cs
new file mode 100644
index 0000000..fab2113
--- /dev/null
+++ b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/ResourceView.cs
@@ -0,0 +1,55 @@
+// Copyright (c) 2024 Nico de Poel
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+using UnityEngine.Rendering;
+
+namespace ArmASR
+{
+ ///
+ /// An immutable structure wrapping all the necessary information to bind a specific buffer or attachment of a render target to a compute shader.
+ ///
+ public readonly struct ResourceView
+ {
+ ///
+ /// This value is the equivalent of not setting any value at all; all struct fields will have their default values.
+ /// It does not refer to a valid texture, therefore any variable set to this value should be checked for IsValid and reassigned before being bound to a shader.
+ ///
+ public static readonly ResourceView Unassigned = new ResourceView(default);
+
+ ///
+ /// This value contains a valid texture reference that can be bound to a shader, however it is just an empty placeholder texture.
+ /// Binding this to a shader can be seen as setting the texture variable inside the shader to null.
+ ///
+ public static readonly ResourceView None = new ResourceView(BuiltinRenderTextureType.None);
+
+ public ResourceView(in RenderTargetIdentifier renderTarget, RenderTextureSubElement subElement = RenderTextureSubElement.Default, int mipLevel = 0)
+ {
+ RenderTarget = renderTarget;
+ SubElement = subElement;
+ MipLevel = mipLevel;
+ }
+
+ public bool IsValid => !RenderTarget.Equals(default);
+
+ public readonly RenderTargetIdentifier RenderTarget;
+ public readonly RenderTextureSubElement SubElement;
+ public readonly int MipLevel;
+ }
+}
diff --git a/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/ResourceView.cs.meta b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/ResourceView.cs.meta
new file mode 100644
index 0000000..f7e1122
--- /dev/null
+++ b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/ASR/Runtime/ResourceView.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 6e2e3cd4f5c3d4146b6fe3f93685751b
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant: