91 changed files with 14904 additions and 1 deletions
-
12com.unity.render-pipelines.high-definition/Editor/Lighting/ScreenSpaceAmbientOcclusionEditor.cs
-
8com.unity.render-pipelines.high-definition/Runtime/FidelityFX.meta
-
8com.unity.render-pipelines.high-definition/Runtime/FidelityFX/CACAO.meta
-
331com.unity.render-pipelines.high-definition/Runtime/FidelityFX/CACAO/Cacao.cs
-
11com.unity.render-pipelines.high-definition/Runtime/FidelityFX/CACAO/Cacao.cs.meta
-
77com.unity.render-pipelines.high-definition/Runtime/FidelityFX/CACAO/CacaoAssets.cs
-
11com.unity.render-pipelines.high-definition/Runtime/FidelityFX/CACAO/CacaoAssets.cs.meta
-
50com.unity.render-pipelines.high-definition/Runtime/FidelityFX/CACAO/CacaoConsts.cs
-
11com.unity.render-pipelines.high-definition/Runtime/FidelityFX/CACAO/CacaoConsts.cs.meta
-
411com.unity.render-pipelines.high-definition/Runtime/FidelityFX/CACAO/CacaoContext.cs
-
11com.unity.render-pipelines.high-definition/Runtime/FidelityFX/CACAO/CacaoContext.cs.meta
-
426com.unity.render-pipelines.high-definition/Runtime/FidelityFX/CACAO/CacaoPass.cs
-
11com.unity.render-pipelines.high-definition/Runtime/FidelityFX/CACAO/CacaoPass.cs.meta
-
150com.unity.render-pipelines.high-definition/Runtime/FidelityFX/CACAO/CacaoPreset.cs
-
11com.unity.render-pipelines.high-definition/Runtime/FidelityFX/CACAO/CacaoPreset.cs.meta
-
97com.unity.render-pipelines.high-definition/Runtime/FidelityFX/CACAO/CacaoResources.cs
-
11com.unity.render-pipelines.high-definition/Runtime/FidelityFX/CACAO/CacaoResources.cs.meta
-
35com.unity.render-pipelines.high-definition/Runtime/FidelityFX/CACAO/CacaoShaderIDs.cs
-
11com.unity.render-pipelines.high-definition/Runtime/FidelityFX/CACAO/CacaoShaderIDs.cs.meta
-
97com.unity.render-pipelines.high-definition/Runtime/FidelityFX/HDRenderPipeline.FidelityFX.Cacao.cs
-
11com.unity.render-pipelines.high-definition/Runtime/FidelityFX/HDRenderPipeline.FidelityFX.Cacao.cs.meta
-
10com.unity.render-pipelines.high-definition/Runtime/FidelityFX/ffx_cacao_apply_pass.compute
-
7com.unity.render-pipelines.high-definition/Runtime/FidelityFX/ffx_cacao_apply_pass.compute.meta
-
64com.unity.render-pipelines.high-definition/Runtime/FidelityFX/ffx_cacao_common_hdrp.cginc
-
7com.unity.render-pipelines.high-definition/Runtime/FidelityFX/ffx_cacao_common_hdrp.cginc.meta
-
15com.unity.render-pipelines.high-definition/Runtime/FidelityFX/ffx_cacao_edge_sensitive_blur_pass.compute
-
7com.unity.render-pipelines.high-definition/Runtime/FidelityFX/ffx_cacao_edge_sensitive_blur_pass.compute.meta
-
10com.unity.render-pipelines.high-definition/Runtime/FidelityFX/ffx_cacao_generate_importance_map_pass.compute
-
7com.unity.render-pipelines.high-definition/Runtime/FidelityFX/ffx_cacao_generate_importance_map_pass.compute.meta
-
12com.unity.render-pipelines.high-definition/Runtime/FidelityFX/ffx_cacao_generate_pass.compute
-
7com.unity.render-pipelines.high-definition/Runtime/FidelityFX/ffx_cacao_generate_pass.compute.meta
-
13com.unity.render-pipelines.high-definition/Runtime/FidelityFX/ffx_cacao_prepare_depths_pass.compute
-
7com.unity.render-pipelines.high-definition/Runtime/FidelityFX/ffx_cacao_prepare_depths_pass.compute.meta
-
11com.unity.render-pipelines.high-definition/Runtime/FidelityFX/ffx_cacao_prepare_normals_pass.compute
-
7com.unity.render-pipelines.high-definition/Runtime/FidelityFX/ffx_cacao_prepare_normals_pass.compute.meta
-
10com.unity.render-pipelines.high-definition/Runtime/FidelityFX/ffx_cacao_upscale_bilateral_pass.compute
-
7com.unity.render-pipelines.high-definition/Runtime/FidelityFX/ffx_cacao_upscale_bilateral_pass.compute.meta
-
8com.unity.render-pipelines.high-definition/Runtime/FidelityFX/shaders.meta
-
8com.unity.render-pipelines.high-definition/Runtime/FidelityFX/shaders/cacao.meta
-
105com.unity.render-pipelines.high-definition/Runtime/FidelityFX/shaders/cacao/ffx_cacao_apply.h
-
27com.unity.render-pipelines.high-definition/Runtime/FidelityFX/shaders/cacao/ffx_cacao_apply.h.meta
-
884com.unity.render-pipelines.high-definition/Runtime/FidelityFX/shaders/cacao/ffx_cacao_callbacks_hlsl.h
-
27com.unity.render-pipelines.high-definition/Runtime/FidelityFX/shaders/cacao/ffx_cacao_callbacks_hlsl.h.meta
-
85com.unity.render-pipelines.high-definition/Runtime/FidelityFX/shaders/cacao/ffx_cacao_defines.h
-
27com.unity.render-pipelines.high-definition/Runtime/FidelityFX/shaders/cacao/ffx_cacao_defines.h.meta
-
449com.unity.render-pipelines.high-definition/Runtime/FidelityFX/shaders/cacao/ffx_cacao_edge_sensitive_blur.h
-
27com.unity.render-pipelines.high-definition/Runtime/FidelityFX/shaders/cacao/ffx_cacao_edge_sensitive_blur.h.meta
-
111com.unity.render-pipelines.high-definition/Runtime/FidelityFX/shaders/cacao/ffx_cacao_importance_map.h
-
27com.unity.render-pipelines.high-definition/Runtime/FidelityFX/shaders/cacao/ffx_cacao_importance_map.h.meta
-
310com.unity.render-pipelines.high-definition/Runtime/FidelityFX/shaders/cacao/ffx_cacao_prepare.h
-
27com.unity.render-pipelines.high-definition/Runtime/FidelityFX/shaders/cacao/ffx_cacao_prepare.h.meta
-
50com.unity.render-pipelines.high-definition/Runtime/FidelityFX/shaders/cacao/ffx_cacao_resources.h
-
27com.unity.render-pipelines.high-definition/Runtime/FidelityFX/shaders/cacao/ffx_cacao_resources.h.meta
-
616com.unity.render-pipelines.high-definition/Runtime/FidelityFX/shaders/cacao/ffx_cacao_ssao_generation.h
-
27com.unity.render-pipelines.high-definition/Runtime/FidelityFX/shaders/cacao/ffx_cacao_ssao_generation.h.meta
-
611com.unity.render-pipelines.high-definition/Runtime/FidelityFX/shaders/cacao/ffx_cacao_upscale.h
-
27com.unity.render-pipelines.high-definition/Runtime/FidelityFX/shaders/cacao/ffx_cacao_upscale.h.meta
-
112com.unity.render-pipelines.high-definition/Runtime/FidelityFX/shaders/cacao/ffx_cacao_utils.h
-
27com.unity.render-pipelines.high-definition/Runtime/FidelityFX/shaders/cacao/ffx_cacao_utils.h.meta
-
8com.unity.render-pipelines.high-definition/Runtime/FidelityFX/shaders/common.meta
-
520com.unity.render-pipelines.high-definition/Runtime/FidelityFX/shaders/common/ffx_common_types.h
-
27com.unity.render-pipelines.high-definition/Runtime/FidelityFX/shaders/common/ffx_common_types.h.meta
-
80com.unity.render-pipelines.high-definition/Runtime/FidelityFX/shaders/common/ffx_core.h
-
27com.unity.render-pipelines.high-definition/Runtime/FidelityFX/shaders/common/ffx_core.h.meta
-
338com.unity.render-pipelines.high-definition/Runtime/FidelityFX/shaders/common/ffx_core_cpu.h
-
27com.unity.render-pipelines.high-definition/Runtime/FidelityFX/shaders/common/ffx_core_cpu.h.meta
-
2784com.unity.render-pipelines.high-definition/Runtime/FidelityFX/shaders/common/ffx_core_gpu_common.h
-
27com.unity.render-pipelines.high-definition/Runtime/FidelityFX/shaders/common/ffx_core_gpu_common.h.meta
-
2979com.unity.render-pipelines.high-definition/Runtime/FidelityFX/shaders/common/ffx_core_gpu_common_half.h
-
27com.unity.render-pipelines.high-definition/Runtime/FidelityFX/shaders/common/ffx_core_gpu_common_half.h.meta
-
1651com.unity.render-pipelines.high-definition/Runtime/FidelityFX/shaders/common/ffx_core_hlsl.h
-
27com.unity.render-pipelines.high-definition/Runtime/FidelityFX/shaders/common/ffx_core_hlsl.h.meta
-
51com.unity.render-pipelines.high-definition/Runtime/FidelityFX/shaders/common/ffx_core_portability.h
-
27com.unity.render-pipelines.high-definition/Runtime/FidelityFX/shaders/common/ffx_core_portability.h.meta
-
66com.unity.render-pipelines.high-definition/Runtime/FidelityFX/shaders/ffx_cacao_apply_pass.hlsl
-
7com.unity.render-pipelines.high-definition/Runtime/FidelityFX/shaders/ffx_cacao_apply_pass.hlsl.meta
-
106com.unity.render-pipelines.high-definition/Runtime/FidelityFX/shaders/ffx_cacao_edge_sensitive_blur_pass.hlsl
-
7com.unity.render-pipelines.high-definition/Runtime/FidelityFX/shaders/ffx_cacao_edge_sensitive_blur_pass.hlsl.meta
-
70com.unity.render-pipelines.high-definition/Runtime/FidelityFX/shaders/ffx_cacao_generate_importance_map_pass.hlsl
-
7com.unity.render-pipelines.high-definition/Runtime/FidelityFX/shaders/ffx_cacao_generate_importance_map_pass.hlsl.meta
-
86com.unity.render-pipelines.high-definition/Runtime/FidelityFX/shaders/ffx_cacao_generate_pass.hlsl
-
7com.unity.render-pipelines.high-definition/Runtime/FidelityFX/shaders/ffx_cacao_generate_pass.hlsl.meta
-
91com.unity.render-pipelines.high-definition/Runtime/FidelityFX/shaders/ffx_cacao_prepare_depths_pass.hlsl
-
7com.unity.render-pipelines.high-definition/Runtime/FidelityFX/shaders/ffx_cacao_prepare_depths_pass.hlsl.meta
-
75com.unity.render-pipelines.high-definition/Runtime/FidelityFX/shaders/ffx_cacao_prepare_normals_pass.hlsl
-
7com.unity.render-pipelines.high-definition/Runtime/FidelityFX/shaders/ffx_cacao_prepare_normals_pass.hlsl.meta
-
68com.unity.render-pipelines.high-definition/Runtime/FidelityFX/shaders/ffx_cacao_upscale_bilateral_pass.hlsl
-
7com.unity.render-pipelines.high-definition/Runtime/FidelityFX/shaders/ffx_cacao_upscale_bilateral_pass.hlsl.meta
-
16com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/HDRenderPipeline.AmbientOcclusion.cs
-
5com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceAmbientOcclusion.cs
-
52com.unity.render-pipelines.high-definition/Runtime/Settings/HDRenderPipelineRuntimeShaders.cs
@ -0,0 +1,8 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 7ee27cfd7cbf3d94e834b1d8ab1c7201 |
|||
folderAsset: yes |
|||
DefaultImporter: |
|||
externalObjects: {} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,8 @@ |
|||
fileFormatVersion: 2 |
|||
guid: d72abc5804ba8c4418ce720e6e281ce7 |
|||
folderAsset: yes |
|||
DefaultImporter: |
|||
externalObjects: {} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,331 @@ |
|||
using System; |
|||
using System.Runtime.InteropServices; |
|||
using UnityEngine; |
|||
using UnityEngine.Rendering; |
|||
|
|||
namespace FidelityFX |
|||
{ |
|||
/// <summary>
|
|||
/// Port of ffx_cacao.cpp/.h
|
|||
/// </summary>
|
|||
public static class Cacao |
|||
{ |
|||
/// <summary>
|
|||
/// Matrix to flip a couple of axes from Unity view space to CACAO's expected view space.
|
|||
/// </summary>
|
|||
public static Matrix4x4 UnityToCacaoViewMatrix = Matrix4x4.Scale(new Vector3(1f, -1f, -1f)); |
|||
|
|||
/// <summary>
|
|||
/// The quality levels that FidelityFX CACAO can generate SSAO at. This affects the number of samples taken for generating SSAO.
|
|||
/// </summary>
|
|||
public enum Quality |
|||
{ |
|||
Lowest = 0, |
|||
Low = 1, |
|||
Medium = 2, |
|||
High = 3, |
|||
Highest = 4, |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// A structure for the settings used by FidelityFX CACAO. These settings may be updated with each draw call.
|
|||
/// </summary>
|
|||
[Serializable] |
|||
public struct Settings |
|||
{ |
|||
[Range(0, 10), Tooltip("World (view) space size of the occlusion sphere.")] |
|||
public float radius; |
|||
|
|||
[Range(0, 5), Tooltip("Effect strength linear multiplier.")] |
|||
public float shadowMultiplier; |
|||
|
|||
[Range(0.5f, 5), Tooltip("Effect strength pow modifier.")] |
|||
public float shadowPower; |
|||
|
|||
[Range(0, 1), Tooltip("Effect max limit (applied after multiplier but before blur).")] |
|||
public float shadowClamp; |
|||
|
|||
[Range(0, 0.2f), Tooltip("Limits self-shadowing (makes the sampling area less of a hemisphere, more of a spherical cone, to avoid self-shadowing and various artifacts due to low tessellation and depth buffer imprecision, etc.).")] |
|||
public float horizonAngleThreshold; |
|||
|
|||
[Range(0, 1000), Tooltip("Distance to start fading out the effect.")] |
|||
public float fadeOutFrom; |
|||
|
|||
[Range(0, 1000), Tooltip("Distance at which the effect is faded out.")] |
|||
public float fadeOutTo; |
|||
|
|||
[Tooltip("Effect quality, affects number of taps etc.")] |
|||
public Quality qualityLevel; |
|||
|
|||
[Range(0, 1), Tooltip("Only for quality level Highest.")] |
|||
public float adaptiveQualityLimit; |
|||
|
|||
[Range(0, 8), Tooltip("Number of edge-sensitive smart blur passes to apply.")] |
|||
public uint blurPassCount; |
|||
|
|||
[Range(0, 1), Tooltip("How much to bleed over edges; 1: not at all, 0.5: half-half; 0.0: completely ignore edges.")] |
|||
public float sharpness; |
|||
|
|||
[Range(0, Mathf.PI), Tooltip("Used to rotate sampling kernel; If using temporal AA / supersampling, suggested to rotate by ( (frame%3)/3.0*PI ) or similar. Kernel is already symmetrical, which is why we use PI and not 2*PI.")] |
|||
public float temporalSupersamplingAngleOffset; |
|||
|
|||
[Range(0, 2), Tooltip("Used to scale sampling kernel; If using temporal AA / supersampling, suggested to scale by ( 1.0f + (((frame%3)-1.0)/3.0)*0.1 ) or similar.")] |
|||
public float temporalSupersamplingRadiusOffset; |
|||
|
|||
[Range(0, 5), Tooltip("Used for high-res detail AO using neighboring depth pixels: adds a lot of detail but also reduces temporal stability (adds aliasing).")] |
|||
public float detailShadowStrength; |
|||
|
|||
[Tooltip("This option should be set to true if FidelityFX-CACAO should reconstruct a normal buffer from the depth buffer. It is required to be true if no normal buffer is provided.")] |
|||
public bool generateNormals; |
|||
|
|||
[Tooltip("Sigma squared value for use in bilateral upsampler giving Gaussian blur term. Should be greater than 0.0.")] |
|||
public float bilateralSigmaSquared; |
|||
|
|||
[Tooltip("Sigma squared value for use in bilateral upsampler giving similarity weighting for neighbouring pixels. Should be greater than 0.0.")] |
|||
public float bilateralSimilarityDistanceSigma; |
|||
} |
|||
|
|||
public static readonly Settings DefaultSettings = new() |
|||
{ |
|||
radius = 1.2f, |
|||
shadowMultiplier = 1.0f, |
|||
shadowPower = 1.5f, |
|||
shadowClamp = 0.98f, |
|||
horizonAngleThreshold = 0.06f, |
|||
fadeOutFrom = 50f, |
|||
fadeOutTo = 300f, |
|||
qualityLevel = Quality.Highest, |
|||
adaptiveQualityLimit = 0.45f, |
|||
blurPassCount = 2, |
|||
sharpness = 0.98f, |
|||
temporalSupersamplingAngleOffset = 0f, |
|||
temporalSupersamplingRadiusOffset = 0f, |
|||
detailShadowStrength = 0.5f, |
|||
generateNormals = false, |
|||
bilateralSigmaSquared = 5f, |
|||
bilateralSimilarityDistanceSigma = 0.01f, |
|||
}; |
|||
|
|||
/// <summary>
|
|||
/// The parameters necessary when changing the screen size of FidelityFX CACAO.
|
|||
/// </summary>
|
|||
public struct ScreenSizeInfo |
|||
{ |
|||
public uint Width; |
|||
public uint Height; |
|||
public bool UseDownsampledSsao; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// A structure containing all of the input and output render targets used by FidelityFX CACAO.
|
|||
/// </summary>
|
|||
public struct DispatchInfo |
|||
{ |
|||
public ResourceView DepthView; |
|||
public ResourceView? NormalsView; // This will be ignored if GenerateNormals is true
|
|||
public ResourceView OutputView; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// A structure containing sizes of each of the buffers used by FidelityFX CACAO.
|
|||
/// </summary>
|
|||
internal struct BufferSizeInfo |
|||
{ |
|||
public uint InputOutputBufferWidth; |
|||
public uint InputOutputBufferHeight; |
|||
|
|||
public uint SsaoBufferWidth; |
|||
public uint SsaoBufferHeight; |
|||
|
|||
public uint DepthBufferXOffset; |
|||
public uint DepthBufferYOffset; |
|||
|
|||
public uint DepthBufferWidth; |
|||
public uint DepthBufferHeight; |
|||
|
|||
public uint DeinterleavedDepthBufferXOffset; |
|||
public uint DeinterleavedDepthBufferYOffset; |
|||
|
|||
public uint DeinterleavedDepthBufferWidth; |
|||
public uint DeinterleavedDepthBufferHeight; |
|||
|
|||
public uint ImportanceMapWidth; |
|||
public uint ImportanceMapHeight; |
|||
|
|||
public uint DownsampledSsaoBufferWidth; |
|||
public uint DownsampledSsaoBufferHeight; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// A C# structure for the constant buffer used by FidelityFX CACAO.
|
|||
/// </summary>
|
|||
[Serializable, StructLayout(LayoutKind.Sequential)] |
|||
internal struct Constants |
|||
{ |
|||
public Vector2 DepthUnpackConsts; |
|||
public Vector2 CameraTanHalfFOV; |
|||
|
|||
public Vector2 NDCToViewMul; |
|||
public Vector2 NDCToViewAdd; |
|||
|
|||
public Vector2 DepthBufferUVToViewMul; |
|||
public Vector2 DepthBufferUVToViewAdd; |
|||
|
|||
public float EffectRadius; |
|||
public float EffectShadowStrength; |
|||
public float EffectShadowPow; |
|||
public float EffectShadowClamp; |
|||
|
|||
public float EffectFadeOutMul; |
|||
public float EffectFadeOutAdd; |
|||
public float EffectHorizonAngleThreshold; |
|||
public float EffectSamplingRadiusNearLimitRec; |
|||
|
|||
public float DepthPrecisionOffsetMod; |
|||
public float NegRecEffectRadius; |
|||
public float LoadCounterAvgDiv; |
|||
public float AdaptiveSampleCountLimit; |
|||
|
|||
public float InvSharpness; |
|||
public int BlurNumPasses; |
|||
public float BilateralSigmaSquared; |
|||
public float BilateralSimilarityDistanceSigma; |
|||
|
|||
public PatternRotScaleMatrices PatternRotScaleMatrices0; |
|||
public PatternRotScaleMatrices PatternRotScaleMatrices1; |
|||
public PatternRotScaleMatrices PatternRotScaleMatrices2; |
|||
public PatternRotScaleMatrices PatternRotScaleMatrices3; |
|||
|
|||
public float NormalsUnpackMul; |
|||
public float NormalsUnpackAdd; |
|||
public float DetailAOStrength; |
|||
public int Dummy0; |
|||
|
|||
public Vector2 SSAOBufferDimensions; |
|||
public Vector2 SSAOBufferInverseDimensions; |
|||
|
|||
public Vector2 DepthBufferDimensions; |
|||
public Vector2 DepthBufferInverseDimensions; |
|||
|
|||
public Vector2Int DepthBufferOffset; |
|||
public Vector2Int Pad; |
|||
|
|||
public Vector4 PerPassFullResUVOffset0; |
|||
public Vector4 PerPassFullResUVOffset1; |
|||
public Vector4 PerPassFullResUVOffset2; |
|||
public Vector4 PerPassFullResUVOffset3; |
|||
|
|||
public Vector2 InputOutputBufferDimensions; |
|||
public Vector2 InputOutputBufferInverseDimensions; |
|||
|
|||
public Vector2 ImportanceMapDimensions; |
|||
public Vector2 ImportanceMapInverseDimensions; |
|||
|
|||
public Vector2 DeinterleavedDepthBufferDimensions; |
|||
public Vector2 DeinterleavedDepthBufferInverseDimensions; |
|||
|
|||
public Vector2 DeinterleavedDepthBufferOffset; |
|||
public Vector2 DeinterleavedDepthBufferNormalisedOffset; |
|||
|
|||
public Matrix4x4 NormalsWorldToViewspaceMatrix; |
|||
} |
|||
|
|||
[Serializable, StructLayout(LayoutKind.Sequential)] |
|||
internal struct PatternRotScaleMatrices |
|||
{ |
|||
// This is a really ugly solution, but fixed-size arrays are not blittable by Unity
|
|||
public Vector4 PatternRotScaleMatrix0; |
|||
public Vector4 PatternRotScaleMatrix1; |
|||
public Vector4 PatternRotScaleMatrix2; |
|||
public Vector4 PatternRotScaleMatrix3; |
|||
public Vector4 PatternRotScaleMatrix4; |
|||
} |
|||
|
|||
// Nasty workaround for the fact that we can't store these matrices in an array
|
|||
internal static ref Vector4 GetPerPassFullResUVOffset(this ref Constants consts, int index) |
|||
{ |
|||
switch (index) |
|||
{ |
|||
case 0: |
|||
return ref consts.PerPassFullResUVOffset0; |
|||
case 1: |
|||
return ref consts.PerPassFullResUVOffset1; |
|||
case 2: |
|||
return ref consts.PerPassFullResUVOffset2; |
|||
case 3: |
|||
return ref consts.PerPassFullResUVOffset3; |
|||
default: |
|||
throw new IndexOutOfRangeException(); |
|||
} |
|||
} |
|||
|
|||
// Nasty workaround for the fact that we can't store these matrices in an array
|
|||
internal static ref PatternRotScaleMatrices GetPatternRotScaleMatrices(this ref Constants consts, int index) |
|||
{ |
|||
switch (index) |
|||
{ |
|||
case 0: |
|||
return ref consts.PatternRotScaleMatrices0; |
|||
case 1: |
|||
return ref consts.PatternRotScaleMatrices1; |
|||
case 2: |
|||
return ref consts.PatternRotScaleMatrices2; |
|||
case 3: |
|||
return ref consts.PatternRotScaleMatrices3; |
|||
default: |
|||
throw new IndexOutOfRangeException(); |
|||
} |
|||
} |
|||
|
|||
// Nasty workaround for the fact that we can't store these matrices in an array
|
|||
internal static ref Vector4 GetPatternRotScaleMatrix(this ref PatternRotScaleMatrices matrices, int index) |
|||
{ |
|||
switch (index) |
|||
{ |
|||
case 0: |
|||
return ref matrices.PatternRotScaleMatrix0; |
|||
case 1: |
|||
return ref matrices.PatternRotScaleMatrix1; |
|||
case 2: |
|||
return ref matrices.PatternRotScaleMatrix2; |
|||
case 3: |
|||
return ref matrices.PatternRotScaleMatrix3; |
|||
case 4: |
|||
return ref matrices.PatternRotScaleMatrix4; |
|||
default: |
|||
throw new IndexOutOfRangeException(); |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// An immutable structure wrapping all of the necessary information to bind a specific buffer or attachment of a render target to a compute shader.
|
|||
/// </summary>
|
|||
public readonly struct ResourceView |
|||
{ |
|||
/// <summary>
|
|||
/// 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.
|
|||
/// </summary>
|
|||
public static readonly ResourceView Unassigned = new ResourceView(default); |
|||
|
|||
/// <summary>
|
|||
/// 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.
|
|||
/// </summary>
|
|||
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; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 5e78f7678cf696e4e9d5058e6bce96ad |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,77 @@ |
|||
using UnityEngine; |
|||
|
|||
namespace FidelityFX |
|||
{ |
|||
public class CacaoAssets : ScriptableObject |
|||
{ |
|||
public CacaoShaders shaders; |
|||
|
|||
#if UNITY_EDITOR
|
|||
private void Reset() |
|||
{ |
|||
shaders = new CacaoShaders |
|||
{ |
|||
prepareDepths = FindComputeShader("ffx_cacao_prepare_depths_pass"), |
|||
prepareNormals = FindComputeShader("ffx_cacao_prepare_normals_pass"), |
|||
generateImportanceMap = FindComputeShader("ffx_cacao_generate_importance_map_pass"), |
|||
generateSsao = FindComputeShader("ffx_cacao_generate_pass"), |
|||
edgeSensitiveBlur = FindComputeShader("ffx_cacao_edge_sensitive_blur_pass"), |
|||
bilateralUpscale = FindComputeShader("ffx_cacao_upscale_bilateral_pass"), |
|||
reinterleave = FindComputeShader("ffx_cacao_apply_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<ComputeShader>(assetPath); |
|||
} |
|||
#endif
|
|||
} |
|||
|
|||
[System.Serializable] |
|||
public class CacaoShaders |
|||
{ |
|||
public ComputeShader prepareDepths; |
|||
public ComputeShader prepareNormals; |
|||
public ComputeShader generateImportanceMap; |
|||
public ComputeShader generateSsao; |
|||
public ComputeShader edgeSensitiveBlur; |
|||
public ComputeShader bilateralUpscale; |
|||
public ComputeShader reinterleave; |
|||
|
|||
public CacaoShaders Clone() |
|||
{ |
|||
return (CacaoShaders)MemberwiseClone(); |
|||
} |
|||
|
|||
public CacaoShaders DeepCopy() |
|||
{ |
|||
return new CacaoShaders |
|||
{ |
|||
prepareDepths = Object.Instantiate(prepareDepths), |
|||
prepareNormals = Object.Instantiate(prepareNormals), |
|||
generateImportanceMap = Object.Instantiate(generateImportanceMap), |
|||
generateSsao = Object.Instantiate(generateSsao), |
|||
edgeSensitiveBlur = Object.Instantiate(edgeSensitiveBlur), |
|||
bilateralUpscale = Object.Instantiate(bilateralUpscale), |
|||
reinterleave = Object.Instantiate(reinterleave), |
|||
}; |
|||
} |
|||
|
|||
public void Dispose() |
|||
{ |
|||
Object.Destroy(prepareDepths); |
|||
Object.Destroy(prepareNormals); |
|||
Object.Destroy(generateImportanceMap); |
|||
Object.Destroy(generateSsao); |
|||
Object.Destroy(edgeSensitiveBlur); |
|||
Object.Destroy(bilateralUpscale); |
|||
Object.Destroy(reinterleave); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
fileFormatVersion: 2 |
|||
guid: b37a4f858b846a3408956de7254d575d |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,50 @@ |
|||
namespace FidelityFX |
|||
{ |
|||
internal static class CacaoConsts |
|||
{ |
|||
// Prepare
|
|||
public const int PrepareDepthsAndMipsWidth = 8; |
|||
public const int PrepareDepthsAndMipsHeight = 8; |
|||
|
|||
public const int PrepareDepthsWidth = 8; |
|||
public const int PrepareDepthsHeight = 8; |
|||
|
|||
public const int PrepareDepthsHalfWidth = 8; |
|||
public const int PrepareDepthsHalfHeight = 8; |
|||
|
|||
public const int PrepareNormalsWidth = 8; |
|||
public const int PrepareNormalsHeight = 8; |
|||
|
|||
public const int PrepareNormalsFromInputNormalsWidth = 8; |
|||
public const int PrepareNormalsFromInputNormalsHeight = 8; |
|||
|
|||
// SSAO Generation
|
|||
public const int GenerateSparseWidth = 4; |
|||
public const int GenerateSparseHeight = 16; |
|||
|
|||
public const int GenerateWidth = 8; |
|||
public const int GenerateHeight = 8; |
|||
|
|||
// Importance Map
|
|||
public const int ImportanceMapWidth = 8; |
|||
public const int ImportanceMapHeight = 8; |
|||
|
|||
public const int ImportanceMapAWidth = 8; |
|||
public const int ImportanceMapAHeight = 8; |
|||
|
|||
public const int ImportanceMapBWidth = 8; |
|||
public const int ImportanceMapBHeight = 8; |
|||
|
|||
// Edge Sensitive Blur
|
|||
public const int BlurWidth = 16; |
|||
public const int BlurHeight = 16; |
|||
|
|||
// Apply
|
|||
public const int ApplyWidth = 8; |
|||
public const int ApplyHeight = 8; |
|||
|
|||
// Bilateral Upscale
|
|||
public const int BilateralUpscaleWidth = 8; |
|||
public const int BilateralUpscaleHeight = 8; |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
fileFormatVersion: 2 |
|||
guid: f00024bd5483b094c869a4be87114629 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,411 @@ |
|||
using System; |
|||
using System.Runtime.InteropServices; |
|||
using Unity.Profiling; |
|||
using UnityEngine; |
|||
using UnityEngine.Rendering; |
|||
|
|||
namespace FidelityFX |
|||
{ |
|||
/// <summary>
|
|||
/// Port of ffx_cacao_impl.cpp/.h
|
|||
/// </summary>
|
|||
public class CacaoContext |
|||
{ |
|||
private Cacao.Settings _settings; |
|||
private Cacao.BufferSizeInfo _bufferSizeInfo; |
|||
private bool _useDownsampledSsao; |
|||
|
|||
private readonly CacaoResources _resources = new CacaoResources(); |
|||
|
|||
private CacaoPrepareDepthsPass _prepareDepthsPass; |
|||
private CacaoPrepareNormalsPass _prepareNormalsPass; |
|||
private CacaoGenerateBaseSsaoPass _generateBaseSsaoPass; |
|||
private CacaoGenerateImportanceMapPass _generateImportanceMapPass; |
|||
private CacaoGenerateSsaoPass _generateSsaoPass; |
|||
private CacaoEdgeSensitiveBlurPass _edgeSensitiveBlurPass; |
|||
private CacaoBilateralUpscalePass _bilateralUpscalePass; |
|||
private CacaoReinterleavePass _reinterleavePass; |
|||
|
|||
private ComputeBuffer _constantsBuffer; |
|||
private readonly Cacao.Constants[] _constants = new Cacao.Constants[1]; |
|||
private ref Cacao.Constants Constants => ref _constants[0]; |
|||
|
|||
public bool Init(CacaoShaders shaders) |
|||
{ |
|||
// Create constant buffers
|
|||
_constantsBuffer = CreateConstantBuffer<Cacao.Constants>("FFX_CACAO_CONSTANT_BUFFER"); |
|||
|
|||
// Create load counter resource
|
|||
if (!_resources.CreateLoadCounter()) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
// Initialize compute shaders
|
|||
CreatePasses(shaders); |
|||
return true; |
|||
} |
|||
|
|||
private void CreatePasses(CacaoShaders shaders) |
|||
{ |
|||
_prepareDepthsPass = new CacaoPrepareDepthsPass(shaders.prepareDepths, _resources); |
|||
_prepareNormalsPass = new CacaoPrepareNormalsPass(shaders.prepareNormals, _resources); |
|||
_generateBaseSsaoPass = new CacaoGenerateBaseSsaoPass(shaders.generateSsao, _resources); |
|||
_generateImportanceMapPass = new CacaoGenerateImportanceMapPass(shaders.generateImportanceMap, _resources); |
|||
_generateSsaoPass = new CacaoGenerateSsaoPass(shaders.generateSsao, _resources); |
|||
_edgeSensitiveBlurPass = new CacaoEdgeSensitiveBlurPass(shaders.edgeSensitiveBlur, _resources); |
|||
_bilateralUpscalePass = new CacaoBilateralUpscalePass(shaders.bilateralUpscale, _resources); |
|||
_reinterleavePass = new CacaoReinterleavePass(shaders.reinterleave, _resources); |
|||
} |
|||
|
|||
public void Destroy() |
|||
{ |
|||
DestroyPass(ref _prepareDepthsPass); |
|||
DestroyPass(ref _prepareNormalsPass); |
|||
DestroyPass(ref _generateBaseSsaoPass); |
|||
DestroyPass(ref _generateImportanceMapPass); |
|||
DestroyPass(ref _generateSsaoPass); |
|||
DestroyPass(ref _edgeSensitiveBlurPass); |
|||
DestroyPass(ref _bilateralUpscalePass); |
|||
DestroyPass(ref _reinterleavePass); |
|||
|
|||
_resources.DestroyLoadCounter(); |
|||
|
|||
DestroyConstantBuffer(ref _constantsBuffer); |
|||
} |
|||
|
|||
public bool InitScreenSizeDependentResources(in Cacao.ScreenSizeInfo info) |
|||
{ |
|||
_useDownsampledSsao = info.UseDownsampledSsao; |
|||
|
|||
UpdateBufferSizeInfo(info.Width, info.Height, _useDownsampledSsao, out _bufferSizeInfo); |
|||
|
|||
// Create textures
|
|||
return _resources.CreateResources(_bufferSizeInfo); |
|||
} |
|||
|
|||
public void DestroyScreenSizeDependentResources() |
|||
{ |
|||
_resources.DestroyResources(); |
|||
} |
|||
|
|||
public void UpdateSettings(in Cacao.Settings settings) |
|||
{ |
|||
_settings = settings; |
|||
} |
|||
|
|||
private static readonly ProfilerMarker PrepareMarker = new ProfilerMarker("Prepare Downsampled Depth, Normals and Mips"); |
|||
private static readonly ProfilerMarker BasePassMarker = new ProfilerMarker("Generate High Quality Base Pass"); |
|||
private static readonly ProfilerMarker BaseSsaoMarker = new ProfilerMarker("Base SSAO"); |
|||
private static readonly ProfilerMarker ImportanceMapMarker = new ProfilerMarker("Importance Map"); |
|||
private static readonly ProfilerMarker GenerateSsaoMarker = new ProfilerMarker("Generate SSAO"); |
|||
private static readonly ProfilerMarker DeinterleavedBlurMarker = new ProfilerMarker("Deinterleaved Blur"); |
|||
private static readonly ProfilerMarker BilateralUpsampleMarker = new ProfilerMarker("Bilateral Upsample"); |
|||
private static readonly ProfilerMarker ReinterleaveMarker = new ProfilerMarker("Reinterleave"); |
|||
|
|||
public void Draw(CommandBuffer commandBuffer, in Cacao.DispatchInfo dispatchInfo, in Matrix4x4 proj, in Matrix4x4 normalsToView) |
|||
{ |
|||
// Update constant buffers
|
|||
UpdateConstants(ref Constants, _settings, _bufferSizeInfo, proj, normalsToView); |
|||
commandBuffer.SetBufferData(_constantsBuffer, _constants); |
|||
|
|||
// Clear load counter
|
|||
commandBuffer.SetRenderTarget(_resources.LoadCounter); |
|||
commandBuffer.ClearRenderTarget(false, true, Color.clear); |
|||
|
|||
// Prepare depths, normals and mips
|
|||
commandBuffer.BeginSample(PrepareMarker); |
|||
_prepareDepthsPass.Execute(commandBuffer, _constantsBuffer, dispatchInfo, _bufferSizeInfo, _settings.qualityLevel, _useDownsampledSsao); |
|||
_prepareNormalsPass.Execute(commandBuffer, _constantsBuffer, dispatchInfo, _bufferSizeInfo, _settings.generateNormals, _useDownsampledSsao); |
|||
commandBuffer.EndSample(PrepareMarker); |
|||
|
|||
// Base pass for the highest quality setting
|
|||
if (_settings.qualityLevel == Cacao.Quality.Highest) |
|||
{ |
|||
commandBuffer.BeginSample(BasePassMarker); |
|||
|
|||
commandBuffer.BeginSample(BaseSsaoMarker); |
|||
_generateBaseSsaoPass.Execute(commandBuffer, _constantsBuffer, _bufferSizeInfo); |
|||
commandBuffer.EndSample(BaseSsaoMarker); |
|||
|
|||
commandBuffer.BeginSample(ImportanceMapMarker); |
|||
_generateImportanceMapPass.Execute(commandBuffer, _constantsBuffer, _bufferSizeInfo); |
|||
commandBuffer.EndSample(ImportanceMapMarker); |
|||
|
|||
commandBuffer.EndSample(BasePassMarker); |
|||
} |
|||
|
|||
// Main SSAO generation
|
|||
commandBuffer.BeginSample(GenerateSsaoMarker); |
|||
_generateSsaoPass.Execute(commandBuffer, _constantsBuffer, _bufferSizeInfo, _settings.qualityLevel); |
|||
commandBuffer.EndSample(GenerateSsaoMarker); |
|||
|
|||
// De-interleaved blur
|
|||
uint blurPassCount = Math.Clamp(_settings.blurPassCount, 0, 8); |
|||
if (blurPassCount > 0) |
|||
{ |
|||
commandBuffer.BeginSample(DeinterleavedBlurMarker); |
|||
_edgeSensitiveBlurPass.Execute(commandBuffer, _constantsBuffer, _bufferSizeInfo, _settings.qualityLevel, blurPassCount); |
|||
commandBuffer.EndSample(DeinterleavedBlurMarker); |
|||
} |
|||
|
|||
if (_useDownsampledSsao) |
|||
{ |
|||
// Bilateral upsample
|
|||
commandBuffer.BeginSample(BilateralUpsampleMarker); |
|||
_bilateralUpscalePass.Execute(commandBuffer, _constantsBuffer, dispatchInfo, _bufferSizeInfo, _settings.qualityLevel, blurPassCount > 0); |
|||
commandBuffer.EndSample(BilateralUpsampleMarker); |
|||
} |
|||
else |
|||
{ |
|||
// Reinterleave
|
|||
commandBuffer.BeginSample(ReinterleaveMarker); |
|||
_reinterleavePass.Execute(commandBuffer, _constantsBuffer, dispatchInfo, _bufferSizeInfo, _settings.qualityLevel, blurPassCount > 0); |
|||
commandBuffer.EndSample(ReinterleaveMarker); |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Update buffer size info for resolution width x height.
|
|||
/// </summary>
|
|||
/// <param name="width">Screen width.</param>
|
|||
/// <param name="height">Screen height.</param>
|
|||
/// <param name="useDownsampledSsao">Whether FFX CACAO should use downsampling.</param>
|
|||
/// <param name="bsi">Output buffer size info.</param>
|
|||
private static void UpdateBufferSizeInfo(uint width, uint height, bool useDownsampledSsao, out Cacao.BufferSizeInfo bsi) |
|||
{ |
|||
uint halfWidth = (width + 1) / 2; |
|||
uint halfHeight = (height + 1) / 2; |
|||
uint quarterWidth = (halfWidth + 1) / 2; |
|||
uint quarterHeight = (halfHeight + 1) / 2; |
|||
uint eighthWidth = (quarterWidth + 1) / 2; |
|||
uint eighthHeight = (quarterHeight + 1) / 2; |
|||
|
|||
uint depthBufferWidth = width; |
|||
uint depthBufferHeight = height; |
|||
uint depthBufferHalfWidth = halfWidth; |
|||
uint depthBufferHalfHeight = halfHeight; |
|||
uint depthBufferQuarterWidth = quarterWidth; |
|||
uint depthBufferQuarterHeight = quarterHeight; |
|||
|
|||
uint depthBufferXOffset = 0; |
|||
uint depthBufferYOffset = 0; |
|||
uint depthBufferHalfXOffset = 0; |
|||
uint depthBufferHalfYOffset = 0; |
|||
uint depthBufferQuarterXOffset = 0; |
|||
uint depthBufferQuarterYOffset = 0; |
|||
|
|||
bsi.InputOutputBufferWidth = width; |
|||
bsi.InputOutputBufferHeight = height; |
|||
bsi.DepthBufferXOffset = depthBufferXOffset; |
|||
bsi.DepthBufferYOffset = depthBufferYOffset; |
|||
bsi.DepthBufferWidth = depthBufferWidth; |
|||
bsi.DepthBufferHeight = depthBufferHeight; |
|||
|
|||
if (useDownsampledSsao) |
|||
{ |
|||
bsi.SsaoBufferWidth = quarterWidth; |
|||
bsi.SsaoBufferHeight = quarterHeight; |
|||
bsi.DeinterleavedDepthBufferXOffset = depthBufferQuarterXOffset; |
|||
bsi.DeinterleavedDepthBufferYOffset = depthBufferQuarterYOffset; |
|||
bsi.DeinterleavedDepthBufferWidth = depthBufferQuarterWidth; |
|||
bsi.DeinterleavedDepthBufferHeight = depthBufferQuarterHeight; |
|||
bsi.ImportanceMapWidth = eighthWidth; |
|||
bsi.ImportanceMapHeight = eighthHeight; |
|||
bsi.DownsampledSsaoBufferWidth = halfWidth; |
|||
bsi.DownsampledSsaoBufferHeight = halfHeight; |
|||
} |
|||
else |
|||
{ |
|||
bsi.SsaoBufferWidth = halfWidth; |
|||
bsi.SsaoBufferHeight = halfHeight; |
|||
bsi.DeinterleavedDepthBufferXOffset = depthBufferHalfXOffset; |
|||
bsi.DeinterleavedDepthBufferYOffset = depthBufferHalfYOffset; |
|||
bsi.DeinterleavedDepthBufferWidth = depthBufferHalfWidth; |
|||
bsi.DeinterleavedDepthBufferHeight = depthBufferHalfHeight; |
|||
bsi.ImportanceMapWidth = quarterWidth; |
|||
bsi.ImportanceMapHeight = quarterHeight; |
|||
bsi.DownsampledSsaoBufferWidth = 1; |
|||
bsi.DownsampledSsaoBufferHeight = 1; |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Update the contents of the FFX CACAO constant buffer (an FFX_CACAO_Constants struct). Note, this function does not update per pass constants.
|
|||
/// </summary>
|
|||
/// <param name="consts">Cacao.Constants constant buffer.</param>
|
|||
/// <param name="settings">Cacao.Settings settings.</param>
|
|||
/// <param name="bufferSizeInfo">Cacao.BufferSizeInfo buffer size info.</param>
|
|||
/// <param name="proj">Projection matrix for the frame.</param>
|
|||
/// <param name="normalsToView">Normals world space to view space matrix for the frame.</param>
|
|||
private static void UpdateConstants(ref Cacao.Constants consts, in Cacao.Settings settings, in Cacao.BufferSizeInfo bufferSizeInfo, in Matrix4x4 proj, in Matrix4x4 normalsToView) |
|||
{ |
|||
consts.BilateralSigmaSquared = settings.bilateralSigmaSquared; |
|||
consts.BilateralSimilarityDistanceSigma = settings.bilateralSimilarityDistanceSigma; |
|||
|
|||
if (settings.generateNormals) |
|||
{ |
|||
consts.NormalsWorldToViewspaceMatrix = Matrix4x4.identity; |
|||
} |
|||
else |
|||
{ |
|||
consts.NormalsWorldToViewspaceMatrix = normalsToView; |
|||
} |
|||
|
|||
// used to get average load per pixel; 9.0 is there to compensate for only doing every 9th InterlockedAdd in PSPostprocessImportanceMapB for performance reasons
|
|||
consts.LoadCounterAvgDiv = 9.0f / (bufferSizeInfo.ImportanceMapWidth * bufferSizeInfo.ImportanceMapHeight * 255); |
|||
|
|||
float depthLinearizeMul = -proj.m32; // float depthLinearizeMul = ( clipFar * clipNear ) / ( clipFar - clipNear );
|
|||
float depthLinearizeAdd = proj.m22; // float depthLinearizeAdd = clipFar / ( clipFar - clipNear );
|
|||
// correct the handedness issue. need to make sure this below is correct, but I think it is.
|
|||
if (depthLinearizeMul * depthLinearizeAdd < 0) |
|||
depthLinearizeAdd = -depthLinearizeAdd; |
|||
|
|||
consts.DepthUnpackConsts.x = depthLinearizeMul; |
|||
consts.DepthUnpackConsts.y = depthLinearizeAdd; |
|||
|
|||
float tanHalfFovY = 1.0f / proj.m11; // = tanf( drawContext.Camera.GetYFOV( ) * 0.5f );
|
|||
float tanHalfFovX = 1.0f / proj.m00; // = tanHalfFovY * drawContext.Camera.GetAspect( );
|
|||
consts.CameraTanHalfFOV.x = tanHalfFovX; |
|||
consts.CameraTanHalfFOV.y = tanHalfFovY; |
|||
|
|||
consts.NDCToViewMul.x = consts.CameraTanHalfFOV.x * 2.0f; |
|||
consts.NDCToViewMul.y = consts.CameraTanHalfFOV.y * -2.0f; |
|||
consts.NDCToViewAdd.x = consts.CameraTanHalfFOV.x * -1.0f; |
|||
consts.NDCToViewAdd.y = consts.CameraTanHalfFOV.y * 1.0f; |
|||
|
|||
float ratio = (float)bufferSizeInfo.InputOutputBufferWidth / bufferSizeInfo.DepthBufferWidth; |
|||
float border = (1.0f - ratio) / 2.0f; |
|||
for (int i = 0; i < 2; ++i) |
|||
{ |
|||
consts.DepthBufferUVToViewMul[i] = consts.NDCToViewMul[i] / ratio; |
|||
consts.DepthBufferUVToViewAdd[i] = consts.NDCToViewAdd[i] - consts.NDCToViewMul[i] * border / ratio; |
|||
} |
|||
|
|||
consts.EffectRadius = Mathf.Clamp(settings.radius, 0.0f, 100000.0f); |
|||
consts.EffectShadowStrength = Mathf.Clamp(settings.shadowMultiplier * 4.3f, 0.0f, 10.0f); |
|||
consts.EffectShadowPow = Mathf.Clamp(settings.shadowPower, 0.0f, 10.0f); |
|||
consts.EffectShadowClamp = Mathf.Clamp(settings.shadowClamp, 0.0f, 1.0f); |
|||
consts.EffectFadeOutMul = -1.0f / (settings.fadeOutTo - settings.fadeOutFrom); |
|||
consts.EffectFadeOutAdd = settings.fadeOutFrom / (settings.fadeOutTo - settings.fadeOutFrom) + 1.0f; |
|||
consts.EffectHorizonAngleThreshold = Mathf.Clamp(settings.horizonAngleThreshold, 0.0f, 1.0f); |
|||
|
|||
// 1.2 seems to be around the best trade off - 1.0 means on-screen radius will stop/slow growing when the camera is at 1.0 distance, so, depending on FOV, basically filling up most of the screen
|
|||
// This setting is viewspace-dependent and not screen size dependent intentionally, so that when you change FOV the effect stays (relatively) similar.
|
|||
float effectSamplingRadiusNearLimit = settings.radius * 1.2f; |
|||
|
|||
// if the depth precision is switched to 32bit float, this can be set to something closer to 1 (0.9999 is fine)
|
|||
consts.DepthPrecisionOffsetMod = 0.9992f; |
|||
|
|||
// Special settings for lowest quality level - just nerf the effect a tiny bit
|
|||
if (settings.qualityLevel <= Cacao.Quality.Low) |
|||
{ |
|||
//consts.EffectShadowStrength *= 0.9f;
|
|||
effectSamplingRadiusNearLimit *= 1.50f; |
|||
|
|||
if (settings.qualityLevel == Cacao.Quality.Lowest) |
|||
consts.EffectRadius *= 0.8f; |
|||
} |
|||
|
|||
effectSamplingRadiusNearLimit /= tanHalfFovY; // to keep the effect same regardless of FOV
|
|||
|
|||
consts.EffectSamplingRadiusNearLimitRec = 1.0f / effectSamplingRadiusNearLimit; |
|||
consts.AdaptiveSampleCountLimit = settings.adaptiveQualityLimit; |
|||
consts.NegRecEffectRadius = -1.0f / consts.EffectRadius; |
|||
consts.InvSharpness = Mathf.Clamp01(1.0f - settings.sharpness); |
|||
consts.DetailAOStrength = settings.detailShadowStrength; |
|||
|
|||
// set buffer size constants.
|
|||
consts.SSAOBufferDimensions = new Vector2(bufferSizeInfo.SsaoBufferWidth, bufferSizeInfo.SsaoBufferHeight); |
|||
consts.SSAOBufferInverseDimensions = new Vector2(1.0f / bufferSizeInfo.SsaoBufferWidth, 1.0f / bufferSizeInfo.SsaoBufferHeight); |
|||
|
|||
consts.DepthBufferDimensions = new Vector2(bufferSizeInfo.DepthBufferWidth, bufferSizeInfo.DepthBufferHeight); |
|||
consts.DepthBufferInverseDimensions = new Vector2(1.0f / bufferSizeInfo.DepthBufferWidth, 1.0f / bufferSizeInfo.DepthBufferHeight); |
|||
|
|||
consts.DepthBufferOffset = new Vector2Int((int)bufferSizeInfo.DepthBufferXOffset, (int)bufferSizeInfo.DepthBufferYOffset); |
|||
|
|||
consts.InputOutputBufferDimensions = new Vector2(bufferSizeInfo.InputOutputBufferWidth, bufferSizeInfo.InputOutputBufferHeight); |
|||
consts.InputOutputBufferInverseDimensions = new Vector2(1.0f / bufferSizeInfo.InputOutputBufferWidth, 1.0f / bufferSizeInfo.InputOutputBufferHeight); |
|||
|
|||
consts.ImportanceMapDimensions = new Vector2(bufferSizeInfo.ImportanceMapWidth, bufferSizeInfo.ImportanceMapHeight); |
|||
consts.ImportanceMapInverseDimensions = new Vector2(1.0f / bufferSizeInfo.ImportanceMapWidth, 1.0f / bufferSizeInfo.ImportanceMapHeight); |
|||
|
|||
consts.DeinterleavedDepthBufferDimensions = new Vector2(bufferSizeInfo.DeinterleavedDepthBufferWidth, bufferSizeInfo.DeinterleavedDepthBufferHeight); |
|||
consts.DeinterleavedDepthBufferInverseDimensions = new Vector2(1.0f / bufferSizeInfo.DeinterleavedDepthBufferWidth, 1.0f / bufferSizeInfo.DeinterleavedDepthBufferHeight); |
|||
|
|||
consts.DeinterleavedDepthBufferOffset = new Vector2(bufferSizeInfo.DeinterleavedDepthBufferXOffset, bufferSizeInfo.DeinterleavedDepthBufferYOffset); |
|||
consts.DeinterleavedDepthBufferNormalisedOffset = consts.DeinterleavedDepthBufferOffset / consts.DeinterleavedDepthBufferDimensions; |
|||
|
|||
if (!settings.generateNormals) |
|||
{ |
|||
consts.NormalsUnpackMul = 2.0f; // inputs->NormalsUnpackMul;
|
|||
consts.NormalsUnpackAdd = -1.0f; // inputs->NormalsUnpackAdd;
|
|||
} |
|||
else |
|||
{ |
|||
consts.NormalsUnpackMul = 2.0f; |
|||
consts.NormalsUnpackAdd = -1.0f; |
|||
} |
|||
|
|||
consts.BlurNumPasses = settings.qualityLevel == Cacao.Quality.Lowest ? 2 : 4; |
|||
|
|||
float additionalAngleOffset = settings.temporalSupersamplingAngleOffset; // if using temporal supersampling approach (like "Progressive Rendering Using Multi-frame Sampling" from GPU Pro 7, etc.)
|
|||
float additionalRadiusScale = settings.temporalSupersamplingRadiusOffset; // if using temporal supersampling approach (like "Progressive Rendering Using Multi-frame Sampling" from GPU Pro 7, etc.)
|
|||
|
|||
for (int passId = 0; passId < 4; ++passId) |
|||
{ |
|||
ref Vector4 perPassFullResUVOffset = ref consts.GetPerPassFullResUVOffset(passId); |
|||
perPassFullResUVOffset.x = (float)(passId % 2) / bufferSizeInfo.SsaoBufferWidth; |
|||
perPassFullResUVOffset.y = (float)(passId / 2) / bufferSizeInfo.SsaoBufferHeight; |
|||
perPassFullResUVOffset.z = 0; |
|||
perPassFullResUVOffset.w = 0; |
|||
|
|||
ref Cacao.PatternRotScaleMatrices patternRotScaleMatrices = ref consts.GetPatternRotScaleMatrices(passId); |
|||
const int subPassCount = 5; |
|||
for (int subPass = 0; subPass < subPassCount; subPass++) |
|||
{ |
|||
int a = passId; |
|||
int b = SpMap[subPass]; |
|||
|
|||
float angle0 = (a + (float)b / subPassCount) * Mathf.PI * 0.5f; |
|||
float ca = Mathf.Cos(angle0); |
|||
float sa = Mathf.Sin(angle0); |
|||
|
|||
float scale = 1.0f + (a - 1.5f + (b - (subPassCount - 1.0f) * 0.5f) / subPassCount) * 0.07f; |
|||
|
|||
ref Vector4 patternRotScaleMatrix = ref patternRotScaleMatrices.GetPatternRotScaleMatrix(subPass); |
|||
patternRotScaleMatrix.x = scale * ca; |
|||
patternRotScaleMatrix.y = scale * -sa; |
|||
patternRotScaleMatrix.z = -scale * sa; |
|||
patternRotScaleMatrix.w = -scale * ca; |
|||
} |
|||
} |
|||
} |
|||
|
|||
private static readonly int[] SpMap = { 0, 1, 4, 3, 2 }; |
|||
|
|||
private static ComputeBuffer CreateConstantBuffer<TConstants>(string name) where TConstants: struct |
|||
{ |
|||
return new ComputeBuffer(1, Marshal.SizeOf<TConstants>(), ComputeBufferType.Constant) { name = name }; |
|||
} |
|||
|
|||
private static void DestroyConstantBuffer(ref ComputeBuffer bufferRef) |
|||
{ |
|||
if (bufferRef == null) |
|||
return; |
|||
|
|||
bufferRef.Release(); |
|||
bufferRef = null; |
|||
} |
|||
|
|||
private static void DestroyPass<TPass>(ref TPass pass) |
|||
where TPass: CacaoPass |
|||
{ |
|||
if (pass == null) |
|||
return; |
|||
|
|||
pass.Dispose(); |
|||
pass = null; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 6791d724b552593419500329cff7cb65 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,426 @@ |
|||
using System; |
|||
using System.Runtime.InteropServices; |
|||
using UnityEngine; |
|||
using UnityEngine.Rendering; |
|||
|
|||
namespace FidelityFX |
|||
{ |
|||
internal abstract class CacaoPass: IDisposable |
|||
{ |
|||
protected readonly CacaoResources Resources; |
|||
|
|||
protected ComputeShader ComputeShader; |
|||
protected int[] KernelIndices; |
|||
|
|||
protected CacaoPass(CacaoResources resources) |
|||
{ |
|||
Resources = resources; |
|||
} |
|||
|
|||
protected void InitComputeShaders<TKernel>(string passName, ComputeShader shader) |
|||
where TKernel: Enum |
|||
{ |
|||
if (shader == null) |
|||
{ |
|||
throw new MissingReferenceException($"Shader for FSR3 Upscaler '{passName}' could not be loaded! Please ensure it is included in the project correctly."); |
|||
} |
|||
|
|||
ComputeShader = shader; |
|||
|
|||
var kernelNames = Enum.GetNames(typeof(TKernel)); |
|||
KernelIndices = new int[kernelNames.Length]; |
|||
|
|||
for (int i = 0; i < kernelNames.Length; ++i) |
|||
{ |
|||
KernelIndices[i] = shader.FindKernel(kernelNames[i]); |
|||
} |
|||
} |
|||
|
|||
public void Dispose() |
|||
{ |
|||
} |
|||
|
|||
protected static int DispatchSize(uint tileSize, uint totalSize) |
|||
{ |
|||
return (int)((totalSize + tileSize - 1) / tileSize); |
|||
} |
|||
} |
|||
|
|||
internal class CacaoPrepareDepthsPass : CacaoPass |
|||
{ |
|||
private enum Kernels |
|||
{ |
|||
CS_Native, |
|||
CS_NativeHalf, |
|||
CS_NativeAndMips, |
|||
CS_Downsampled, |
|||
CS_DownsampledHalf, |
|||
CS_DownsampledAndMips, |
|||
} |
|||
|
|||
public CacaoPrepareDepthsPass(ComputeShader shader, CacaoResources resources) |
|||
: base(resources) |
|||
{ |
|||
InitComputeShaders<Kernels>("prepare_depths", shader); |
|||
} |
|||
|
|||
public void Execute(CommandBuffer commandBuffer, ComputeBuffer constants, in Cacao.DispatchInfo dispatchInfo, in Cacao.BufferSizeInfo bsi, Cacao.Quality quality, bool useDownsampledSsao) |
|||
{ |
|||
Kernels kernel; |
|||
int dispatchWidth, dispatchHeight; |
|||
|
|||
switch (quality) |
|||
{ |
|||
case Cacao.Quality.Lowest: |
|||
dispatchWidth = DispatchSize(CacaoConsts.PrepareDepthsHalfWidth, bsi.DeinterleavedDepthBufferWidth); |
|||
dispatchHeight = DispatchSize(CacaoConsts.PrepareDepthsHalfHeight, bsi.DeinterleavedDepthBufferHeight); |
|||
kernel = useDownsampledSsao ? Kernels.CS_DownsampledHalf : Kernels.CS_NativeHalf; |
|||
break; |
|||
case Cacao.Quality.Low: |
|||
dispatchWidth = DispatchSize(CacaoConsts.PrepareDepthsWidth, bsi.DeinterleavedDepthBufferWidth); |
|||
dispatchHeight = DispatchSize(CacaoConsts.PrepareDepthsHeight, bsi.DeinterleavedDepthBufferHeight); |
|||
kernel = useDownsampledSsao ? Kernels.CS_Downsampled : Kernels.CS_Native; |
|||
break; |
|||
default: |
|||
dispatchWidth = DispatchSize(CacaoConsts.PrepareDepthsAndMipsWidth, bsi.DeinterleavedDepthBufferWidth); |
|||
dispatchHeight = DispatchSize(CacaoConsts.PrepareDepthsAndMipsHeight, bsi.DeinterleavedDepthBufferHeight); |
|||
kernel = useDownsampledSsao ? Kernels.CS_DownsampledAndMips : Kernels.CS_NativeAndMips; |
|||
break; |
|||
} |
|||
|
|||
int kernelIndex = KernelIndices[(int)kernel]; |
|||
commandBuffer.SetComputeConstantBufferParam(ComputeShader, CacaoShaderIDs.CbSsaoConstantsBuffer, constants, 0, Marshal.SizeOf<Cacao.Constants>()); |
|||
|
|||
var depthView = dispatchInfo.DepthView; |
|||
commandBuffer.SetComputeTextureParam(ComputeShader, kernelIndex, CacaoShaderIDs.SrvDepthIn, depthView.RenderTarget, depthView.MipLevel, depthView.SubElement); |
|||
|
|||
commandBuffer.SetComputeTextureParam(ComputeShader, kernelIndex, CacaoShaderIDs.UavDeinterleavedDepth, Resources.DeinterleavedDepths); |
|||
commandBuffer.SetComputeTextureParam(ComputeShader, kernelIndex, CacaoShaderIDs.UavDownsampledDepthMip0, Resources.DeinterleavedDepths, 0); |
|||
commandBuffer.SetComputeTextureParam(ComputeShader, kernelIndex, CacaoShaderIDs.UavDownsampledDepthMip1, Resources.DeinterleavedDepths, 1); |
|||
commandBuffer.SetComputeTextureParam(ComputeShader, kernelIndex, CacaoShaderIDs.UavDownsampledDepthMip2, Resources.DeinterleavedDepths, 2); |
|||
commandBuffer.SetComputeTextureParam(ComputeShader, kernelIndex, CacaoShaderIDs.UavDownsampledDepthMip3, Resources.DeinterleavedDepths, 3); |
|||
|
|||
commandBuffer.DispatchCompute(ComputeShader, kernelIndex, dispatchWidth, dispatchHeight, 1); |
|||
} |
|||
} |
|||
|
|||
internal class CacaoPrepareNormalsPass : CacaoPass |
|||
{ |
|||
private enum Kernels |
|||
{ |
|||
CS_Native, |
|||
CS_NativeFromInputNormals, |
|||
CS_Downsampled, |
|||
CS_DownsampledFromInputNormals, |
|||
} |
|||
|
|||
public CacaoPrepareNormalsPass(ComputeShader shader, CacaoResources resources) |
|||
: base(resources) |
|||
{ |
|||
InitComputeShaders<Kernels>("prepare_normals", shader); |
|||
} |
|||
|
|||
public void Execute(CommandBuffer commandBuffer, ComputeBuffer constants, in Cacao.DispatchInfo dispatchInfo, in Cacao.BufferSizeInfo bsi, bool generateNormals, bool useDownsampledSsao) |
|||
{ |
|||
Kernels kernel; |
|||
int dispatchWidth, dispatchHeight; |
|||
|
|||
if (generateNormals) |
|||
{ |
|||
dispatchWidth = DispatchSize(CacaoConsts.PrepareNormalsWidth, bsi.SsaoBufferWidth); |
|||
dispatchHeight = DispatchSize(CacaoConsts.PrepareNormalsHeight, bsi.SsaoBufferHeight); |
|||
kernel = useDownsampledSsao ? Kernels.CS_Downsampled : Kernels.CS_Native; |
|||
} |
|||
else |
|||
{ |
|||
dispatchWidth = DispatchSize(CacaoConsts.PrepareNormalsFromInputNormalsWidth, bsi.SsaoBufferWidth); |
|||
dispatchHeight = DispatchSize(CacaoConsts.PrepareNormalsFromInputNormalsHeight, bsi.SsaoBufferHeight); |
|||
kernel = useDownsampledSsao ? Kernels.CS_DownsampledFromInputNormals : Kernels.CS_NativeFromInputNormals; |
|||
} |
|||
|
|||
int kernelIndex = KernelIndices[(int)kernel]; |
|||
commandBuffer.SetComputeConstantBufferParam(ComputeShader, CacaoShaderIDs.CbSsaoConstantsBuffer, constants, 0, Marshal.SizeOf<Cacao.Constants>()); |
|||
|
|||
if (generateNormals) |
|||
{ |
|||
var depthView = dispatchInfo.DepthView; |
|||
commandBuffer.SetComputeTextureParam(ComputeShader, kernelIndex, CacaoShaderIDs.SrvDepthIn, depthView.RenderTarget, depthView.MipLevel, depthView.SubElement); |
|||
} |
|||
else if (dispatchInfo.NormalsView.HasValue) |
|||
{ |
|||
var normalsView = dispatchInfo.NormalsView.Value; |
|||
commandBuffer.SetComputeTextureParam(ComputeShader, kernelIndex, CacaoShaderIDs.SrvNormalIn, normalsView.RenderTarget, normalsView.MipLevel, normalsView.SubElement); |
|||
} |
|||
else |
|||
{ |
|||
commandBuffer.SetComputeTextureParam(ComputeShader, kernelIndex, CacaoShaderIDs.SrvNormalIn, (Texture)null); |
|||
} |
|||
|
|||
commandBuffer.SetComputeTextureParam(ComputeShader, kernelIndex, CacaoShaderIDs.UavDeinterleavedNormals, Resources.DeinterleavedNormals); |
|||
|
|||
commandBuffer.DispatchCompute(ComputeShader, kernelIndex, dispatchWidth, dispatchHeight, 1); |
|||
} |
|||
} |
|||
|
|||
internal class CacaoGenerateBaseSsaoPass : CacaoPass |
|||
{ |
|||
private enum Kernels |
|||
{ |
|||
CS_Q3Base |
|||
} |
|||
|
|||
public CacaoGenerateBaseSsaoPass(ComputeShader shader, CacaoResources resources) |
|||
: base(resources) |
|||
{ |
|||
InitComputeShaders<Kernels>("generate_base_ssao", shader); |
|||
} |
|||
|
|||
public void Execute(CommandBuffer commandBuffer, ComputeBuffer constants, in Cacao.BufferSizeInfo bsi) |
|||
{ |
|||
int kernelIndex = KernelIndices[(int)Kernels.CS_Q3Base]; |
|||
int dispatchWidth = DispatchSize(CacaoConsts.GenerateWidth, bsi.SsaoBufferWidth); |
|||
int dispatchHeight = DispatchSize(CacaoConsts.GenerateHeight, bsi.SsaoBufferHeight); |
|||
|
|||
commandBuffer.SetComputeConstantBufferParam(ComputeShader, CacaoShaderIDs.CbSsaoConstantsBuffer, constants, 0, Marshal.SizeOf<Cacao.Constants>()); |
|||
commandBuffer.SetComputeTextureParam(ComputeShader, kernelIndex, CacaoShaderIDs.SrvDeinterleavedDepth, Resources.DeinterleavedDepths); |
|||
commandBuffer.SetComputeTextureParam(ComputeShader, kernelIndex, CacaoShaderIDs.SrvDeinterleavedNormals, Resources.DeinterleavedNormals); |
|||
commandBuffer.SetComputeTextureParam(ComputeShader, kernelIndex, CacaoShaderIDs.UavSsaoBufferPing, Resources.SsaoBufferPong); // FFX_CACAO_UAV_SSAO_REMAP_TO_PONG
|
|||
|
|||
commandBuffer.DispatchCompute(ComputeShader, kernelIndex, dispatchWidth, dispatchHeight, 4); |
|||
} |
|||
} |
|||
|
|||
internal class CacaoGenerateImportanceMapPass : CacaoPass |
|||
{ |
|||
private enum Kernels |
|||
{ |
|||
CS_Generate, |
|||
CS_PostprocessA, |
|||
CS_PostprocessB, |
|||
} |
|||
|
|||
public CacaoGenerateImportanceMapPass(ComputeShader shader, CacaoResources resources) |
|||
: base(resources) |
|||
{ |
|||
InitComputeShaders<Kernels>("generate_importance_map", shader); |
|||
} |
|||
|
|||
public void Execute(CommandBuffer commandBuffer, ComputeBuffer constants, in Cacao.BufferSizeInfo bsi) |
|||
{ |
|||
int dispatchWidth = DispatchSize(CacaoConsts.ImportanceMapWidth, bsi.ImportanceMapWidth); |
|||
int dispatchHeight = DispatchSize(CacaoConsts.ImportanceMapHeight, bsi.ImportanceMapHeight); |
|||
|
|||
commandBuffer.SetComputeConstantBufferParam(ComputeShader, CacaoShaderIDs.CbSsaoConstantsBuffer, constants, 0, Marshal.SizeOf<Cacao.Constants>()); |
|||
|
|||
int kernelIndex = KernelIndices[(int)Kernels.CS_Generate]; |
|||
commandBuffer.SetComputeTextureParam(ComputeShader, kernelIndex, CacaoShaderIDs.SrvSsaoBufferPong, Resources.SsaoBufferPong); |
|||
commandBuffer.SetComputeTextureParam(ComputeShader, kernelIndex, CacaoShaderIDs.UavImportanceMap, Resources.ImportanceMap); |
|||
commandBuffer.DispatchCompute(ComputeShader, kernelIndex, dispatchWidth, dispatchHeight, 1); |
|||
|
|||
kernelIndex = KernelIndices[(int)Kernels.CS_PostprocessA]; |
|||
commandBuffer.SetComputeTextureParam(ComputeShader, kernelIndex, CacaoShaderIDs.SrvImportanceMap, Resources.ImportanceMap); |
|||
commandBuffer.SetComputeTextureParam(ComputeShader, kernelIndex, CacaoShaderIDs.UavImportanceMapPong, Resources.ImportanceMapPong); |
|||
commandBuffer.DispatchCompute(ComputeShader, kernelIndex, dispatchWidth, dispatchHeight, 1); |
|||
|
|||
kernelIndex = KernelIndices[(int)Kernels.CS_PostprocessB]; |
|||
commandBuffer.SetComputeTextureParam(ComputeShader, kernelIndex, CacaoShaderIDs.SrvImportanceMapPong, Resources.ImportanceMapPong); |
|||
commandBuffer.SetComputeTextureParam(ComputeShader, kernelIndex, CacaoShaderIDs.UavImportanceMap, Resources.ImportanceMap); |
|||
commandBuffer.SetComputeTextureParam(ComputeShader, kernelIndex, CacaoShaderIDs.UavLoadCounterBuffer, Resources.LoadCounter); |
|||
commandBuffer.DispatchCompute(ComputeShader, kernelIndex, dispatchWidth, dispatchHeight, 1); |
|||
} |
|||
} |
|||
|
|||
internal class CacaoGenerateSsaoPass : CacaoPass |
|||
{ |
|||
private enum Kernels |
|||
{ |
|||
CS_Q0, |
|||
CS_Q1, |
|||
CS_Q2, |
|||
CS_Q3, |
|||
} |
|||
|
|||
public CacaoGenerateSsaoPass(ComputeShader shader, CacaoResources resources) |
|||
: base(resources) |
|||
{ |
|||
InitComputeShaders<Kernels>("generate_ssao", shader); |
|||
} |
|||
|
|||
public void Execute(CommandBuffer commandBuffer, ComputeBuffer constants, in Cacao.BufferSizeInfo bsi, Cacao.Quality quality) |
|||
{ |
|||
int kernelIndex = KernelIndices[(int)Kernels.CS_Q0 + Math.Max(0, (int)quality - 1)]; |
|||
|
|||
int dispatchWidth, dispatchHeight, dispatchDepth; |
|||
switch (quality) |
|||
{ |
|||
case Cacao.Quality.Lowest: |
|||
case Cacao.Quality.Low: |
|||
case Cacao.Quality.Medium: |
|||
dispatchWidth = DispatchSize(CacaoConsts.GenerateSparseWidth, bsi.SsaoBufferWidth); |
|||
dispatchWidth = (dispatchWidth + 4) / 5; |
|||
dispatchHeight = DispatchSize(CacaoConsts.GenerateSparseHeight, bsi.SsaoBufferHeight); |
|||
dispatchDepth = 5; |
|||
break; |
|||
case Cacao.Quality.High: |
|||
case Cacao.Quality.Highest: |
|||
default: |
|||
dispatchWidth = DispatchSize(CacaoConsts.GenerateWidth, bsi.SsaoBufferWidth); |
|||
dispatchHeight = DispatchSize(CacaoConsts.GenerateHeight, bsi.SsaoBufferHeight); |
|||
dispatchDepth = 1; |
|||
break; |
|||
} |
|||
|
|||
dispatchDepth *= (quality == Cacao.Quality.Lowest) ? 2 : 4; // 2 layers for lowest, 4 for all others
|
|||
|
|||
commandBuffer.SetComputeConstantBufferParam(ComputeShader, CacaoShaderIDs.CbSsaoConstantsBuffer, constants, 0, Marshal.SizeOf<Cacao.Constants>()); |
|||
|
|||
if (quality == Cacao.Quality.Highest) |
|||
{ |
|||
// Use adaptive descriptor set
|
|||
commandBuffer.SetComputeTextureParam(ComputeShader, kernelIndex, CacaoShaderIDs.SrvLoadCounter, Resources.LoadCounter); |
|||
commandBuffer.SetComputeTextureParam(ComputeShader, kernelIndex, CacaoShaderIDs.SrvImportanceMap, Resources.ImportanceMap); |
|||
commandBuffer.SetComputeTextureParam(ComputeShader, kernelIndex, CacaoShaderIDs.SrvSsaoBufferPong, Resources.SsaoBufferPong); |
|||
} |
|||
|
|||
commandBuffer.SetComputeTextureParam(ComputeShader, kernelIndex, CacaoShaderIDs.SrvDeinterleavedDepth, Resources.DeinterleavedDepths); |
|||
commandBuffer.SetComputeTextureParam(ComputeShader, kernelIndex, CacaoShaderIDs.SrvDeinterleavedNormals, Resources.DeinterleavedNormals); |
|||
commandBuffer.SetComputeTextureParam(ComputeShader, kernelIndex, CacaoShaderIDs.UavSsaoBufferPing, Resources.SsaoBufferPing); |
|||
|
|||
commandBuffer.DispatchCompute(ComputeShader, kernelIndex, dispatchWidth, dispatchHeight, dispatchDepth); |
|||
} |
|||
} |
|||
|
|||
internal class CacaoEdgeSensitiveBlurPass : CacaoPass |
|||
{ |
|||
private enum Kernels |
|||
{ |
|||
CS_1Pass, |
|||
CS_2Pass, |
|||
CS_3Pass, |
|||
CS_4Pass, |
|||
CS_5Pass, |
|||
CS_6Pass, |
|||
CS_7Pass, |
|||
CS_8Pass, |
|||
} |
|||
|
|||
public CacaoEdgeSensitiveBlurPass(ComputeShader shader, CacaoResources resources) |
|||
: base(resources) |
|||
{ |
|||
InitComputeShaders<Kernels>("edge_sensitive_blur", shader); |
|||
} |
|||
|
|||
public void Execute(CommandBuffer commandBuffer, ComputeBuffer constants, in Cacao.BufferSizeInfo bsi, Cacao.Quality quality, uint blurPassCount) |
|||
{ |
|||
uint w = 4 * CacaoConsts.BlurWidth - 2 * blurPassCount; |
|||
uint h = 3 * CacaoConsts.BlurHeight - 2 * blurPassCount; |
|||
int dispatchWidth = DispatchSize(w, bsi.SsaoBufferWidth); |
|||
int dispatchHeight = DispatchSize(h, bsi.SsaoBufferHeight); |
|||
int dispatchDepth = (quality == Cacao.Quality.Lowest) ? 2 : 4; |
|||
|
|||
int kernelIndex = KernelIndices[(int)Kernels.CS_1Pass + blurPassCount - 1]; |
|||
|
|||
commandBuffer.SetComputeConstantBufferParam(ComputeShader, CacaoShaderIDs.CbSsaoConstantsBuffer, constants, 0, Marshal.SizeOf<Cacao.Constants>()); |
|||
commandBuffer.SetComputeTextureParam(ComputeShader, kernelIndex, CacaoShaderIDs.SrvSsaoBufferPing, Resources.SsaoBufferPing); |
|||
commandBuffer.SetComputeTextureParam(ComputeShader, kernelIndex, CacaoShaderIDs.UavSsaoBufferPong, Resources.SsaoBufferPong); |
|||
|
|||
commandBuffer.DispatchCompute(ComputeShader, kernelIndex, dispatchWidth, dispatchHeight, dispatchDepth); |
|||
} |
|||
} |
|||
|
|||
internal class CacaoBilateralUpscalePass : CacaoPass |
|||
{ |
|||
private enum Kernels |
|||
{ |
|||
CS_5x5Smart, |
|||
CS_5x5NonSmart, |
|||
CS_5x5Half, |
|||
} |
|||
|
|||
public CacaoBilateralUpscalePass(ComputeShader shader, CacaoResources resources) |
|||
: base(resources) |
|||
{ |
|||
InitComputeShaders<Kernels>("bilateral_upscale", shader); |
|||
} |
|||
|
|||
public void Execute(CommandBuffer commandBuffer, ComputeBuffer constants, in Cacao.DispatchInfo dispatchInfo, in Cacao.BufferSizeInfo bsi, Cacao.Quality quality, bool usedBlur) |
|||
{ |
|||
Kernels kernel; |
|||
switch (quality) |
|||
{ |
|||
case Cacao.Quality.Lowest: |
|||
kernel = Kernels.CS_5x5Half; |
|||
break; |
|||
case Cacao.Quality.Low: |
|||
case Cacao.Quality.Medium: |
|||
kernel = Kernels.CS_5x5NonSmart; |
|||
break; |
|||
case Cacao.Quality.High: |
|||
case Cacao.Quality.Highest: |
|||
default: |
|||
kernel = Kernels.CS_5x5Smart; |
|||
break; |
|||
} |
|||
|
|||
int kernelIndex = KernelIndices[(int)kernel]; |
|||
int dispatchWidth = DispatchSize(2 * CacaoConsts.BilateralUpscaleWidth, bsi.InputOutputBufferWidth); |
|||
int dispatchHeight = DispatchSize(2 * CacaoConsts.BilateralUpscaleHeight, bsi.InputOutputBufferHeight); |
|||
|
|||
commandBuffer.SetComputeConstantBufferParam(ComputeShader, CacaoShaderIDs.CbSsaoConstantsBuffer, constants, 0, Marshal.SizeOf<Cacao.Constants>()); |
|||
commandBuffer.SetComputeTextureParam(ComputeShader, kernelIndex, CacaoShaderIDs.SrvSsaoBufferPing, usedBlur ? Resources.SsaoBufferPong : Resources.SsaoBufferPing); |
|||
commandBuffer.SetComputeTextureParam(ComputeShader, kernelIndex, CacaoShaderIDs.SrvDeinterleavedDepth, Resources.DeinterleavedDepths); |
|||
|
|||
var depthView = dispatchInfo.DepthView; |
|||
var outputView = dispatchInfo.OutputView; |
|||
commandBuffer.SetComputeTextureParam(ComputeShader, kernelIndex, CacaoShaderIDs.SrvDepthIn, depthView.RenderTarget, depthView.MipLevel, depthView.SubElement); |
|||
commandBuffer.SetComputeTextureParam(ComputeShader, kernelIndex, CacaoShaderIDs.UavOutput, outputView.RenderTarget, outputView.MipLevel, outputView.SubElement); |
|||
|
|||
commandBuffer.DispatchCompute(ComputeShader, kernelIndex, dispatchWidth, dispatchHeight, 1); |
|||
} |
|||
} |
|||
|
|||
internal class CacaoReinterleavePass : CacaoPass |
|||
{ |
|||
private enum Kernels |
|||
{ |
|||
CS_Smart, |
|||
CS_NonSmart, |
|||
CS_NonSmartHalf, |
|||
} |
|||
|
|||
public CacaoReinterleavePass(ComputeShader shader, CacaoResources resources) |
|||
: base(resources) |
|||
{ |
|||
InitComputeShaders<Kernels>("reinterleave_apply", shader); |
|||
} |
|||
|
|||
public void Execute(CommandBuffer commandBuffer, ComputeBuffer constants, in Cacao.DispatchInfo dispatchInfo, in Cacao.BufferSizeInfo bsi, Cacao.Quality quality, bool usedBlur) |
|||
{ |
|||
Kernels kernel; |
|||
switch (quality) |
|||
{ |
|||
case Cacao.Quality.Lowest: |
|||
kernel = Kernels.CS_NonSmartHalf; |
|||
break; |
|||
case Cacao.Quality.Low: |
|||
kernel = Kernels.CS_NonSmart; |
|||
break; |
|||
default: |
|||
kernel = Kernels.CS_Smart; |
|||
break; |
|||
} |
|||
|
|||
int kernelIndex = KernelIndices[(int)kernel]; |
|||
int dispatchWidth = DispatchSize(CacaoConsts.ApplyWidth, bsi.InputOutputBufferWidth); |
|||
int dispatchHeight = DispatchSize(CacaoConsts.ApplyHeight, bsi.InputOutputBufferHeight); |
|||
|
|||
commandBuffer.SetComputeConstantBufferParam(ComputeShader, CacaoShaderIDs.CbSsaoConstantsBuffer, constants, 0, Marshal.SizeOf<Cacao.Constants>()); |
|||
commandBuffer.SetComputeTextureParam(ComputeShader, kernelIndex, CacaoShaderIDs.SrvSsaoBufferPing, usedBlur ? Resources.SsaoBufferPong : Resources.SsaoBufferPing); |
|||
|
|||
var outputView = dispatchInfo.OutputView; |
|||
commandBuffer.SetComputeTextureParam(ComputeShader, kernelIndex, CacaoShaderIDs.UavOutput, outputView.RenderTarget, outputView.MipLevel, outputView.SubElement); |
|||
|
|||
commandBuffer.DispatchCompute(ComputeShader, kernelIndex, dispatchWidth, dispatchHeight, 1); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 084306d2fca046742bfc5729ed34883d |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,150 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
|
|||
namespace FidelityFX |
|||
{ |
|||
[Serializable] |
|||
public class CacaoPreset |
|||
{ |
|||
public bool useDownsampledSSAO; |
|||
public Cacao.Settings settings = Cacao.DefaultSettings; |
|||
|
|||
public enum PresetName |
|||
{ |
|||
NativeAdaptiveQuality, |
|||
NativeHighQuality, |
|||
NativeMediumQuality, |
|||
NativeLowQuality, |
|||
NativeLowestQuality, |
|||
DownsampledAdaptiveQuality, |
|||
DownsampledHighQuality, |
|||
DownsampledMediumQuality, |
|||
DownsampledLowQuality, |
|||
DownsampledLowestQuality, |
|||
} |
|||
|
|||
public static readonly Dictionary<PresetName, CacaoPreset> Presets = new() |
|||
{ |
|||
[PresetName.NativeAdaptiveQuality] = new CacaoPreset |
|||
{ |
|||
useDownsampledSSAO = false, |
|||
settings = new() |
|||
{ |
|||
radius = 1.2f, |
|||
shadowMultiplier = 1.0f, |
|||
shadowPower = 1.5f, |
|||
shadowClamp = 0.98f, |
|||
horizonAngleThreshold = 0.06f, |
|||
fadeOutFrom = 20f, |
|||
fadeOutTo = 40f, |
|||
qualityLevel = Cacao.Quality.Highest, |
|||
adaptiveQualityLimit = 0.75f, |
|||
blurPassCount = 2, |
|||
sharpness = 0.98f, |
|||
temporalSupersamplingAngleOffset = 0f, |
|||
temporalSupersamplingRadiusOffset = 0f, |
|||
detailShadowStrength = 0.5f, |
|||
generateNormals = false, |
|||
bilateralSigmaSquared = 5f, |
|||
bilateralSimilarityDistanceSigma = 0.1f, |
|||
}, |
|||
}, |
|||
[PresetName.NativeHighQuality] = new CacaoPreset |
|||
{ |
|||
useDownsampledSSAO = false, |
|||
settings = new() |
|||
{ |
|||
radius = 1.2f, |
|||
shadowMultiplier = 1.0f, |
|||
shadowPower = 1.5f, |
|||
shadowClamp = 0.98f, |
|||
horizonAngleThreshold = 0.06f, |
|||
fadeOutFrom = 20f, |
|||
fadeOutTo = 40f, |
|||
qualityLevel = Cacao.Quality.High, |
|||
adaptiveQualityLimit = 0.75f, |
|||
blurPassCount = 2, |
|||
sharpness = 0.98f, |
|||
temporalSupersamplingAngleOffset = 0f, |
|||
temporalSupersamplingRadiusOffset = 0f, |
|||
detailShadowStrength = 0.5f, |
|||
generateNormals = false, |
|||
bilateralSigmaSquared = 5f, |
|||
bilateralSimilarityDistanceSigma = 0.1f, |
|||
}, |
|||
}, |
|||
[PresetName.NativeMediumQuality] = new CacaoPreset |
|||
{ |
|||
useDownsampledSSAO = false, |
|||
settings = new() |
|||
{ |
|||
radius = 1.2f, |
|||
shadowMultiplier = 1.0f, |
|||
shadowPower = 1.5f, |
|||
shadowClamp = 0.98f, |
|||
horizonAngleThreshold = 0.06f, |
|||
fadeOutFrom = 20f, |
|||
fadeOutTo = 40f, |
|||
qualityLevel = Cacao.Quality.Medium, |
|||
adaptiveQualityLimit = 0.75f, |
|||
blurPassCount = 2, |
|||
sharpness = 0.98f, |
|||
temporalSupersamplingAngleOffset = 0f, |
|||
temporalSupersamplingRadiusOffset = 0f, |
|||
detailShadowStrength = 0.5f, |
|||
generateNormals = false, |
|||
bilateralSigmaSquared = 5f, |
|||
bilateralSimilarityDistanceSigma = 0.1f, |
|||
}, |
|||
}, |
|||
[PresetName.NativeLowQuality] = new CacaoPreset |
|||
{ |
|||
useDownsampledSSAO = false, |
|||
settings = new() |
|||
{ |
|||
radius = 1.2f, |
|||
shadowMultiplier = 1.0f, |
|||
shadowPower = 1.5f, |
|||
shadowClamp = 0.98f, |
|||
horizonAngleThreshold = 0.06f, |
|||
fadeOutFrom = 20f, |
|||
fadeOutTo = 40f, |
|||
qualityLevel = Cacao.Quality.Low, |
|||
adaptiveQualityLimit = 0.75f, |
|||
blurPassCount = 6, |
|||
sharpness = 0.98f, |
|||
temporalSupersamplingAngleOffset = 0f, |
|||
temporalSupersamplingRadiusOffset = 0f, |
|||
detailShadowStrength = 0.5f, |
|||
generateNormals = false, |
|||
bilateralSigmaSquared = 5f, |
|||
bilateralSimilarityDistanceSigma = 0.1f, |
|||
}, |
|||
}, |
|||
[PresetName.NativeLowestQuality] = new CacaoPreset |
|||
{ |
|||
useDownsampledSSAO = false, |
|||
settings = new() |
|||
{ |
|||
radius = 1.2f, |
|||
shadowMultiplier = 1.0f, |
|||
shadowPower = 1.5f, |
|||
shadowClamp = 0.98f, |
|||
horizonAngleThreshold = 0.06f, |
|||
fadeOutFrom = 20f, |
|||
fadeOutTo = 40f, |
|||
qualityLevel = Cacao.Quality.Lowest, |
|||
adaptiveQualityLimit = 0.75f, |
|||
blurPassCount = 6, |
|||
sharpness = 0.98f, |
|||
temporalSupersamplingAngleOffset = 0f, |
|||
temporalSupersamplingRadiusOffset = 0f, |
|||
detailShadowStrength = 0.5f, |
|||
generateNormals = false, |
|||
bilateralSigmaSquared = 5f, |
|||
bilateralSimilarityDistanceSigma = 0.1f, |
|||
}, |
|||
}, |
|||
}; |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 2773372d7a075424189e10b8ef40c198 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,97 @@ |
|||
using UnityEngine; |
|||
using UnityEngine.Experimental.Rendering; |
|||
using UnityEngine.Rendering; |
|||
|
|||
namespace FidelityFX |
|||
{ |
|||
internal class CacaoResources |
|||
{ |
|||
public RenderTexture LoadCounter; |
|||
|
|||
public RenderTexture DeinterleavedDepths; |
|||
public RenderTexture DeinterleavedNormals; |
|||
public RenderTexture SsaoBufferPing; |
|||
public RenderTexture SsaoBufferPong; |
|||
public RenderTexture ImportanceMap; |
|||
public RenderTexture ImportanceMapPong; |
|||
public RenderTexture DownsampledSsaoBuffer; |
|||
|
|||
public bool CreateLoadCounter() |
|||
{ |
|||
LoadCounter = new RenderTexture(1, 1, 0, GraphicsFormat.R32_UInt) { name = "FFX_CACAO_LOAD_COUNTER", enableRandomWrite = true }; |
|||
if (!LoadCounter.Create()) |
|||
{ |
|||
Debug.LogError("Failed to create load counter resource"); |
|||
return false; |
|||
} |
|||
|
|||
return true; |
|||
} |
|||
|
|||
public void DestroyLoadCounter() |
|||
{ |
|||
DestroyResource(ref LoadCounter); |
|||
} |
|||
|
|||
public bool CreateResources(in Cacao.BufferSizeInfo bsi) |
|||
{ |
|||
CreateArrayResource(out DeinterleavedDepths, "FFX_CACAO_DEINTERLEAVED_DEPTHS", bsi.DeinterleavedDepthBufferWidth, bsi.DeinterleavedDepthBufferHeight, GraphicsFormat.R16_SFloat, 4,4); |
|||
CreateArrayResource(out DeinterleavedNormals, "FFX_CACAO_DEINTERLEAVED_NORMALS", bsi.SsaoBufferWidth, bsi.SsaoBufferHeight, GraphicsFormat.R8G8B8A8_SNorm, 4); // TODO: does SNorm work?
|
|||
CreateArrayResource(out SsaoBufferPing, "FFX_CACAO_SSAO_BUFFER_PING", bsi.SsaoBufferWidth, bsi.SsaoBufferHeight, GraphicsFormat.R8G8_UNorm, 4); |
|||
CreateArrayResource(out SsaoBufferPong, "FFX_CACAO_SSAO_BUFFER_PONG", bsi.SsaoBufferWidth, bsi.SsaoBufferHeight, GraphicsFormat.R8G8_UNorm, 4); |
|||
|
|||
CreateResource(out ImportanceMap, "FFX_CACAO_IMPORTANCE_MAP", bsi.ImportanceMapWidth, bsi.ImportanceMapHeight, GraphicsFormat.R8_UNorm); |
|||
CreateResource(out ImportanceMapPong, "FFX_CACAO_IMPORTANCE_MAP_PONG", bsi.ImportanceMapWidth, bsi.ImportanceMapHeight, GraphicsFormat.R8_UNorm); |
|||
CreateResource(out DownsampledSsaoBuffer, "FFX_CACAO_DOWNSAMPLED_SSAO_BUFFER", bsi.DownsampledSsaoBufferWidth, bsi.DownsampledSsaoBufferHeight, GraphicsFormat.R8_UNorm); |
|||
|
|||
return true; |
|||
} |
|||
|
|||
public void DestroyResources() |
|||
{ |
|||
DestroyResource(ref DownsampledSsaoBuffer); |
|||
DestroyResource(ref ImportanceMapPong); |
|||
DestroyResource(ref ImportanceMap); |
|||
DestroyResource(ref SsaoBufferPong); |
|||
DestroyResource(ref SsaoBufferPing); |
|||
DestroyResource(ref DeinterleavedNormals); |
|||
DestroyResource(ref DeinterleavedDepths); |
|||
} |
|||
|
|||
private static bool CreateResource(out RenderTexture resource, string name, uint width, uint height, GraphicsFormat format) |
|||
{ |
|||
resource = new RenderTexture((int)width, (int)height, 0, format) { name = name, enableRandomWrite = true }; |
|||
return resource.Create(); |
|||
} |
|||
|
|||
private static bool CreateArrayResource(out RenderTexture resource, string name, uint width, uint height, GraphicsFormat format, int arraySize, int mipCount = 1) |
|||
{ |
|||
var desc = new RenderTextureDescriptor |
|||
{ |
|||
width = (int)width, |
|||
height = (int)height, |
|||
depthBufferBits = 0, |
|||
msaaSamples = 1, |
|||
graphicsFormat = format, |
|||
useMipMap = mipCount > 1, |
|||
mipCount = mipCount, |
|||
autoGenerateMips = false, |
|||
enableRandomWrite = true, |
|||
dimension = TextureDimension.Tex2DArray, |
|||
volumeDepth = arraySize, |
|||
}; |
|||
|
|||
resource = new RenderTexture(desc); |
|||
return resource.Create(); |
|||
} |
|||
|
|||
private static void DestroyResource(ref RenderTexture resource) |
|||
{ |
|||
if (resource == null) |
|||
return; |
|||
|
|||
resource.Release(); |
|||
resource = null; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 234fea833f9a4d04fb8625b7b1bfb652 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,35 @@ |
|||
using UnityEngine; |
|||
|
|||
namespace FidelityFX |
|||
{ |
|||
internal static class CacaoShaderIDs |
|||
{ |
|||
// Shader resource views, i.e. read-only bindings
|
|||
internal static readonly int SrvDepthIn = Shader.PropertyToID("g_DepthIn"); |
|||
internal static readonly int SrvNormalIn = Shader.PropertyToID("g_NormalIn"); |
|||
internal static readonly int SrvLoadCounter = Shader.PropertyToID("g_LoadCounter"); |
|||
internal static readonly int SrvDeinterleavedDepth = Shader.PropertyToID("g_DeinterleavedDepth"); |
|||
internal static readonly int SrvDeinterleavedNormals = Shader.PropertyToID("g_DeinterleavedNormals"); |
|||
internal static readonly int SrvSsaoBufferPing = Shader.PropertyToID("g_SsaoBufferPing"); |
|||
internal static readonly int SrvSsaoBufferPong = Shader.PropertyToID("g_SsaoBufferPong"); |
|||
internal static readonly int SrvImportanceMap = Shader.PropertyToID("g_ImportanceMap"); |
|||
internal static readonly int SrvImportanceMapPong = Shader.PropertyToID("g_ImportanceMapPong"); |
|||
|
|||
// Unordered access views, i.e. random read/write bindings
|
|||
internal static readonly int UavLoadCounterBuffer = Shader.PropertyToID("g_RwLoadCounter"); |
|||
internal static readonly int UavDeinterleavedDepth = Shader.PropertyToID("g_RwDeinterleavedDepth"); |
|||
internal static readonly int UavDeinterleavedNormals = Shader.PropertyToID("g_RwDeinterleavedNormals"); |
|||
internal static readonly int UavSsaoBufferPing = Shader.PropertyToID("g_RwSsaoBufferPing"); |
|||
internal static readonly int UavSsaoBufferPong = Shader.PropertyToID("g_RwSsaoBufferPong"); |
|||
internal static readonly int UavImportanceMap = Shader.PropertyToID("g_RwImportanceMap"); |
|||
internal static readonly int UavImportanceMapPong = Shader.PropertyToID("g_RwImportanceMapPong"); |
|||
internal static readonly int UavOutput = Shader.PropertyToID("g_RwOutput"); |
|||
internal static readonly int UavDownsampledDepthMip0 = Shader.PropertyToID("g_RwDepthMips0"); |
|||
internal static readonly int UavDownsampledDepthMip1 = Shader.PropertyToID("g_RwDepthMips1"); |
|||
internal static readonly int UavDownsampledDepthMip2 = Shader.PropertyToID("g_RwDepthMips2"); |
|||
internal static readonly int UavDownsampledDepthMip3 = Shader.PropertyToID("g_RwDepthMips3"); |
|||
|
|||
// Constant buffer bindings
|
|||
internal static readonly int CbSsaoConstantsBuffer = Shader.PropertyToID("SSAOConstantsBuffer"); |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 7e411954555b00944888a4e9b2db3ecf |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,97 @@ |
|||
using FidelityFX; |
|||
using UnityEngine.Experimental.Rendering; |
|||
using UnityEngine.Rendering.RenderGraphModule; |
|||
|
|||
namespace UnityEngine.Rendering.HighDefinition |
|||
{ |
|||
public partial class HDRenderPipeline |
|||
{ |
|||
private CacaoContext m_CacaoContext; |
|||
|
|||
class RenderCacaoParameters |
|||
{ |
|||
public bool runAsync; |
|||
|
|||
public Vector2Int resolution; |
|||
public bool downsample; |
|||
|
|||
public Cacao.Settings settings = Cacao.DefaultSettings; |
|||
|
|||
public Matrix4x4 projectionMatrix; |
|||
public Matrix4x4 cameraToWorldMatrix; |
|||
} |
|||
|
|||
class RenderCacaoPassData |
|||
{ |
|||
public TextureHandle depthBuffer; |
|||
public TextureHandle normalBuffer; |
|||
|
|||
public Matrix4x4 projectionMatrix; |
|||
public Matrix4x4 normalsToView; |
|||
|
|||
public TextureHandle aoOutput; |
|||
} |
|||
|
|||
TextureHandle RenderCacao(RenderGraph renderGraph, in RenderCacaoParameters parameters, TextureHandle depthBuffer, TextureHandle normalBuffer) |
|||
{ |
|||
if (m_CacaoContext == null) |
|||
{ |
|||
m_CacaoContext = new CacaoContext(); |
|||
m_CacaoContext.Init(new CacaoShaders |
|||
{ |
|||
prepareDepths = runtimeShaders.cacaoPrepareDepths, |
|||
prepareNormals = runtimeShaders.cacaoPrepareNormals, |
|||
generateImportanceMap = runtimeShaders.cacaoGenerateImportanceMap, |
|||
generateSsao = runtimeShaders.cacaoGenerateSsao, |
|||
edgeSensitiveBlur = runtimeShaders.cacaoEdgeSensitiveBlur, |
|||
bilateralUpscale = runtimeShaders.cacaoBilateralUpscale, |
|||
reinterleave = runtimeShaders.cacaoReinterleave, |
|||
}); |
|||
|
|||
m_CacaoContext.InitScreenSizeDependentResources(new Cacao.ScreenSizeInfo |
|||
{ |
|||
Width = (uint)parameters.resolution.x, |
|||
Height = (uint)parameters.resolution.y, |
|||
UseDownsampledSsao = parameters.downsample, |
|||
}); |
|||
} |
|||
|
|||
// TODO: init m_CacaoContext with data from parameters
|
|||
// TODO: detect changes in parameters and reinit m_CacaoContext if necessary
|
|||
m_CacaoContext.UpdateSettings(parameters.settings); |
|||
|
|||
using (var builder = renderGraph.AddRenderPass<RenderCacaoPassData>("FidelityFX CACAO", out var passData, ProfilingSampler.Get(HDProfileId.AmbientOcclusion))) |
|||
{ |
|||
builder.EnableAsyncCompute(parameters.runAsync); |
|||
|
|||
passData.aoOutput = builder.WriteTexture(renderGraph.CreateTexture(new TextureDesc(Vector2.one, true, true) |
|||
{ colorFormat = GraphicsFormat.R32_SFloat, enableRandomWrite = true, name = "CACAO Output" })); |
|||
|
|||
passData.depthBuffer = depthBuffer; |
|||
passData.normalBuffer = normalBuffer; |
|||
passData.projectionMatrix = parameters.projectionMatrix; |
|||
passData.normalsToView = parameters.cameraToWorldMatrix * Cacao.UnityToCacaoViewMatrix; |
|||
|
|||
builder.SetRenderFunc((RenderCacaoPassData data, RenderGraphContext ctx) => |
|||
{ |
|||
var dispatchInfo = new Cacao.DispatchInfo |
|||
{ |
|||
DepthView = new Cacao.ResourceView(data.depthBuffer), |
|||
NormalsView = new Cacao.ResourceView(data.normalBuffer), |
|||
OutputView = new Cacao.ResourceView(data.aoOutput), |
|||
}; |
|||
|
|||
ctx.cmd.SetGlobalTexture("_CameraDepthTexture", data.depthBuffer); |
|||
ctx.cmd.SetGlobalTexture("_NormalBufferTexture", data.normalBuffer); |
|||
ctx.cmd.SetGlobalTexture("_OcclusionTexture", data.aoOutput); |
|||
|
|||
m_CacaoContext.Draw(ctx.cmd, dispatchInfo, data.projectionMatrix, data.normalsToView); |
|||
}); |
|||
|
|||
return passData.aoOutput; |
|||
} |
|||
} |
|||
|
|||
// TODO: clean up CacaoContext in some kind of cleanup method (called from where?)
|
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
fileFormatVersion: 2 |
|||
guid: d5e7745c4aa6d764fa6d7562300ef26c |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,10 @@ |
|||
#pragma kernel CS_Smart |
|||
#pragma kernel CS_NonSmart |
|||
#pragma kernel CS_NonSmartHalf |
|||
|
|||
#define FFX_GPU // Compiling for GPU |
|||
#define FFX_HLSL // Compile for plain HLSL |
|||
|
|||
#include "ffx_cacao_common_hdrp.cginc" |
|||
|
|||
#include "shaders/ffx_cacao_apply_pass.hlsl" |
|||
@ -0,0 +1,7 @@ |
|||
fileFormatVersion: 2 |
|||
guid: ca1a8ef3a561f0c4fbe049ee8a6c928f |
|||
ComputeShaderImporter: |
|||
externalObjects: {} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,64 @@ |
|||
#pragma warning(disable: 3556) // Integer divides might be much slower, try using uints if possible. |
|||
#pragma warning(disable: 3205) // In the conversion from larger type to smaller, a loss of data might occur. |
|||
#pragma warning(disable: 3571) // pow(f, e) will not work for negative f, use abs(f) or conditionally handle negative values if you expect them. |
|||
|
|||
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl" |
|||
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl" |
|||
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/NormalBuffer.hlsl" |
|||
|
|||
#if defined(USE_TEXTURE2D_X_AS_ARRAY) |
|||
#define UV_TEXTURE2D_X(uv) float3(uv, SLICE_ARRAY_INDEX) |
|||
#define COORD_TEXTURE2D_X_LOD(coord, lod) uint4(coord, SLICE_ARRAY_INDEX, lod) |
|||
#else |
|||
#define UV_TEXTURE2D_X(uv) uv |
|||
#define COORD_TEXTURE2D_X_LOD(coord, lod) uint3(coord, lod) |
|||
#endif |
|||
|
|||
float4 FFX_CACAO_Prepare_SampleDepthOffsets(float2 uv) |
|||
{ |
|||
float4 samples; |
|||
samples.x = _CameraDepthTexture.SampleLevel(s_point_clamp_sampler, UV_TEXTURE2D_X(uv), 0.0f, int2(0, 2)).r; |
|||
samples.y = _CameraDepthTexture.SampleLevel(s_point_clamp_sampler, UV_TEXTURE2D_X(uv), 0.0f, int2(2, 2)).r; |
|||
samples.z = _CameraDepthTexture.SampleLevel(s_point_clamp_sampler, UV_TEXTURE2D_X(uv), 0.0f, int2(2, 0)).r; |
|||
samples.w = _CameraDepthTexture.SampleLevel(s_point_clamp_sampler, UV_TEXTURE2D_X(uv), 0.0f, int2(0, 0)).r; |
|||
return samples; |
|||
} |
|||
|
|||
float4 FFX_CACAO_Prepare_GatherDepth(float2 uv) |
|||
{ |
|||
return _CameraDepthTexture.GatherRed(s_point_clamp_sampler, UV_TEXTURE2D_X(uv)); |
|||
} |
|||
|
|||
float FFX_CACAO_Prepare_LoadDepth(int2 coord) |
|||
{ |
|||
return _CameraDepthTexture.Load(COORD_TEXTURE2D_X_LOD(coord, 0)).r; |
|||
} |
|||
|
|||
float FFX_CACAO_Prepare_LoadDepthOffset(int2 coord, int2 offset) |
|||
{ |
|||
return _CameraDepthTexture.Load(COORD_TEXTURE2D_X_LOD(coord, 0), offset).r; |
|||
} |
|||
|
|||
float4 FFX_CACAO_Prepare_GatherDepthOffset(float2 uv, int2 offset) |
|||
{ |
|||
return _CameraDepthTexture.GatherRed(s_point_clamp_sampler, UV_TEXTURE2D_X(uv), offset); |
|||
} |
|||
|
|||
float3 LoadSceneNormals(int2 coord) |
|||
{ |
|||
NormalData normalData; |
|||
DecodeFromNormalBuffer(coord, normalData); |
|||
return normalData.normalWS; |
|||
} |
|||
|
|||
RW_TEXTURE2D_X(float, _OcclusionTexture); |
|||
|
|||
void FFX_CACAO_Apply_StoreOutput(uint2 coord, float val) |
|||
{ |
|||
_OcclusionTexture[COORD_TEXTURE2D_X(coord)] = 1.0 - val; |
|||
} |
|||
|
|||
void FFX_CACAO_BilateralUpscale_StoreOutput(uint2 coord, int2 offset, float val) |
|||
{ |
|||
_OcclusionTexture[COORD_TEXTURE2D_X(coord + offset)] = 1.0 - val; |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
fileFormatVersion: 2 |
|||
guid: e44898a8b7f537549a295932f99b26d7 |
|||
ShaderIncludeImporter: |
|||
externalObjects: {} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,15 @@ |
|||
#pragma kernel CS_1Pass |
|||
#pragma kernel CS_2Pass |
|||
#pragma kernel CS_3Pass |
|||
#pragma kernel CS_4Pass |
|||
#pragma kernel CS_5Pass |
|||
#pragma kernel CS_6Pass |
|||
#pragma kernel CS_7Pass |
|||
#pragma kernel CS_8Pass |
|||
|
|||
#define FFX_GPU // Compiling for GPU |
|||
#define FFX_HLSL // Compile for plain HLSL |
|||
|
|||
#include "ffx_cacao_common_hdrp.cginc" |
|||
|
|||
#include "shaders/ffx_cacao_edge_sensitive_blur_pass.hlsl" |
|||
@ -0,0 +1,7 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 91d877c39234b33468a2e7a97e8e82b1 |
|||
ComputeShaderImporter: |
|||
externalObjects: {} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,10 @@ |
|||
#pragma kernel CS_Generate |
|||
#pragma kernel CS_PostprocessA |
|||
#pragma kernel CS_PostprocessB |
|||
|
|||
#define FFX_GPU // Compiling for GPU |
|||
#define FFX_HLSL // Compile for plain HLSL |
|||
|
|||
#include "ffx_cacao_common_hdrp.cginc" |
|||
|
|||
#include "shaders/ffx_cacao_generate_importance_map_pass.hlsl" |
|||
@ -0,0 +1,7 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 2eb39ae50536d594193fdce01d821088 |
|||
ComputeShaderImporter: |
|||
externalObjects: {} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,12 @@ |
|||
#pragma kernel CS_Q0 |
|||
#pragma kernel CS_Q1 |
|||
#pragma kernel CS_Q2 |
|||
#pragma kernel CS_Q3Base |
|||
#pragma kernel CS_Q3 |
|||
|
|||
#define FFX_GPU // Compiling for GPU |
|||
#define FFX_HLSL // Compile for plain HLSL |
|||
|
|||
#include "ffx_cacao_common_hdrp.cginc" |
|||
|
|||
#include "shaders/ffx_cacao_generate_pass.hlsl" |
|||
@ -0,0 +1,7 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 6129160ce7728b64b8f1c9304c5e7958 |
|||
ComputeShaderImporter: |
|||
externalObjects: {} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,13 @@ |
|||
#pragma kernel CS_Native |
|||
#pragma kernel CS_NativeHalf |
|||
#pragma kernel CS_NativeAndMips |
|||
#pragma kernel CS_Downsampled |
|||
#pragma kernel CS_DownsampledHalf |
|||
#pragma kernel CS_DownsampledAndMips |
|||
|
|||
#define FFX_GPU // Compiling for GPU |
|||
#define FFX_HLSL // Compile for plain HLSL |
|||
|
|||
#include "ffx_cacao_common_hdrp.cginc" |
|||
|
|||
#include "shaders/ffx_cacao_prepare_depths_pass.hlsl" |
|||
@ -0,0 +1,7 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 204c4d88f15fef241919acf114a5183f |
|||
ComputeShaderImporter: |
|||
externalObjects: {} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,11 @@ |
|||
#pragma kernel CS_Native |
|||
#pragma kernel CS_NativeFromInputNormals |
|||
#pragma kernel CS_Downsampled |
|||
#pragma kernel CS_DownsampledFromInputNormals |
|||
|
|||
#define FFX_GPU // Compiling for GPU |
|||
#define FFX_HLSL // Compile for plain HLSL |
|||
|
|||
#include "ffx_cacao_common_hdrp.cginc" |
|||
|
|||
#include "shaders/ffx_cacao_prepare_normals_pass.hlsl" |
|||
@ -0,0 +1,7 @@ |
|||
fileFormatVersion: 2 |
|||
guid: f4d3301f049082943a4d60e07219e551 |
|||
ComputeShaderImporter: |
|||
externalObjects: {} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,10 @@ |
|||
#pragma kernel CS_5x5Smart FFX_CACAO_OPTION_APPLY_SMART=1 |
|||
#pragma kernel CS_5x5NonSmart |
|||
#pragma kernel CS_5x5Half FFX_HALF=1 |
|||
|
|||
#define FFX_GPU // Compiling for GPU |
|||
#define FFX_HLSL // Compile for plain HLSL |
|||
|
|||
#include "ffx_cacao_common_hdrp.cginc" |
|||
|
|||
#include "shaders/ffx_cacao_upscale_bilateral_pass.hlsl" |
|||
@ -0,0 +1,7 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 332a934e3c79a0e44a374818c1f0f8ff |
|||
ComputeShaderImporter: |
|||
externalObjects: {} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,8 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 38a9164b0cfaeb74ab18b82bbe7de2d7 |
|||
folderAsset: yes |
|||
DefaultImporter: |
|||
externalObjects: {} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,8 @@ |
|||
fileFormatVersion: 2 |
|||
guid: cb957805ce989d64588a51d11e147a7d |
|||
folderAsset: yes |
|||
DefaultImporter: |
|||
externalObjects: {} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,105 @@ |
|||
// This file is part of the FidelityFX SDK. |
|||
// |
|||
// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved. |
|||
// |
|||
// 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. |
|||
|
|||
|
|||
#include "../common/ffx_core.h" |
|||
#include "ffx_cacao_defines.h" |
|||
#include "ffx_cacao_utils.h" |
|||
|
|||
void FFX_CACAO_Apply(FfxUInt32x2 coord) |
|||
{ |
|||
FfxFloat32 ao; |
|||
FfxFloat32x2 inPos = coord; |
|||
FfxUInt32x2 pixPos = coord; |
|||
FfxUInt32x2 pixPosHalf = pixPos / FfxUInt32x2(2, 2); |
|||
|
|||
// calculate index in the four deinterleaved source array texture |
|||
FfxInt32 mx = FfxInt32(pixPos.x % 2); |
|||
FfxInt32 my = FfxInt32(pixPos.y % 2); |
|||
FfxInt32 ic = mx + my * 2; // center index |
|||
FfxInt32 ih = (1 - mx) + my * 2; // neighbouring, horizontal |
|||
FfxInt32 iv = mx + (1 - my) * 2; // neighbouring, vertical |
|||
FfxInt32 id = (1 - mx) + (1 - my) * 2; // diagonal |
|||
|
|||
FfxFloat32x2 centerVal = FFX_CACAO_Apply_LoadSSAOPass(FfxInt32x2(pixPosHalf), ic); |
|||
|
|||
ao = centerVal.x; |
|||
|
|||
#if 1 // change to 0 if you want to disable last pass high-res blur (for debugging purposes, etc.) |
|||
FfxFloat32x4 edgesLRTB = FFX_CACAO_UnpackEdges(centerVal.y); |
|||
|
|||
// return 1.0 - FfxFloat32x4( edgesLRTB.x, edgesLRTB.y * 0.5 + edgesLRTB.w * 0.5, edgesLRTB.z, 0.0 ); // debug show edges |
|||
|
|||
// convert index shifts to sampling offsets |
|||
FfxFloat32 fmx = FfxFloat32(mx); |
|||
FfxFloat32 fmy = FfxFloat32(my); |
|||
|
|||
// in case of an edge, push sampling offsets away from the edge (towards pixel center) |
|||
FfxFloat32 fmxe = (edgesLRTB.y - edgesLRTB.x); |
|||
FfxFloat32 fmye = (edgesLRTB.w - edgesLRTB.z); |
|||
|
|||
// calculate final sampling offsets and sample using bilinear filter |
|||
FfxFloat32x2 uvH = (inPos.xy + FfxFloat32x2(fmx + fmxe - 0.5, 0.5 - fmy)) * 0.5 * SSAOBufferInverseDimensions(); |
|||
FfxFloat32 aoH = FFX_CACAO_Apply_SampleSSAOUVPass(uvH, ih); |
|||
FfxFloat32x2 uvV = (inPos.xy + FfxFloat32x2(0.5 - fmx, fmy - 0.5 + fmye)) * 0.5 * SSAOBufferInverseDimensions(); |
|||
FfxFloat32 aoV = FFX_CACAO_Apply_SampleSSAOUVPass(uvV, iv); |
|||
FfxFloat32x2 uvD = (inPos.xy + FfxFloat32x2(fmx - 0.5 + fmxe, fmy - 0.5 + fmye)) * 0.5 * SSAOBufferInverseDimensions(); |
|||
FfxFloat32 aoD = FFX_CACAO_Apply_SampleSSAOUVPass(uvD, id); |
|||
|
|||
// reduce weight for samples near edge - if the edge is on both sides, weight goes to 0 |
|||
FfxFloat32x4 blendWeights; |
|||
blendWeights.x = 1.0; |
|||
blendWeights.y = (edgesLRTB.x + edgesLRTB.y) * 0.5; |
|||
blendWeights.z = (edgesLRTB.z + edgesLRTB.w) * 0.5; |
|||
blendWeights.w = (blendWeights.y + blendWeights.z) * 0.5; |
|||
|
|||
// calculate weighted average |
|||
FfxFloat32 blendWeightsSum = dot(blendWeights, FfxFloat32x4(1.0, 1.0, 1.0, 1.0)); |
|||
ao = dot(FfxFloat32x4(ao, aoH, aoV, aoD), blendWeights) / blendWeightsSum; |
|||
#endif |
|||
ao.x = pow(ao.x, 2.2); |
|||
FFX_CACAO_Apply_StoreOutput(FfxInt32x2(coord), ao.x); |
|||
} |
|||
|
|||
|
|||
// edge-ignorant blur & apply (for the lowest quality level 0) |
|||
void FFX_CACAO_NonSmartApply(FfxUInt32x2 tid) |
|||
{ |
|||
FfxFloat32x2 inUV = FfxFloat32x2(tid) * OutputBufferInverseDimensions(); |
|||
FfxFloat32 a = FFX_CACAO_Apply_SampleSSAOUVPass(inUV.xy, 0); |
|||
FfxFloat32 b = FFX_CACAO_Apply_SampleSSAOUVPass(inUV.xy, 1); |
|||
FfxFloat32 c = FFX_CACAO_Apply_SampleSSAOUVPass(inUV.xy, 2); |
|||
FfxFloat32 d = FFX_CACAO_Apply_SampleSSAOUVPass(inUV.xy, 3); |
|||
FfxFloat32 avg = (a + b + c + d) * 0.25f; |
|||
|
|||
FFX_CACAO_Apply_StoreOutput(FfxInt32x2(tid), avg); |
|||
} |
|||
|
|||
// edge-ignorant blur & apply, skipping half pixels in checkerboard pattern (for the Lowest quality level 0 and Settings::SkipHalfPixelsOnLowQualityLevel == true ) |
|||
void FFX_CACAO_NonSmartHalfApply(FfxUInt32x2 tid) |
|||
{ |
|||
FfxFloat32x2 inUV = FfxFloat32x2(tid) * OutputBufferInverseDimensions(); |
|||
FfxFloat32 a = FFX_CACAO_Apply_SampleSSAOUVPass(inUV.xy, 0); |
|||
FfxFloat32 d = FFX_CACAO_Apply_SampleSSAOUVPass(inUV.xy, 3); |
|||
FfxFloat32 avg = (a + d) * 0.5f; |
|||
|
|||
FFX_CACAO_Apply_StoreOutput(FfxInt32x2(tid), avg); |
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
fileFormatVersion: 2 |
|||
guid: d4cb580ae5265ea49879b29db86477bb |
|||
PluginImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
iconMap: {} |
|||
executionOrder: {} |
|||
defineConstraints: [] |
|||
isPreloaded: 0 |
|||
isOverridable: 0 |
|||
isExplicitlyReferenced: 0 |
|||
validateReferences: 1 |
|||
platformData: |
|||
- first: |
|||
Any: |
|||
second: |
|||
enabled: 1 |
|||
settings: {} |
|||
- first: |
|||
Editor: Editor |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
DefaultValueInitialized: true |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,884 @@ |
|||
// This file is part of the FidelityFX SDK. |
|||
// |
|||
// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved. |
|||
// |
|||
// 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. |
|||
|
|||
|
|||
#include "ffx_cacao_resources.h" |
|||
|
|||
#if defined(FFX_GPU) |
|||
#ifdef __hlsl_dx_compiler |
|||
#pragma dxc diagnostic push |
|||
#pragma dxc diagnostic ignored "-Wambig-lit-shift" |
|||
#endif //__hlsl_dx_compiler |
|||
#include "../common/ffx_core.h" |
|||
#ifdef __hlsl_dx_compiler |
|||
#pragma dxc diagnostic pop |
|||
#endif //__hlsl_dx_compiler |
|||
#endif // #if defined(FFX_GPU) |
|||
|
|||
#if defined(FFX_GPU) |
|||
#ifndef FFX_PREFER_WAVE64 |
|||
#define FFX_PREFER_WAVE64 |
|||
#endif // #if defined(FFX_GPU) |
|||
|
|||
#if defined(FFX_GPU) |
|||
#pragma warning(disable: 3205) // conversion from larger type to smaller |
|||
#endif // #if defined(FFX_GPU) |
|||
|
|||
#define DECLARE_SRV_REGISTER(regIndex) t##regIndex |
|||
#define DECLARE_UAV_REGISTER(regIndex) u##regIndex |
|||
#define DECLARE_CB_REGISTER(regIndex) b##regIndex |
|||
#define FFX_CACAO_DECLARE_SRV(regIndex) register(DECLARE_SRV_REGISTER(regIndex)) |
|||
#define FFX_CACAO_DECLARE_UAV(regIndex) register(DECLARE_UAV_REGISTER(regIndex)) |
|||
#define FFX_CACAO_DECLARE_CB(regIndex) register(DECLARE_CB_REGISTER(regIndex)) |
|||
|
|||
#if defined(CACAO_BIND_CB_CACAO) |
|||
cbuffer SSAOConstantsBuffer : register(b0) |
|||
{ |
|||
FfxFloat32x2 g_FFX_CACAO_DepthUnpackConsts; |
|||
FfxFloat32x2 g_FFX_CACAO_CameraTanHalfFOV; |
|||
|
|||
FfxFloat32x2 g_FFX_CACAO_NDCToViewMul; |
|||
FfxFloat32x2 g_FFX_CACAO_NDCToViewAdd; |
|||
|
|||
FfxFloat32x2 g_FFX_CACAO_DepthBufferUVToViewMul; |
|||
FfxFloat32x2 g_FFX_CACAO_DepthBufferUVToViewAdd; |
|||
|
|||
FfxFloat32 g_FFX_CACAO_EffectRadius; // world (viewspace) maximum size of the shadow |
|||
FfxFloat32 g_FFX_CACAO_EffectShadowStrength; // global strength of the effect (0 - 5) |
|||
FfxFloat32 g_FFX_CACAO_EffectShadowPow; |
|||
FfxFloat32 g_FFX_CACAO_EffectShadowClamp; |
|||
|
|||
FfxFloat32 g_FFX_CACAO_EffectFadeOutMul; // effect fade out from distance (ex. 25) |
|||
FfxFloat32 g_FFX_CACAO_EffectFadeOutAdd; // effect fade out to distance (ex. 100) |
|||
FfxFloat32 g_FFX_CACAO_EffectHorizonAngleThreshold; // limit errors on slopes and caused by insufficient geometry tessellation (0.05 to 0.5) |
|||
FfxFloat32 g_FFX_CACAO_EffectSamplingRadiusNearLimitRec; // if viewspace pixel closer than this, don't enlarge shadow sampling radius anymore (makes no sense to grow beyond some distance, not enough samples to cover everything, so just limit the shadow growth; could be SSAOSettingsFadeOutFrom * 0.1 or less) |
|||
|
|||
FfxFloat32 g_FFX_CACAO_DepthPrecisionOffsetMod; |
|||
FfxFloat32 g_FFX_CACAO_NegRecEffectRadius; // -1.0 / EffectRadius |
|||
FfxFloat32 g_FFX_CACAO_LoadCounterAvgDiv; // 1.0 / ( halfDepthMip[SSAO_DEPTH_MIP_LEVELS-1].sizeX * halfDepthMip[SSAO_DEPTH_MIP_LEVELS-1].sizeY ) |
|||
FfxFloat32 g_FFX_CACAO_AdaptiveSampleCountLimit; |
|||
|
|||
FfxFloat32 g_FFX_CACAO_InvSharpness; |
|||
FfxInt32 g_FFX_CACAO_BlurNumPasses; |
|||
FfxFloat32 g_FFX_CACAO_BilateralSigmaSquared; |
|||
FfxFloat32 g_FFX_CACAO_BilateralSimilarityDistanceSigma; |
|||
|
|||
FfxFloat32x4 g_FFX_CACAO_PatternRotScaleMatrices[4][5]; |
|||
|
|||
FfxFloat32 g_FFX_CACAO_NormalsUnpackMul; |
|||
FfxFloat32 g_FFX_CACAO_NormalsUnpackAdd; |
|||
FfxFloat32 g_FFX_CACAO_DetailAOStrength; |
|||
FfxInt32 g_FFX_CACAO_Dummy0; |
|||
|
|||
FfxFloat32x2 g_FFX_CACAO_SSAOBufferDimensions; |
|||
FfxFloat32x2 g_FFX_CACAO_SSAOBufferInverseDimensions; |
|||
|
|||
FfxFloat32x2 g_FFX_CACAO_DepthBufferDimensions; |
|||
FfxFloat32x2 g_FFX_CACAO_DepthBufferInverseDimensions; |
|||
|
|||
FfxInt32x2 g_FFX_CACAO_DepthBufferOffset; |
|||
FfxInt32x2 g_FFX_CACAO_Pad; |
|||
|
|||
FfxFloat32x4 g_FFX_CACAO_PerPassFullResUVOffset[4]; |
|||
|
|||
FfxFloat32x2 g_FFX_CACAO_OutputBufferDimensions; |
|||
FfxFloat32x2 g_FFX_CACAO_OutputBufferInverseDimensions; |
|||
|
|||
FfxFloat32x2 g_FFX_CACAO_ImportanceMapDimensions; |
|||
FfxFloat32x2 g_FFX_CACAO_ImportanceMapInverseDimensions; |
|||
|
|||
FfxFloat32x2 g_FFX_CACAO_DeinterleavedDepthBufferDimensions; |
|||
FfxFloat32x2 g_FFX_CACAO_DeinterleavedDepthBufferInverseDimensions; |
|||
|
|||
FfxFloat32x2 g_FFX_CACAO_DeinterleavedDepthBufferOffset; |
|||
FfxFloat32x2 g_FFX_CACAO_DeinterleavedDepthBufferNormalisedOffset; |
|||
|
|||
float4x4 g_FFX_CACAO_NormalsWorldToViewspaceMatrix; |
|||
}; |
|||
|
|||
#define FFX_CACAO_CONSTANT_BUFFER_1_SIZE 172 // Number of 32-bit values. This must be kept in sync with max( cbRCAS , cbSPD) size. |
|||
#endif |
|||
|
|||
FfxFloat32x2 DepthUnpackConsts(){ |
|||
#if defined(CACAO_BIND_CB_CACAO) |
|||
return g_FFX_CACAO_DepthUnpackConsts; |
|||
#else |
|||
return 0; |
|||
#endif |
|||
} |
|||
FfxFloat32x2 CameraTanHalfFOV(){ |
|||
#if defined(CACAO_BIND_CB_CACAO) |
|||
return g_FFX_CACAO_CameraTanHalfFOV; |
|||
#else |
|||
return 0; |
|||
#endif |
|||
} |
|||
|
|||
FfxFloat32x2 NDCToViewMul(){ |
|||
#if defined(CACAO_BIND_CB_CACAO) |
|||
return g_FFX_CACAO_NDCToViewMul; |
|||
#else |
|||
return 0; |
|||
#endif |
|||
} |
|||
FfxFloat32x2 NDCToViewAdd(){ |
|||
#if defined(CACAO_BIND_CB_CACAO) |
|||
return g_FFX_CACAO_NDCToViewAdd; |
|||
#else |
|||
return 0; |
|||
#endif |
|||
} |
|||
|
|||
FfxFloat32x2 DepthBufferUVToViewMul(){ |
|||
#if defined(CACAO_BIND_CB_CACAO) |
|||
return g_FFX_CACAO_DepthBufferUVToViewMul; |
|||
#else |
|||
return 0; |
|||
#endif |
|||
} |
|||
FfxFloat32x2 DepthBufferUVToViewAdd(){ |
|||
#if defined(CACAO_BIND_CB_CACAO) |
|||
return g_FFX_CACAO_DepthBufferUVToViewAdd; |
|||
#else |
|||
return 0; |
|||
#endif |
|||
} |
|||
|
|||
FfxFloat32 EffectRadius(){ |
|||
#if defined(CACAO_BIND_CB_CACAO) |
|||
return g_FFX_CACAO_EffectRadius; |
|||
#else |
|||
return 0; |
|||
#endif |
|||
} |
|||
FfxFloat32 EffectShadowStrength(){ |
|||
#if defined(CACAO_BIND_CB_CACAO) |
|||
return g_FFX_CACAO_EffectShadowStrength; |
|||
#else |
|||
return 0; |
|||
#endif |
|||
} |
|||
FfxFloat32 EffectShadowPow(){ |
|||
#if defined(CACAO_BIND_CB_CACAO) |
|||
return g_FFX_CACAO_EffectShadowPow; |
|||
#else |
|||
return 0; |
|||
#endif |
|||
} |
|||
FfxFloat32 EffectShadowClamp(){ |
|||
#if defined(CACAO_BIND_CB_CACAO) |
|||
return g_FFX_CACAO_EffectShadowClamp; |
|||
#else |
|||
return 0; |
|||
#endif |
|||
} |
|||
|
|||
FfxFloat32 EffectFadeOutMul(){ |
|||
#if defined(CACAO_BIND_CB_CACAO) |
|||
return g_FFX_CACAO_EffectFadeOutMul; |
|||
#else |
|||
return 0; |
|||
#endif |
|||
} |
|||
FfxFloat32 EffectFadeOutAdd(){ |
|||
#if defined(CACAO_BIND_CB_CACAO) |
|||
return g_FFX_CACAO_EffectFadeOutAdd; |
|||
#else |
|||
return 0; |
|||
#endif |
|||
} |
|||
FfxFloat32 EffectHorizonAngleThreshold(){ |
|||
#if defined(CACAO_BIND_CB_CACAO) |
|||
return g_FFX_CACAO_EffectHorizonAngleThreshold; |
|||
#else |
|||
return 0; |
|||
#endif |
|||
} |
|||
FfxFloat32 EffectSamplingRadiusNearLimitRec(){ |
|||
#if defined(CACAO_BIND_CB_CACAO) |
|||
return g_FFX_CACAO_EffectSamplingRadiusNearLimitRec; |
|||
#else |
|||
return 0; |
|||
#endif |
|||
} |
|||
|
|||
FfxFloat32 DepthPrecisionOffsetMod(){ |
|||
#if defined(CACAO_BIND_CB_CACAO) |
|||
return g_FFX_CACAO_DepthPrecisionOffsetMod; |
|||
#else |
|||
return 0; |
|||
#endif |
|||
} |
|||
FfxFloat32 NegRecEffectRadius(){ |
|||
#if defined(CACAO_BIND_CB_CACAO) |
|||
return g_FFX_CACAO_NegRecEffectRadius; |
|||
#else |
|||
return 0; |
|||
#endif |
|||
} |
|||
FfxFloat32 LoadCounterAvgDiv(){ |
|||
#if defined(CACAO_BIND_CB_CACAO) |
|||
return g_FFX_CACAO_LoadCounterAvgDiv; |
|||
#else |
|||
return 0; |
|||
#endif |
|||
} |
|||
FfxFloat32 AdaptiveSampleCountLimit(){ |
|||
#if defined(CACAO_BIND_CB_CACAO) |
|||
return g_FFX_CACAO_AdaptiveSampleCountLimit; |
|||
#else |
|||
return 0; |
|||
#endif |
|||
} |
|||
|
|||
FfxFloat32 InvSharpness(){ |
|||
#if defined(CACAO_BIND_CB_CACAO) |
|||
return g_FFX_CACAO_InvSharpness; |
|||
#else |
|||
return 0; |
|||
#endif |
|||
} |
|||
FfxInt32 BlurNumPasses(){ |
|||
#if defined(CACAO_BIND_CB_CACAO) |
|||
return g_FFX_CACAO_BlurNumPasses; |
|||
#else |
|||
return 0; |
|||
#endif |
|||
} |
|||
FfxFloat32 BilateralSigmaSquared(){ |
|||
#if defined(CACAO_BIND_CB_CACAO) |
|||
return g_FFX_CACAO_BilateralSigmaSquared; |
|||
#else |
|||
return 0; |
|||
#endif |
|||
} |
|||
FfxFloat32 BilateralSimilarityDistanceSigma(){ |
|||
#if defined(CACAO_BIND_CB_CACAO) |
|||
return g_FFX_CACAO_BilateralSimilarityDistanceSigma; |
|||
#else |
|||
return 0; |
|||
#endif |
|||
} |
|||
|
|||
FfxFloat32x4 PatternRotScaleMatrices(uint i, uint j){ |
|||
#if defined(CACAO_BIND_CB_CACAO) |
|||
return g_FFX_CACAO_PatternRotScaleMatrices[i][j]; |
|||
#else |
|||
return 0; |
|||
#endif |
|||
} |
|||
|
|||
FfxFloat32 NormalsUnpackMul(){ |
|||
#if defined(CACAO_BIND_CB_CACAO) |
|||
return g_FFX_CACAO_NormalsUnpackMul; |
|||
#else |
|||
return 0; |
|||
#endif |
|||
} |
|||
FfxFloat32 NormalsUnpackAdd(){ |
|||
#if defined(CACAO_BIND_CB_CACAO) |
|||
return g_FFX_CACAO_NormalsUnpackAdd; |
|||
#else |
|||
return 0; |
|||
#endif |
|||
} |
|||
FfxFloat32 DetailAOStrength(){ |
|||
#if defined(CACAO_BIND_CB_CACAO) |
|||
return g_FFX_CACAO_DetailAOStrength; |
|||
#else |
|||
return 0; |
|||
#endif |
|||
} |
|||
FfxFloat32 Dummy0(){ |
|||
#if defined(CACAO_BIND_CB_CACAO) |
|||
return g_FFX_CACAO_Dummy0; |
|||
#else |
|||
return 0; |
|||
#endif |
|||
} |
|||
|
|||
FfxFloat32x2 SSAOBufferDimensions(){ |
|||
#if defined(CACAO_BIND_CB_CACAO) |
|||
return g_FFX_CACAO_SSAOBufferDimensions; |
|||
#else |
|||
return 0; |
|||
#endif |
|||
} |
|||
FfxFloat32x2 SSAOBufferInverseDimensions(){ |
|||
#if defined(CACAO_BIND_CB_CACAO) |
|||
return g_FFX_CACAO_SSAOBufferInverseDimensions; |
|||
#else |
|||
return 0; |
|||
#endif |
|||
} |
|||
|
|||
FfxFloat32x2 DepthBufferDimensions(){ |
|||
#if defined(CACAO_BIND_CB_CACAO) |
|||
return g_FFX_CACAO_DepthBufferDimensions; |
|||
#else |
|||
return 0; |
|||
#endif |
|||
} |
|||
FfxFloat32x2 DepthBufferInverseDimensions(){ |
|||
#if defined(CACAO_BIND_CB_CACAO) |
|||
return g_FFX_CACAO_DepthBufferInverseDimensions; |
|||
#else |
|||
return 0; |
|||
#endif |
|||
} |
|||
|
|||
FfxInt32x2 DepthBufferOffset(){ |
|||
#if defined(CACAO_BIND_CB_CACAO) |
|||
return g_FFX_CACAO_DepthBufferOffset; |
|||
#else |
|||
return 0; |
|||
#endif |
|||
} |
|||
FfxFloat32x4 PerPassFullResUVOffset(uint i){ |
|||
#if defined(CACAO_BIND_CB_CACAO) |
|||
return g_FFX_CACAO_PerPassFullResUVOffset[i]; |
|||
#else |
|||
return 0; |
|||
#endif |
|||
} |
|||
|
|||
FfxFloat32x2 OutputBufferDimensions(){ |
|||
#if defined(CACAO_BIND_CB_CACAO) |
|||
return g_FFX_CACAO_OutputBufferDimensions; |
|||
#else |
|||
return 0; |
|||
#endif |
|||
} |
|||
FfxFloat32x2 OutputBufferInverseDimensions(){ |
|||
#if defined(CACAO_BIND_CB_CACAO) |
|||
return g_FFX_CACAO_OutputBufferInverseDimensions; |
|||
#else |
|||
return 0; |
|||
#endif |
|||
} |
|||
|
|||
FfxFloat32x2 ImportanceMapDimensions(){ |
|||
#if defined(CACAO_BIND_CB_CACAO) |
|||
return g_FFX_CACAO_ImportanceMapDimensions; |
|||
#else |
|||
return 0; |
|||
#endif |
|||
} |
|||
FfxFloat32x2 ImportanceMapInverseDimensions(){ |
|||
#if defined(CACAO_BIND_CB_CACAO) |
|||
return g_FFX_CACAO_ImportanceMapInverseDimensions; |
|||
#else |
|||
return 0; |
|||
#endif |
|||
} |
|||
|
|||
FfxFloat32x2 DeinterleavedDepthBufferDimensions(){ |
|||
#if defined(CACAO_BIND_CB_CACAO) |
|||
return g_FFX_CACAO_DeinterleavedDepthBufferDimensions; |
|||
#else |
|||
return 0; |
|||
#endif |
|||
} |
|||
FfxFloat32x2 DeinterleavedDepthBufferInverseDimensions(){ |
|||
#if defined(CACAO_BIND_CB_CACAO) |
|||
return g_FFX_CACAO_DeinterleavedDepthBufferInverseDimensions; |
|||
#else |
|||
return 0; |
|||
#endif |
|||
} |
|||
|
|||
FfxFloat32x2 DeinterleavedDepthBufferOffset(){ |
|||
#if defined(CACAO_BIND_CB_CACAO) |
|||
return g_FFX_CACAO_DeinterleavedDepthBufferOffset; |
|||
#else |
|||
return 0; |
|||
#endif |
|||
} |
|||
FfxFloat32x2 DeinterleavedDepthBufferNormalisedOffset(){ |
|||
#if defined(CACAO_BIND_CB_CACAO) |
|||
return g_FFX_CACAO_DeinterleavedDepthBufferNormalisedOffset; |
|||
#else |
|||
return 0; |
|||
#endif |
|||
} |
|||
|
|||
float4x4 NormalsWorldToViewspaceMatrix(){ |
|||
#if defined(CACAO_BIND_CB_CACAO) |
|||
return g_FFX_CACAO_NormalsWorldToViewspaceMatrix; |
|||
#else |
|||
return 0; |
|||
#endif |
|||
} |
|||
|
|||
#if defined(FFX_GPU) |
|||
#define FFX_CACAO_ROOTSIG_STRINGIFY(p) FFX_CACAO_ROOTSIG_STR(p) |
|||
#define FFX_CACAO_ROOTSIG_STR(p) #p |
|||
#define FFX_CACAO_ROOTSIG [RootSignature( "DescriptorTable(UAV(u0, numDescriptors = " FFX_CACAO_ROOTSIG_STRINGIFY(FFX_CACAO_RESOURCE_IDENTIFIER_COUNT) ")), " \ |
|||
"DescriptorTable(SRV(t0, numDescriptors = " FFX_CACAO_ROOTSIG_STRINGIFY(FFX_CACAO_RESOURCE_IDENTIFIER_COUNT) ")), " \ |
|||
"RootConstants(num32BitConstants=" FFX_CACAO_ROOTSIG_STRINGIFY(FFX_CACAO_CONSTANT_BUFFER_1_SIZE) ", b0) ")] \ |
|||
|
|||
#define FFX_CACAO_CB2_ROOTSIG [RootSignature( "DescriptorTable(UAV(u0, numDescriptors = " FFX_CACAO_ROOTSIG_STRINGIFY(FFX_CACAO_RESOURCE_IDENTIFIER_COUNT) ")), " \ |
|||
"DescriptorTable(SRV(t0, numDescriptors = " FFX_CACAO_ROOTSIG_STRINGIFY(FFX_CACAO_RESOURCE_IDENTIFIER_COUNT) ")), " \ |
|||
"RootConstants(num32BitConstants=" FFX_CACAO_ROOTSIG_STRINGIFY(FFX_CACAO_CONSTANT_BUFFER_1_SIZE) ", b0), " \ |
|||
|
|||
#define FFX_CACAO_CB_GENERATE_REACTIVE_ROOTSIG [RootSignature( "DescriptorTable(UAV(u0, numDescriptors = " FFX_CACAO_ROOTSIG_STRINGIFY(FFX_CACAO_RESOURCE_IDENTIFIER_COUNT) ")), " \ |
|||
"DescriptorTable(SRV(t0, numDescriptors = " FFX_CACAO_ROOTSIG_STRINGIFY(FFX_CACAO_RESOURCE_IDENTIFIER_COUNT) ")), " \ |
|||
"RootConstants(num32BitConstants=" FFX_CACAO_ROOTSIG_STRINGIFY(FFX_CACAO_CONSTANT_BUFFER_1_SIZE) ", b0), " \ |
|||
"RootConstants(num32BitConstants=" FFX_CACAO_ROOTSIG_STRINGIFY(FFX_CACAO_CONSTANT_BUFFER_GENERATE_REACTIVE_SIZE) ", b1), ")] \ |
|||
|
|||
#if defined(FFX_CACAO_EMBED_ROOTSIG) |
|||
#define FFX_CACAO_EMBED_ROOTSIG_CONTENT FFX_CACAO_ROOTSIG |
|||
#define FFX_CACAO_EMBED_CB2_ROOTSIG_CONTENT FFX_CACAO_CB2_ROOTSIG |
|||
#define FFX_CACAO_EMBED_CB_GENERATE_REACTIVE_ROOTSIG_CONTENT FFX_CACAO_CB_GENERATE_REACTIVE_ROOTSIG |
|||
#else |
|||
#define FFX_CACAO_EMBED_ROOTSIG_CONTENT |
|||
#define FFX_CACAO_EMBED_CB2_ROOTSIG_CONTENT |
|||
#define FFX_CACAO_EMBED_CB_GENERATE_REACTIVE_ROOTSIG_CONTENT |
|||
#endif // #if FFX_CACAO_EMBED_ROOTSIG |
|||
#endif // #if defined(FFX_GPU) |
|||
|
|||
SamplerState g_PointClampSampler : register(s0); |
|||
SamplerState g_PointMirrorSampler : register(s1); |
|||
SamplerState g_LinearClampSampler : register(s2); |
|||
SamplerState g_ViewPointClampSampler : register(s3); |
|||
SamplerState g_RealPointClampSampler : register(s4); |
|||
|
|||
#if defined CACAO_BIND_SRV_DEPTH_IN |
|||
Texture2D<FfxFloat32> g_DepthIn : FFX_CACAO_DECLARE_SRV(CACAO_BIND_SRV_DEPTH_IN); |
|||
#endif |
|||
#if defined CACAO_BIND_SRV_NORMAL_IN |
|||
Texture2D<FfxFloat32x4> g_NormalIn : FFX_CACAO_DECLARE_SRV(CACAO_BIND_SRV_NORMAL_IN); |
|||
#endif |
|||
#if defined CACAO_BIND_SRV_LOAD_COUNTER |
|||
Texture1D<FfxUInt32> g_LoadCounter : FFX_CACAO_DECLARE_SRV(CACAO_BIND_SRV_LOAD_COUNTER); |
|||
#endif |
|||
#if defined CACAO_BIND_SRV_DEINTERLEAVED_DEPTHS |
|||
Texture2DArray<FfxFloat32> g_DeinterleavedDepth : FFX_CACAO_DECLARE_SRV(CACAO_BIND_SRV_DEINTERLEAVED_DEPTHS); |
|||
#endif |
|||
#if defined CACAO_BIND_SRV_DEINTERLEAVED_NORMALS |
|||
Texture2DArray<FfxFloat32x4> g_DeinterleavedNormals : FFX_CACAO_DECLARE_SRV(CACAO_BIND_SRV_DEINTERLEAVED_NORMALS); |
|||
#endif |
|||
#if defined CACAO_BIND_SRV_SSAO_BUFFER_PING |
|||
Texture2DArray<FfxFloat32x2> g_SsaoBufferPing : FFX_CACAO_DECLARE_SRV(CACAO_BIND_SRV_SSAO_BUFFER_PING); |
|||
#endif |
|||
#if defined CACAO_BIND_SRV_SSAO_BUFFER_PONG |
|||
Texture2DArray<FfxFloat32x2> g_SsaoBufferPong : FFX_CACAO_DECLARE_SRV(CACAO_BIND_SRV_SSAO_BUFFER_PONG); |
|||
#endif |
|||
#if defined CACAO_BIND_SRV_IMPORTANCE_MAP |
|||
Texture2D<FfxFloat32> g_ImportanceMap : FFX_CACAO_DECLARE_SRV(CACAO_BIND_SRV_IMPORTANCE_MAP); |
|||
#endif |
|||
#if defined CACAO_BIND_SRV_IMPORTANCE_MAP_PONG |
|||
Texture2D<FfxFloat32> g_ImportanceMapPong : FFX_CACAO_DECLARE_SRV(CACAO_BIND_SRV_IMPORTANCE_MAP_PONG); |
|||
#endif |
|||
|
|||
#if defined CACAO_BIND_UAV_LOAD_COUNTER |
|||
RWTexture1D<FfxUInt32> g_RwLoadCounter : FFX_CACAO_DECLARE_UAV(CACAO_BIND_UAV_LOAD_COUNTER); |
|||
#endif |
|||
#if defined CACAO_BIND_UAV_DEINTERLEAVED_DEPTHS |
|||
RWTexture2DArray<FfxFloat32> g_RwDeinterleavedDepth : FFX_CACAO_DECLARE_UAV(CACAO_BIND_UAV_DEINTERLEAVED_DEPTHS); |
|||
#endif |
|||
#if defined CACAO_BIND_UAV_DEINTERLEAVED_NORMALS |
|||
RWTexture2DArray<FfxFloat32x4> g_RwDeinterleavedNormals : FFX_CACAO_DECLARE_UAV(CACAO_BIND_UAV_DEINTERLEAVED_NORMALS); |
|||
#endif |
|||
#if defined CACAO_BIND_UAV_SSAO_BUFFER_PING |
|||
RWTexture2DArray<FfxFloat32x2> g_RwSsaoBufferPing : FFX_CACAO_DECLARE_UAV(CACAO_BIND_UAV_SSAO_BUFFER_PING); |
|||
#endif |
|||
#if defined CACAO_BIND_UAV_SSAO_BUFFER_PONG |
|||
RWTexture2DArray<FfxFloat32x2> g_RwSsaoBufferPong : FFX_CACAO_DECLARE_UAV(CACAO_BIND_UAV_SSAO_BUFFER_PONG); |
|||
#endif |
|||
#if defined CACAO_BIND_UAV_IMPORTANCE_MAP |
|||
RWTexture2D<FfxFloat32> g_RwImportanceMap : FFX_CACAO_DECLARE_UAV(CACAO_BIND_UAV_IMPORTANCE_MAP); |
|||
#endif |
|||
#if defined CACAO_BIND_UAV_IMPORTANCE_MAP_PONG |
|||
RWTexture2D<FfxFloat32> g_RwImportanceMapPong : FFX_CACAO_DECLARE_UAV(CACAO_BIND_UAV_IMPORTANCE_MAP_PONG); |
|||
#endif |
|||
#if defined CACAO_BIND_UAV_OUTPUT |
|||
RWTexture2D<FfxFloat32> g_RwOutput : FFX_CACAO_DECLARE_UAV(CACAO_BIND_UAV_OUTPUT); |
|||
#endif |
|||
#if defined CACAO_BIND_UAV_DEPTH_DOWNSAMPLED_MIPS |
|||
RWTexture2DArray<FfxFloat32> g_RwDepthMips0 : FFX_CACAO_DECLARE_UAV(0); |
|||
RWTexture2DArray<FfxFloat32> g_RwDepthMips1 : FFX_CACAO_DECLARE_UAV(1); |
|||
RWTexture2DArray<FfxFloat32> g_RwDepthMips2 : FFX_CACAO_DECLARE_UAV(2); |
|||
RWTexture2DArray<FfxFloat32> g_RwDepthMips3 : FFX_CACAO_DECLARE_UAV(3); |
|||
#endif |
|||
|
|||
// ============================================================================= |
|||
// Clear Load Counter |
|||
|
|||
void FFX_CACAO_ClearLoadCounter_SetLoadCounter(FfxUInt32 val) |
|||
{ |
|||
#if defined CACAO_BIND_UAV_LOAD_COUNTER |
|||
g_RwLoadCounter[0] = val; |
|||
#endif |
|||
} |
|||
|
|||
// ============================================================================= |
|||
// Edge Sensitive Blur |
|||
|
|||
FfxFloat32x2 FFX_CACAO_EdgeSensitiveBlur_SampleInputOffset(FfxFloat32x2 uv, FfxInt32x2 offset, FfxUInt32 layerId) |
|||
{ |
|||
#if defined CACAO_BIND_SRV_SSAO_BUFFER_PING |
|||
return g_SsaoBufferPing.SampleLevel(g_PointMirrorSampler, FfxFloat32x3(uv, FfxFloat32(layerId)), 0.0f, offset); |
|||
#else |
|||
return FfxFloat32x2(0, 0); |
|||
#endif |
|||
} |
|||
|
|||
FfxFloat32x2 FFX_CACAO_EdgeSensitiveBlur_SampleInput(FfxFloat32x2 uv, FfxUInt32 layerId) |
|||
{ |
|||
#if defined CACAO_BIND_SRV_SSAO_BUFFER_PING |
|||
return g_SsaoBufferPing.SampleLevel(g_PointMirrorSampler, FfxFloat32x3(uv, FfxFloat32(layerId)), 0.0f); |
|||
#else |
|||
return FfxFloat32x2(0, 0); |
|||
#endif |
|||
} |
|||
|
|||
void FFX_CACAO_EdgeSensitiveBlur_StoreOutput(FfxUInt32x2 coord, FfxFloat32x2 value, FfxUInt32 layerId) |
|||
{ |
|||
#if defined CACAO_BIND_UAV_SSAO_BUFFER_PONG |
|||
g_RwSsaoBufferPong[FfxInt32x3(coord, layerId)] = value; |
|||
#endif |
|||
} |
|||
|
|||
// ============================================================================= |
|||
// SSAO Generation |
|||
|
|||
FfxFloat32 FFX_CACAO_SSAOGeneration_SampleViewspaceDepthMip(FfxFloat32x2 uv, FfxFloat32 mip, FfxUInt32 layerId) |
|||
{ |
|||
#if defined CACAO_BIND_SRV_DEINTERLEAVED_DEPTHS |
|||
return g_DeinterleavedDepth.SampleLevel(g_ViewPointClampSampler, FfxFloat32x3(uv, FfxFloat32(layerId)), mip); |
|||
#else |
|||
return 0; |
|||
#endif |
|||
} |
|||
|
|||
FfxFloat32x4 FFX_CACAO_SSAOGeneration_GatherViewspaceDepthOffset(FfxFloat32x2 uv, FfxInt32x2 offset, FfxUInt32 layerId) |
|||
{ |
|||
#if defined CACAO_BIND_SRV_DEINTERLEAVED_DEPTHS |
|||
return g_DeinterleavedDepth.GatherRed(g_PointMirrorSampler, FfxFloat32x3(uv, FfxFloat32(layerId)), offset); |
|||
#else |
|||
return FfxFloat32x4(0, 0, 0, 0); |
|||
#endif |
|||
} |
|||
|
|||
FfxUInt32 FFX_CACAO_SSAOGeneration_GetLoadCounter() |
|||
{ |
|||
#if defined CACAO_BIND_SRV_LOAD_COUNTER |
|||
return g_LoadCounter[0]; |
|||
#else |
|||
return 0; |
|||
#endif |
|||
} |
|||
|
|||
FfxFloat32 FFX_CACAO_SSAOGeneration_SampleImportance(FfxFloat32x2 uv) |
|||
{ |
|||
#if defined CACAO_BIND_SRV_IMPORTANCE_MAP |
|||
return g_ImportanceMap.SampleLevel(g_LinearClampSampler, uv, 0.0f); |
|||
#else |
|||
return 0; |
|||
#endif |
|||
} |
|||
|
|||
FfxFloat32x2 FFX_CACAO_SSAOGeneration_LoadBasePassSSAOPass(FfxUInt32x2 coord, FfxUInt32 passnum) |
|||
{ |
|||
#if defined CACAO_BIND_SRV_SSAO_BUFFER_PONG |
|||
return g_SsaoBufferPong.Load(FfxInt32x4(coord, passnum, 0)).xy; |
|||
#else |
|||
return FfxFloat32x2(0, 0); |
|||
#endif |
|||
} |
|||
|
|||
FfxFloat32x3 FFX_CACAO_SSAOGeneration_GetNormalPass(FfxUInt32x2 coord, FfxUInt32 passnum) |
|||
{ |
|||
#if defined CACAO_BIND_SRV_DEINTERLEAVED_NORMALS |
|||
return g_DeinterleavedNormals[FfxInt32x3(coord, passnum)].xyz; |
|||
#else |
|||
return FfxFloat32x3(0, 0, 0); |
|||
#endif |
|||
} |
|||
|
|||
void FFX_CACAO_SSAOGeneration_StoreOutput(FfxUInt32x2 coord, FfxFloat32x2 val, FfxUInt32 layerId) |
|||
{ |
|||
#if defined CACAO_BIND_UAV_SSAO_BUFFER_PING |
|||
g_RwSsaoBufferPing[FfxInt32x3(coord, layerId)] = val; |
|||
#endif |
|||
} |
|||
|
|||
// ============================================================================ |
|||
// Apply |
|||
|
|||
// This resource can be ssao ping or pong, handled by schedule Dispatch |
|||
|
|||
FfxFloat32 FFX_CACAO_Apply_SampleSSAOUVPass(FfxFloat32x2 uv, FfxUInt32 passnum) |
|||
{ |
|||
#if defined CACAO_BIND_SRV_SSAO_BUFFER_PING |
|||
return g_SsaoBufferPing.SampleLevel(g_LinearClampSampler, FfxFloat32x3(uv, passnum), 0.0f).x; |
|||
#else |
|||
return 0; |
|||
#endif |
|||
} |
|||
|
|||
FfxFloat32x2 FFX_CACAO_Apply_LoadSSAOPass(FfxUInt32x2 coord, FfxUInt32 passnum) |
|||
{ |
|||
#if defined CACAO_BIND_SRV_SSAO_BUFFER_PING |
|||
return g_SsaoBufferPing.Load(FfxInt32x4(coord, passnum, 0)); |
|||
#else |
|||
return FfxFloat32x2(0, 0); |
|||
#endif |
|||
} |
|||
|
|||
// void FFX_CACAO_Apply_StoreOutput(FfxUInt32x2 coord, FfxFloat32 val) |
|||
// { |
|||
// #if defined CACAO_BIND_UAV_OUTPUT |
|||
// g_RwOutput[coord] = val; |
|||
// #endif |
|||
// } |
|||
|
|||
// ============================================================================= |
|||
// Prepare |
|||
|
|||
// FfxFloat32x4 FFX_CACAO_Prepare_SampleDepthOffsets(FfxFloat32x2 uv) |
|||
// { |
|||
// #if defined CACAO_BIND_SRV_DEPTH_IN |
|||
// FfxFloat32x4 samples; |
|||
// samples.x = g_DepthIn.SampleLevel(g_PointClampSampler, uv, 0.0f, FfxInt32x2(0, 2)); |
|||
// samples.y = g_DepthIn.SampleLevel(g_PointClampSampler, uv, 0.0f, FfxInt32x2(2, 2)); |
|||
// samples.z = g_DepthIn.SampleLevel(g_PointClampSampler, uv, 0.0f, FfxInt32x2(2, 0)); |
|||
// samples.w = g_DepthIn.SampleLevel(g_PointClampSampler, uv, 0.0f, FfxInt32x2(0, 0)); |
|||
// return samples; |
|||
// #else |
|||
// return FfxFloat32x4(0, 0, 0, 0); |
|||
// #endif |
|||
// } |
|||
// |
|||
// FfxFloat32x4 FFX_CACAO_Prepare_GatherDepth(FfxFloat32x2 uv) |
|||
// { |
|||
// #if defined CACAO_BIND_SRV_DEPTH_IN |
|||
// return g_DepthIn.GatherRed(g_PointClampSampler, uv); |
|||
// #else |
|||
// return FfxFloat32x4(0, 0, 0, 0); |
|||
// #endif |
|||
// } |
|||
// |
|||
// FfxFloat32 FFX_CACAO_Prepare_LoadDepth(FfxUInt32x2 coord) |
|||
// { |
|||
// #if defined CACAO_BIND_SRV_DEPTH_IN |
|||
// return g_DepthIn.Load(FfxInt32x3(coord, 0)); |
|||
// #else |
|||
// return 0; |
|||
// #endif |
|||
// } |
|||
// |
|||
// FfxFloat32 FFX_CACAO_Prepare_LoadDepthOffset(FfxUInt32x2 coord, FfxInt32x2 offset) |
|||
// { |
|||
// #if defined CACAO_BIND_SRV_DEPTH_IN |
|||
// return g_DepthIn.Load(FfxInt32x3(coord, 0), offset); |
|||
// #else |
|||
// return 0; |
|||
// #endif |
|||
// } |
|||
// |
|||
// FfxFloat32x4 FFX_CACAO_Prepare_GatherDepthOffset(FfxFloat32x2 uv, FfxInt32x2 offset) |
|||
// { |
|||
// #if defined CACAO_BIND_SRV_DEPTH_IN |
|||
// return g_DepthIn.GatherRed(g_PointClampSampler, uv, offset); |
|||
// #else |
|||
// return FfxFloat32x4(0, 0, 0, 0); |
|||
// #endif |
|||
// } |
|||
|
|||
FfxFloat32x3 FFX_CACAO_Prepare_LoadNormal(FfxUInt32x2 coord) |
|||
{ |
|||
#if defined CACAO_BIND_SRV_NORMAL_IN |
|||
//FfxFloat32x3 normal = g_NormalIn.Load(FfxInt32x3(coord, 0)).xyz; |
|||
FfxFloat32x3 normal = LoadSceneNormals(coord); |
|||
//normal = normal * NormalsUnpackMul().xxx + NormalsUnpackAdd().xxx; |
|||
normal = mul(normal, (float3x3)NormalsWorldToViewspaceMatrix()).xyz; |
|||
// normal = normalize(normal); |
|||
return normal; |
|||
#else |
|||
return FfxFloat32x3(0, 0, 0); |
|||
#endif |
|||
} |
|||
|
|||
void FFX_CACAO_Prepare_StoreDepthMip0(FfxUInt32x2 coord, FfxUInt32 index, FfxFloat32 val) |
|||
{ |
|||
#if defined CACAO_BIND_UAV_DEPTH_DOWNSAMPLED_MIPS |
|||
g_RwDepthMips0[FfxInt32x3(coord, index)] = val; |
|||
#endif |
|||
} |
|||
|
|||
void FFX_CACAO_Prepare_StoreDepthMip1(FfxUInt32x2 coord, FfxUInt32 index, FfxFloat32 val) |
|||
{ |
|||
#if defined CACAO_BIND_UAV_DEPTH_DOWNSAMPLED_MIPS |
|||
g_RwDepthMips1[FfxInt32x3(coord, index)] = val; |
|||
#endif |
|||
} |
|||
|
|||
void FFX_CACAO_Prepare_StoreDepthMip2(FfxUInt32x2 coord, FfxUInt32 index, FfxFloat32 val) |
|||
{ |
|||
#if defined CACAO_BIND_UAV_DEPTH_DOWNSAMPLED_MIPS |
|||
g_RwDepthMips2[FfxInt32x3(coord, index)] = val; |
|||
#endif |
|||
} |
|||
|
|||
void FFX_CACAO_Prepare_StoreDepthMip3(FfxUInt32x2 coord, FfxUInt32 index, FfxFloat32 val) |
|||
{ |
|||
#if defined CACAO_BIND_UAV_DEPTH_DOWNSAMPLED_MIPS |
|||
g_RwDepthMips3[FfxInt32x3(coord, index)] = val; |
|||
#endif |
|||
} |
|||
|
|||
void FFX_CACAO_Prepare_StoreDepth(FfxUInt32x2 coord, FfxUInt32 index, FfxFloat32 val) |
|||
{ |
|||
#if defined CACAO_BIND_UAV_DEINTERLEAVED_DEPTHS |
|||
g_RwDeinterleavedDepth[FfxInt32x3(coord, index)] = val; |
|||
#endif |
|||
} |
|||
|
|||
void FFX_CACAO_Prepare_StoreNormal(FfxUInt32x2 coord, FfxUInt32 index, FfxFloat32x3 normal) |
|||
{ |
|||
#if defined CACAO_BIND_UAV_DEINTERLEAVED_NORMALS |
|||
g_RwDeinterleavedNormals[FfxInt32x3(coord, index)] = FfxFloat32x4(normal, 1.0f); |
|||
#endif |
|||
} |
|||
|
|||
// ============================================================================= |
|||
// Importance Map |
|||
|
|||
FfxFloat32x4 FFX_CACAO_Importance_GatherSSAO(FfxFloat32x2 uv, FfxUInt32 index) |
|||
{ |
|||
#if defined CACAO_BIND_SRV_SSAO_BUFFER_PONG |
|||
return g_SsaoBufferPong.GatherRed(g_PointClampSampler, FfxFloat32x3(uv, index)); |
|||
#else |
|||
return FfxFloat32x4(0, 0, 0, 0); |
|||
#endif |
|||
} |
|||
|
|||
void FFX_CACAO_Importance_StoreImportance(FfxUInt32x2 coord, FfxFloat32 val) |
|||
{ |
|||
#if defined CACAO_BIND_UAV_IMPORTANCE_MAP |
|||
g_RwImportanceMap[coord] = val; |
|||
#endif |
|||
} |
|||
|
|||
FfxFloat32 FFX_CACAO_Importance_SampleImportanceA(FfxFloat32x2 uv) |
|||
{ |
|||
#if defined CACAO_BIND_SRV_IMPORTANCE_MAP |
|||
return g_ImportanceMap.SampleLevel(g_LinearClampSampler, uv, 0.0f); |
|||
#else |
|||
return 0; |
|||
#endif |
|||
} |
|||
|
|||
void FFX_CACAO_Importance_StoreImportanceA(FfxUInt32x2 coord, FfxFloat32 val) |
|||
{ |
|||
#if defined CACAO_BIND_UAV_IMPORTANCE_MAP_PONG |
|||
g_RwImportanceMapPong[coord] = val; |
|||
#endif |
|||
} |
|||
|
|||
FfxFloat32 FFX_CACAO_Importance_SampleImportanceB(FfxFloat32x2 uv) |
|||
{ |
|||
#if defined CACAO_BIND_SRV_IMPORTANCE_MAP_PONG |
|||
return g_ImportanceMapPong.SampleLevel(g_LinearClampSampler, uv, 0.0f); |
|||
#else |
|||
return 0; |
|||
#endif |
|||
} |
|||
|
|||
void FFX_CACAO_Importance_StoreImportanceB(FfxUInt32x2 coord, FfxFloat32 val) |
|||
{ |
|||
#if defined CACAO_BIND_UAV_IMPORTANCE_MAP |
|||
g_RwImportanceMap[coord] = val; |
|||
#endif |
|||
} |
|||
|
|||
void FFX_CACAO_Importance_LoadCounterInterlockedAdd(FfxUInt32 val) |
|||
{ |
|||
#if defined CACAO_BIND_UAV_LOAD_COUNTER |
|||
InterlockedAdd(g_RwLoadCounter[0], val); |
|||
#endif |
|||
} |
|||
|
|||
// ============================================================================= |
|||
// Bilateral Upscale |
|||
|
|||
// These resources ping/pong which is handled by schedule dispatch |
|||
|
|||
// void FFX_CACAO_BilateralUpscale_StoreOutput(FfxUInt32x2 coord, FfxInt32x2 offset, FfxFloat32 val) |
|||
// { |
|||
// #if defined CACAO_BIND_UAV_OUTPUT |
|||
// g_RwOutput[coord + offset] = val; |
|||
// #endif |
|||
// } |
|||
|
|||
FfxFloat32 FFX_CACAO_BilateralUpscale_SampleSSAOLinear(FfxFloat32x2 uv, FfxUInt32 index) |
|||
{ |
|||
#if defined CACAO_BIND_SRV_SSAO_BUFFER_PING |
|||
return g_SsaoBufferPing.SampleLevel(g_LinearClampSampler, FfxFloat32x3(uv, index), 0).x; |
|||
#else |
|||
return 0; |
|||
#endif |
|||
} |
|||
|
|||
FfxFloat32 FFX_CACAO_BilateralUpscale_SampleSSAOPoint(FfxFloat32x2 uv, FfxUInt32 index) |
|||
{ |
|||
#if defined CACAO_BIND_SRV_SSAO_BUFFER_PING |
|||
return g_SsaoBufferPing.SampleLevel(g_PointClampSampler, FfxFloat32x3(uv, index), 0).x; |
|||
#else |
|||
return 0; |
|||
#endif |
|||
} |
|||
|
|||
FfxFloat32x2 FFX_CACAO_BilateralUpscale_LoadSSAO(FfxUInt32x2 coord, FfxUInt32 index) |
|||
{ |
|||
#if defined CACAO_BIND_SRV_SSAO_BUFFER_PING |
|||
return g_SsaoBufferPing.Load(FfxInt32x4(coord, index, 0)); |
|||
#else |
|||
return 0; |
|||
#endif |
|||
} |
|||
|
|||
FfxFloat32x4 FFX_CACAO_BilateralUpscale_LoadDepths(FfxUInt32x2 coord) |
|||
{ |
|||
FfxFloat32x4 depths; |
|||
#if defined CACAO_BIND_SRV_DEPTH_IN |
|||
depths.x = g_DepthIn.Load(FfxInt32x3(coord, 0), FfxInt32x2(0, 0)); |
|||
depths.y = g_DepthIn.Load(FfxInt32x3(coord, 0), FfxInt32x2(1, 0)); |
|||
depths.z = g_DepthIn.Load(FfxInt32x3(coord, 0), FfxInt32x2(0, 1)); |
|||
depths.w = g_DepthIn.Load(FfxInt32x3(coord, 0), FfxInt32x2(1, 1)); |
|||
return depths; |
|||
#else |
|||
return FfxFloat32x4(0, 0, 0, 0); |
|||
#endif |
|||
} |
|||
|
|||
FfxFloat32 FFX_CACAO_BilateralUpscale_LoadDownscaledDepth(FfxUInt32x2 coord, FfxUInt32 index) |
|||
{ |
|||
#if defined CACAO_BIND_SRV_DEINTERLEAVED_DEPTHS |
|||
return g_DeinterleavedDepth.Load(FfxInt32x4(coord, index, 0)); |
|||
#else |
|||
return 0; |
|||
#endif |
|||
} |
|||
|
|||
#endif // #if defined(FFX_GPU) |
|||
@ -0,0 +1,27 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 85398acdeda824849a91ad610b72da4f |
|||
PluginImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
iconMap: {} |
|||
executionOrder: {} |
|||
defineConstraints: [] |
|||
isPreloaded: 0 |
|||
isOverridable: 0 |
|||
isExplicitlyReferenced: 0 |
|||
validateReferences: 1 |
|||
platformData: |
|||
- first: |
|||
Any: |
|||
second: |
|||
enabled: 1 |
|||
settings: {} |
|||
- first: |
|||
Editor: Editor |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
DefaultValueInitialized: true |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,85 @@ |
|||
// This file is part of the FidelityFX SDK. |
|||
// |
|||
// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved. |
|||
// |
|||
// 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. |
|||
|
|||
|
|||
// Defines for constants common to both CACAO.cpp and CACAO.hlsl |
|||
|
|||
#ifndef FFX_CACAO_DEFINES_H |
|||
#define FFX_CACAO_DEFINES_H |
|||
|
|||
// ============================================================================ |
|||
// Prepare |
|||
|
|||
#define FFX_CACAO_PREPARE_DEPTHS_AND_MIPS_WIDTH 8 |
|||
#define FFX_CACAO_PREPARE_DEPTHS_AND_MIPS_HEIGHT 8 |
|||
|
|||
#define FFX_CACAO_PREPARE_DEPTHS_WIDTH 8 |
|||
#define FFX_CACAO_PREPARE_DEPTHS_HEIGHT 8 |
|||
|
|||
#define FFX_CACAO_PREPARE_DEPTHS_HALF_WIDTH 8 |
|||
#define FFX_CACAO_PREPARE_DEPTHS_HALF_HEIGHT 8 |
|||
|
|||
#define FFX_CACAO_PREPARE_NORMALS_WIDTH 8 |
|||
#define FFX_CACAO_PREPARE_NORMALS_HEIGHT 8 |
|||
|
|||
#define PREPARE_NORMALS_FROM_INPUT_NORMALS_WIDTH 8 |
|||
#define PREPARE_NORMALS_FROM_INPUT_NORMALS_HEIGHT 8 |
|||
|
|||
// ============================================================================ |
|||
// SSAO Generation |
|||
|
|||
#define FFX_CACAO_GENERATE_SPARSE_WIDTH 4 |
|||
#define FFX_CACAO_GENERATE_SPARSE_HEIGHT 16 |
|||
|
|||
#define FFX_CACAO_GENERATE_WIDTH 8 |
|||
#define FFX_CACAO_GENERATE_HEIGHT 8 |
|||
|
|||
// ============================================================================ |
|||
// Importance Map |
|||
|
|||
#define IMPORTANCE_MAP_WIDTH 8 |
|||
#define IMPORTANCE_MAP_HEIGHT 8 |
|||
|
|||
#define IMPORTANCE_MAP_A_WIDTH 8 |
|||
#define IMPORTANCE_MAP_A_HEIGHT 8 |
|||
|
|||
#define IMPORTANCE_MAP_B_WIDTH 8 |
|||
#define IMPORTANCE_MAP_B_HEIGHT 8 |
|||
|
|||
// ============================================================================ |
|||
// Edge Sensitive Blur |
|||
|
|||
#define FFX_CACAO_BLUR_WIDTH 16 |
|||
#define FFX_CACAO_BLUR_HEIGHT 16 |
|||
|
|||
// ============================================================================ |
|||
// Apply |
|||
|
|||
#define FFX_CACAO_APPLY_WIDTH 8 |
|||
#define FFX_CACAO_APPLY_HEIGHT 8 |
|||
|
|||
// ============================================================================ |
|||
// Bilateral Upscale |
|||
|
|||
#define FFX_CACAO_BILATERAL_UPSCALE_WIDTH 8 |
|||
#define FFX_CACAO_BILATERAL_UPSCALE_HEIGHT 8 |
|||
|
|||
#endif |
|||
@ -0,0 +1,27 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 6667a3e1fa8dcd04bbd17a6abd968159 |
|||
PluginImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
iconMap: {} |
|||
executionOrder: {} |
|||
defineConstraints: [] |
|||
isPreloaded: 0 |
|||
isOverridable: 0 |
|||
isExplicitlyReferenced: 0 |
|||
validateReferences: 1 |
|||
platformData: |
|||
- first: |
|||
Any: |
|||
second: |
|||
enabled: 1 |
|||
settings: {} |
|||
- first: |
|||
Editor: Editor |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
DefaultValueInitialized: true |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,449 @@ |
|||
// This file is part of the FidelityFX SDK. |
|||
// |
|||
// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved. |
|||
// |
|||
// 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. |
|||
|
|||
|
|||
#include "../common/ffx_core.h" |
|||
#include "ffx_cacao_defines.h" |
|||
#include "ffx_cacao_utils.h" |
|||
|
|||
// all in one, SIMD in yo SIMD dawg, shader |
|||
#define FFX_CACAO_TILE_WIDTH 4 |
|||
#define FFX_CACAO_TILE_HEIGHT 3 |
|||
#define FFX_CACAO_HALF_TILE_WIDTH (FFX_CACAO_TILE_WIDTH / 2) |
|||
#define FFX_CACAO_QUARTER_TILE_WIDTH (FFX_CACAO_TILE_WIDTH / 4) |
|||
|
|||
#define FFX_CACAO_ARRAY_WIDTH (FFX_CACAO_HALF_TILE_WIDTH * FFX_CACAO_BLUR_WIDTH + 2) |
|||
#define FFX_CACAO_ARRAY_HEIGHT (FFX_CACAO_TILE_HEIGHT * FFX_CACAO_BLUR_HEIGHT + 2) |
|||
|
|||
#define FFX_CACAO_ITERS 4 |
|||
|
|||
FFX_GROUPSHARED FfxUInt32 s_FFX_CACAO_BlurF16Front_4[FFX_CACAO_ARRAY_WIDTH][FFX_CACAO_ARRAY_HEIGHT]; |
|||
FFX_GROUPSHARED FfxUInt32 s_FFX_CACAO_BlurF16Back_4[FFX_CACAO_ARRAY_WIDTH][FFX_CACAO_ARRAY_HEIGHT]; |
|||
|
|||
#if FFX_HALF |
|||
struct FFX_CACAO_Edges_4 |
|||
{ |
|||
FfxFloat16x4 left; |
|||
FfxFloat16x4 right; |
|||
FfxFloat16x4 top; |
|||
FfxFloat16x4 bottom; |
|||
}; |
|||
|
|||
FFX_CACAO_Edges_4 FFX_CACAO_UnpackEdgesFloat16_4(FfxFloat16x4 _packedVal) |
|||
{ |
|||
FfxUInt32x4 packedVal = FfxUInt32x4(_packedVal * 255.5); |
|||
FFX_CACAO_Edges_4 result; |
|||
result.left = FfxFloat16x4(ffxSaturate(FfxFloat16x4((packedVal >> 6) & 0x03) / 3.0 + InvSharpness())); |
|||
result.right = FfxFloat16x4(ffxSaturate(FfxFloat16x4((packedVal >> 4) & 0x03) / 3.0 + InvSharpness())); |
|||
result.top = FfxFloat16x4(ffxSaturate(FfxFloat16x4((packedVal >> 2) & 0x03) / 3.0 + InvSharpness())); |
|||
result.bottom = FfxFloat16x4(ffxSaturate(FfxFloat16x4((packedVal >> 0) & 0x03) / 3.0 + InvSharpness())); |
|||
|
|||
return result; |
|||
} |
|||
|
|||
FfxFloat16x4 FFX_CACAO_CalcBlurredSampleF16_4(FfxFloat16x4 packedEdges, FfxFloat16x4 centre, FfxFloat16x4 left, FfxFloat16x4 right, FfxFloat16x4 top, FfxFloat16x4 bottom) |
|||
{ |
|||
FfxFloat16x4 sum = centre * FfxFloat16(0.5f); |
|||
FfxFloat16x4 weight = FfxFloat16x4(0.5f, 0.5f, 0.5f, 0.5f); |
|||
FFX_CACAO_Edges_4 edges = FFX_CACAO_UnpackEdgesFloat16_4(packedEdges); |
|||
|
|||
sum += left * edges.left; |
|||
weight += edges.left; |
|||
sum += right * edges.right; |
|||
weight += edges.right; |
|||
sum += top * edges.top; |
|||
weight += edges.top; |
|||
sum += bottom * edges.bottom; |
|||
weight += edges.bottom; |
|||
|
|||
return sum / weight; |
|||
} |
|||
|
|||
void FFX_CACAO_LDSEdgeSensitiveBlur(const FfxUInt32 blurPasses, const FfxUInt32x2 tid, const FfxUInt32x2 gid, const FfxUInt32 layerId) |
|||
{ |
|||
FfxInt32x2 imageCoord = FfxInt32x2(gid) * (FfxInt32x2(FFX_CACAO_TILE_WIDTH * FFX_CACAO_BLUR_WIDTH, FFX_CACAO_TILE_HEIGHT * FFX_CACAO_BLUR_HEIGHT) - FfxInt32(2*blurPasses)) + FfxInt32x2(FFX_CACAO_TILE_WIDTH, FFX_CACAO_TILE_HEIGHT) * FfxInt32x2(tid) - FfxInt32(blurPasses); |
|||
FfxInt32x2 bufferCoord = FfxInt32x2(FFX_CACAO_HALF_TILE_WIDTH, FFX_CACAO_TILE_HEIGHT) * FfxInt32x2(tid) + 1; |
|||
|
|||
FfxFloat16x4 packedEdges[FFX_CACAO_QUARTER_TILE_WIDTH][FFX_CACAO_TILE_HEIGHT]; |
|||
{ |
|||
FfxFloat32x2 inputVal[FFX_CACAO_TILE_WIDTH][FFX_CACAO_TILE_HEIGHT]; |
|||
FfxInt32 y; |
|||
FFX_UNROLL |
|||
for (y = 0; y < FFX_CACAO_TILE_HEIGHT; ++y) |
|||
{ |
|||
FFX_UNROLL |
|||
for (FfxInt32 x = 0; x < FFX_CACAO_TILE_WIDTH; ++x) |
|||
{ |
|||
FfxFloat32x2 sampleUV = (FfxFloat32x2(imageCoord + FfxInt32x2(x, y)) + 0.5f) * SSAOBufferInverseDimensions(); |
|||
inputVal[x][y] = FFX_CACAO_EdgeSensitiveBlur_SampleInput(sampleUV, layerId); |
|||
} |
|||
} |
|||
FFX_UNROLL |
|||
for (y = 0; y < FFX_CACAO_TILE_HEIGHT; ++y) |
|||
{ |
|||
FFX_UNROLL |
|||
for (FfxInt32 x = 0; x < FFX_CACAO_QUARTER_TILE_WIDTH; ++x) |
|||
{ |
|||
FfxFloat16x2 ssaoVals = FfxFloat16x2(inputVal[4 * x + 0][y].x, inputVal[4 * x + 1][y].x); |
|||
s_FFX_CACAO_BlurF16Front_4[bufferCoord.x + 2*x + 0][bufferCoord.y + y] = ffxPackF16(ssaoVals); |
|||
ssaoVals = FfxFloat16x2(inputVal[4 * x + 2][y].x, inputVal[4 * x + 3][y].x); |
|||
s_FFX_CACAO_BlurF16Front_4[bufferCoord.x + 2*x + 1][bufferCoord.y + y] = ffxPackF16(ssaoVals); |
|||
packedEdges[x][y] = FfxFloat16x4(inputVal[4 * x + 0][y].y, inputVal[4 * x + 1][y].y, inputVal[4 * x + 2][y].y, inputVal[4 * x + 3][y].y); |
|||
} |
|||
} |
|||
} |
|||
|
|||
FFX_GROUP_MEMORY_BARRIER(); |
|||
|
|||
FFX_UNROLL |
|||
for (FfxUInt32 i = 0; i < (blurPasses + 1) / 2; ++i) |
|||
{ |
|||
FFX_UNROLL |
|||
for (FfxInt32 y = 0; y < FFX_CACAO_TILE_HEIGHT; ++y) |
|||
{ |
|||
FFX_UNROLL |
|||
for (FfxInt32 x = 0; x < FFX_CACAO_QUARTER_TILE_WIDTH; ++x) |
|||
{ |
|||
FfxInt32x2 c = bufferCoord + FfxInt32x2(2*x, y); |
|||
FfxFloat16x4 centre = FfxFloat16x4(ffxUnpackF16(s_FFX_CACAO_BlurF16Front_4[c.x + 0][c.y + 0]), ffxUnpackF16(s_FFX_CACAO_BlurF16Front_4[c.x + 1][c.y + 0])); |
|||
FfxFloat16x4 top = FfxFloat16x4(ffxUnpackF16(s_FFX_CACAO_BlurF16Front_4[c.x + 0][c.y - 1]), ffxUnpackF16(s_FFX_CACAO_BlurF16Front_4[c.x + 1][c.y - 1])); |
|||
FfxFloat16x4 bottom = FfxFloat16x4(ffxUnpackF16(s_FFX_CACAO_BlurF16Front_4[c.x + 0][c.y + 1]), ffxUnpackF16(s_FFX_CACAO_BlurF16Front_4[c.x + 1][c.y + 1])); |
|||
|
|||
FfxFloat16x2 tmp = ffxUnpackF16(s_FFX_CACAO_BlurF16Front_4[c.x - 1][c.y + 0]); |
|||
FfxFloat16x4 left = FfxFloat16x4(tmp.y, centre.xyz); |
|||
tmp = ffxUnpackF16(s_FFX_CACAO_BlurF16Front_4[c.x + 2][c.y + 0]); |
|||
FfxFloat16x4 right = FfxFloat16x4(centre.yzw, tmp.x); |
|||
|
|||
FfxFloat16x4 tmp_4 = FFX_CACAO_CalcBlurredSampleF16_4(packedEdges[x][y], centre, left, right, top, bottom); |
|||
s_FFX_CACAO_BlurF16Back_4[c.x + 0][c.y] = ffxPackF16(tmp_4.xy); |
|||
s_FFX_CACAO_BlurF16Back_4[c.x + 1][c.y] = ffxPackF16(tmp_4.zw); |
|||
} |
|||
} |
|||
FFX_GROUP_MEMORY_BARRIER();; |
|||
|
|||
if (2 * i + 1 < blurPasses) |
|||
{ |
|||
FFX_UNROLL |
|||
for (FfxInt32 y = 0; y < FFX_CACAO_TILE_HEIGHT; ++y) |
|||
{ |
|||
FFX_UNROLL |
|||
for (FfxInt32 x = 0; x < FFX_CACAO_QUARTER_TILE_WIDTH; ++x) |
|||
{ |
|||
FfxInt32x2 c = bufferCoord + FfxInt32x2(2 * x, y); |
|||
FfxFloat16x4 centre = FfxFloat16x4(ffxUnpackF16(s_FFX_CACAO_BlurF16Back_4[c.x + 0][c.y + 0]), ffxUnpackF16(s_FFX_CACAO_BlurF16Back_4[c.x + 1][c.y + 0])); |
|||
FfxFloat16x4 top = FfxFloat16x4(ffxUnpackF16(s_FFX_CACAO_BlurF16Back_4[c.x + 0][c.y - 1]), ffxUnpackF16(s_FFX_CACAO_BlurF16Back_4[c.x + 1][c.y - 1])); |
|||
FfxFloat16x4 bottom = FfxFloat16x4(ffxUnpackF16(s_FFX_CACAO_BlurF16Back_4[c.x + 0][c.y + 1]), ffxUnpackF16(s_FFX_CACAO_BlurF16Back_4[c.x + 1][c.y + 1])); |
|||
|
|||
FfxFloat16x2 tmp = ffxUnpackF16(s_FFX_CACAO_BlurF16Back_4[c.x - 1][c.y + 0]); |
|||
FfxFloat16x4 left = FfxFloat16x4(tmp.y, centre.xyz); |
|||
tmp = ffxUnpackF16(s_FFX_CACAO_BlurF16Back_4[c.x + 2][c.y + 0]); |
|||
FfxFloat16x4 right = FfxFloat16x4(centre.yzw, tmp.x); |
|||
|
|||
FfxFloat16x4 tmp_4 = FFX_CACAO_CalcBlurredSampleF16_4(packedEdges[x][y], centre, left, right, top, bottom); |
|||
s_FFX_CACAO_BlurF16Front_4[c.x + 0][c.y] = ffxPackF16(tmp_4.xy); |
|||
s_FFX_CACAO_BlurF16Front_4[c.x + 1][c.y] = ffxPackF16(tmp_4.zw); |
|||
} |
|||
} |
|||
FFX_GROUP_MEMORY_BARRIER();; |
|||
} |
|||
} |
|||
|
|||
FFX_UNROLL |
|||
for (FfxUInt32 y = 0; y < FFX_CACAO_TILE_HEIGHT; ++y) |
|||
{ |
|||
FfxUInt32 outputY = FFX_CACAO_TILE_HEIGHT * tid.y + y; |
|||
if (blurPasses <= outputY && outputY < FFX_CACAO_TILE_HEIGHT * FFX_CACAO_BLUR_HEIGHT - blurPasses) |
|||
{ |
|||
FFX_UNROLL |
|||
for (FfxInt32 x = 0; x < FFX_CACAO_QUARTER_TILE_WIDTH; ++x) |
|||
{ |
|||
FfxUInt32 outputX = FFX_CACAO_TILE_WIDTH * tid.x + 4 * x; |
|||
|
|||
FfxFloat16x4 ssaoVal; |
|||
if (blurPasses % 2 == 0) |
|||
{ |
|||
ssaoVal = FfxFloat16x4(ffxUnpackF16(s_FFX_CACAO_BlurF16Front_4[bufferCoord.x + x][bufferCoord.y + y]), ffxUnpackF16(s_FFX_CACAO_BlurF16Front_4[bufferCoord.x + x + 1][bufferCoord.y + y])); |
|||
} |
|||
else |
|||
{ |
|||
ssaoVal = FfxFloat16x4(ffxUnpackF16(s_FFX_CACAO_BlurF16Back_4[bufferCoord.x + x][bufferCoord.y + y]), ffxUnpackF16(s_FFX_CACAO_BlurF16Back_4[bufferCoord.x + x + 1][bufferCoord.y + y])); |
|||
} |
|||
|
|||
if (blurPasses <= outputX && outputX < FFX_CACAO_TILE_WIDTH * FFX_CACAO_BLUR_WIDTH - blurPasses) |
|||
{ |
|||
FFX_CACAO_EdgeSensitiveBlur_StoreOutput(imageCoord + FfxInt32x2(4 * x, y), FfxFloat32x2(ssaoVal.x, packedEdges[x][y].x), layerId); |
|||
} |
|||
outputX += 1; |
|||
if (blurPasses <= outputX && outputX < FFX_CACAO_TILE_WIDTH * FFX_CACAO_BLUR_WIDTH - blurPasses) |
|||
{ |
|||
FFX_CACAO_EdgeSensitiveBlur_StoreOutput(imageCoord + FfxInt32x2(4 * x + 1, y), FfxFloat32x2(ssaoVal.y, packedEdges[x][y].y), layerId); |
|||
} |
|||
outputX += 1; |
|||
if (blurPasses <= outputX && outputX < FFX_CACAO_TILE_WIDTH * FFX_CACAO_BLUR_WIDTH - blurPasses) |
|||
{ |
|||
FFX_CACAO_EdgeSensitiveBlur_StoreOutput(imageCoord + FfxInt32x2(4 * x + 2, y), FfxFloat32x2(ssaoVal.z, packedEdges[x][y].z), layerId); |
|||
} |
|||
outputX += 1; |
|||
if (blurPasses <= outputX && outputX < FFX_CACAO_TILE_WIDTH * FFX_CACAO_BLUR_WIDTH - blurPasses) |
|||
{ |
|||
FFX_CACAO_EdgeSensitiveBlur_StoreOutput(imageCoord + FfxInt32x2(4 * x + 3, y), FfxFloat32x2(ssaoVal.w, packedEdges[x][y].w), layerId); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
#else |
|||
struct FFX_CACAO_Edges_4 |
|||
{ |
|||
FfxFloat32x4 left; |
|||
FfxFloat32x4 right; |
|||
FfxFloat32x4 top; |
|||
FfxFloat32x4 bottom; |
|||
}; |
|||
|
|||
FFX_CACAO_Edges_4 FFX_CACAO_UnpackEdgesFloat32_4(FfxFloat32x4 _packedVal) |
|||
{ |
|||
FfxUInt32x4 packedVal = FfxUInt32x4(_packedVal * 255.5); |
|||
FFX_CACAO_Edges_4 result; |
|||
result.left = ffxSaturate(((packedVal >> 6) & 0x03) / 3.0 + InvSharpness()); |
|||
result.right = ffxSaturate(((packedVal >> 4) & 0x03) / 3.0 + InvSharpness()); |
|||
result.top = ffxSaturate(((packedVal >> 2) & 0x03) / 3.0 + InvSharpness()); |
|||
result.bottom = ffxSaturate(((packedVal >> 0) & 0x03) / 3.0 + InvSharpness()); |
|||
|
|||
return result; |
|||
} |
|||
|
|||
FfxFloat32x4 FFX_CACAO_CalcBlurredSampleF32_4(FfxFloat32x4 packedEdges, FfxFloat32x4 centre, FfxFloat32x4 left, FfxFloat32x4 right, FfxFloat32x4 top, FfxFloat32x4 bottom) |
|||
{ |
|||
FfxFloat32x4 sum = centre * FfxFloat32(0.5f); |
|||
FfxFloat32x4 weight = FfxFloat32x4(0.5f, 0.5f, 0.5f, 0.5f); |
|||
FFX_CACAO_Edges_4 edges = FFX_CACAO_UnpackEdgesFloat32_4(packedEdges); |
|||
|
|||
sum += left * edges.left; |
|||
weight += edges.left; |
|||
sum += right * edges.right; |
|||
weight += edges.right; |
|||
sum += top * edges.top; |
|||
weight += edges.top; |
|||
sum += bottom * edges.bottom; |
|||
weight += edges.bottom; |
|||
|
|||
return sum / weight; |
|||
} |
|||
|
|||
void FFX_CACAO_LDSEdgeSensitiveBlur(const FfxUInt32 blurPasses, const FfxUInt32x2 tid, const FfxUInt32x2 gid, const FfxUInt32 layerId) |
|||
{ |
|||
FfxInt32x2 imageCoord = FfxInt32x2(gid) * (FfxInt32x2(FFX_CACAO_TILE_WIDTH * FFX_CACAO_BLUR_WIDTH, FFX_CACAO_TILE_HEIGHT * FFX_CACAO_BLUR_HEIGHT) - FfxInt32(2*blurPasses)) + FfxInt32x2(FFX_CACAO_TILE_WIDTH, FFX_CACAO_TILE_HEIGHT) * FfxInt32x2(tid) - FfxInt32(blurPasses); |
|||
FfxInt32x2 bufferCoord = FfxInt32x2(FFX_CACAO_HALF_TILE_WIDTH, FFX_CACAO_TILE_HEIGHT) * FfxInt32x2(tid) + 1; |
|||
|
|||
FfxFloat32x4 packedEdges[FFX_CACAO_QUARTER_TILE_WIDTH][FFX_CACAO_TILE_HEIGHT]; |
|||
{ |
|||
FfxFloat32x2 inputVal[FFX_CACAO_TILE_WIDTH][FFX_CACAO_TILE_HEIGHT]; |
|||
FfxInt32 y; |
|||
FFX_UNROLL |
|||
for (y = 0; y < FFX_CACAO_TILE_HEIGHT; ++y) |
|||
{ |
|||
FFX_UNROLL |
|||
for (FfxInt32 x = 0; x < FFX_CACAO_TILE_WIDTH; ++x) |
|||
{ |
|||
FfxFloat32x2 sampleUV = (FfxFloat32x2(imageCoord + FfxInt32x2(x, y)) + 0.5f) * SSAOBufferInverseDimensions(); |
|||
inputVal[x][y] = FFX_CACAO_EdgeSensitiveBlur_SampleInput(sampleUV, layerId); |
|||
} |
|||
} |
|||
FFX_UNROLL |
|||
for (y = 0; y < FFX_CACAO_TILE_HEIGHT; ++y) |
|||
{ |
|||
FFX_UNROLL |
|||
for (FfxInt32 x = 0; x < FFX_CACAO_QUARTER_TILE_WIDTH; ++x) |
|||
{ |
|||
FfxFloat32x2 ssaoVals = FfxFloat32x2(inputVal[4 * x + 0][y].x, inputVal[4 * x + 1][y].x); |
|||
s_FFX_CACAO_BlurF16Front_4[bufferCoord.x + 2*x + 0][bufferCoord.y + y] = ffxPackF32(ssaoVals); |
|||
ssaoVals = FfxFloat32x2(inputVal[4 * x + 2][y].x, inputVal[4 * x + 3][y].x); |
|||
s_FFX_CACAO_BlurF16Front_4[bufferCoord.x + 2*x + 1][bufferCoord.y + y] = ffxPackF32(ssaoVals); |
|||
packedEdges[x][y] = FfxFloat32x4(inputVal[4 * x + 0][y].y, inputVal[4 * x + 1][y].y, inputVal[4 * x + 2][y].y, inputVal[4 * x + 3][y].y); |
|||
} |
|||
} |
|||
} |
|||
|
|||
FFX_GROUP_MEMORY_BARRIER();; |
|||
|
|||
FFX_UNROLL |
|||
for (FfxUInt32 i = 0; i < (blurPasses + 1) / 2; ++i) |
|||
{ |
|||
FFX_UNROLL |
|||
for (FfxInt32 y = 0; y < FFX_CACAO_TILE_HEIGHT; ++y) |
|||
{ |
|||
FFX_UNROLL |
|||
for (FfxInt32 x = 0; x < FFX_CACAO_QUARTER_TILE_WIDTH; ++x) |
|||
{ |
|||
FfxInt32x2 c = bufferCoord + FfxInt32x2(2*x, y); |
|||
FfxFloat32x4 centre = FfxFloat32x4(ffxUnpackF32(s_FFX_CACAO_BlurF16Front_4[c.x + 0][c.y + 0]), ffxUnpackF32(s_FFX_CACAO_BlurF16Front_4[c.x + 1][c.y + 0])); |
|||
FfxFloat32x4 top = FfxFloat32x4(ffxUnpackF32(s_FFX_CACAO_BlurF16Front_4[c.x + 0][c.y - 1]), ffxUnpackF32(s_FFX_CACAO_BlurF16Front_4[c.x + 1][c.y - 1])); |
|||
FfxFloat32x4 bottom = FfxFloat32x4(ffxUnpackF32(s_FFX_CACAO_BlurF16Front_4[c.x + 0][c.y + 1]), ffxUnpackF32(s_FFX_CACAO_BlurF16Front_4[c.x + 1][c.y + 1])); |
|||
|
|||
FfxFloat32x2 tmp = ffxUnpackF32(s_FFX_CACAO_BlurF16Front_4[c.x - 1][c.y + 0]); |
|||
FfxFloat32x4 left = FfxFloat32x4(tmp.y, centre.xyz); |
|||
tmp = ffxUnpackF32(s_FFX_CACAO_BlurF16Front_4[c.x + 2][c.y + 0]); |
|||
FfxFloat32x4 right = FfxFloat32x4(centre.yzw, tmp.x); |
|||
|
|||
FfxFloat32x4 tmp_4 = FFX_CACAO_CalcBlurredSampleF32_4(packedEdges[x][y], centre, left, right, top, bottom); |
|||
s_FFX_CACAO_BlurF16Back_4[c.x + 0][c.y] = ffxPackF32(tmp_4.xy); |
|||
s_FFX_CACAO_BlurF16Back_4[c.x + 1][c.y] = ffxPackF32(tmp_4.zw); |
|||
} |
|||
} |
|||
FFX_GROUP_MEMORY_BARRIER();; |
|||
|
|||
if (2 * i + 1 < blurPasses) |
|||
{ |
|||
FFX_UNROLL |
|||
for (FfxInt32 y = 0; y < FFX_CACAO_TILE_HEIGHT; ++y) |
|||
{ |
|||
FFX_UNROLL |
|||
for (FfxInt32 x = 0; x < FFX_CACAO_QUARTER_TILE_WIDTH; ++x) |
|||
{ |
|||
FfxInt32x2 c = bufferCoord + FfxInt32x2(2 * x, y); |
|||
FfxFloat32x4 centre = FfxFloat32x4(ffxUnpackF32(s_FFX_CACAO_BlurF16Back_4[c.x + 0][c.y + 0]), ffxUnpackF32(s_FFX_CACAO_BlurF16Back_4[c.x + 1][c.y + 0])); |
|||
FfxFloat32x4 top = FfxFloat32x4(ffxUnpackF32(s_FFX_CACAO_BlurF16Back_4[c.x + 0][c.y - 1]), ffxUnpackF32(s_FFX_CACAO_BlurF16Back_4[c.x + 1][c.y - 1])); |
|||
FfxFloat32x4 bottom = FfxFloat32x4(ffxUnpackF32(s_FFX_CACAO_BlurF16Back_4[c.x + 0][c.y + 1]), ffxUnpackF32(s_FFX_CACAO_BlurF16Back_4[c.x + 1][c.y + 1])); |
|||
|
|||
FfxFloat32x2 tmp = ffxUnpackF32(s_FFX_CACAO_BlurF16Back_4[c.x - 1][c.y + 0]); |
|||
FfxFloat32x4 left = FfxFloat32x4(tmp.y, centre.xyz); |
|||
tmp = ffxUnpackF32(s_FFX_CACAO_BlurF16Back_4[c.x + 2][c.y + 0]); |
|||
FfxFloat32x4 right = FfxFloat32x4(centre.yzw, tmp.x); |
|||
|
|||
FfxFloat32x4 tmp_4 = FFX_CACAO_CalcBlurredSampleF32_4(packedEdges[x][y], centre, left, right, top, bottom); |
|||
s_FFX_CACAO_BlurF16Front_4[c.x + 0][c.y] = ffxPackF32(tmp_4.xy); |
|||
s_FFX_CACAO_BlurF16Front_4[c.x + 1][c.y] = ffxPackF32(tmp_4.zw); |
|||
} |
|||
} |
|||
FFX_GROUP_MEMORY_BARRIER();; |
|||
} |
|||
} |
|||
|
|||
FFX_UNROLL |
|||
for (FfxUInt32 y = 0; y < FFX_CACAO_TILE_HEIGHT; ++y) |
|||
{ |
|||
FfxUInt32 outputY = FFX_CACAO_TILE_HEIGHT * tid.y + y; |
|||
if (blurPasses <= outputY && outputY < FFX_CACAO_TILE_HEIGHT * FFX_CACAO_BLUR_HEIGHT - blurPasses) |
|||
{ |
|||
FFX_UNROLL |
|||
for (FfxInt32 x = 0; x < FFX_CACAO_QUARTER_TILE_WIDTH; ++x) |
|||
{ |
|||
FfxUInt32 outputX = FFX_CACAO_TILE_WIDTH * tid.x + 4 * x; |
|||
|
|||
FfxFloat32x4 ssaoVal; |
|||
if (blurPasses % 2 == 0) |
|||
{ |
|||
ssaoVal = FfxFloat32x4(ffxUnpackF32(s_FFX_CACAO_BlurF16Front_4[bufferCoord.x + x][bufferCoord.y + y]), ffxUnpackF32(s_FFX_CACAO_BlurF16Front_4[bufferCoord.x + x + 1][bufferCoord.y + y])); |
|||
} |
|||
else |
|||
{ |
|||
ssaoVal = FfxFloat32x4(ffxUnpackF32(s_FFX_CACAO_BlurF16Back_4[bufferCoord.x + x][bufferCoord.y + y]), ffxUnpackF32(s_FFX_CACAO_BlurF16Back_4[bufferCoord.x + x + 1][bufferCoord.y + y])); |
|||
} |
|||
|
|||
if (blurPasses <= outputX && outputX < FFX_CACAO_TILE_WIDTH * FFX_CACAO_BLUR_WIDTH - blurPasses) |
|||
{ |
|||
FFX_CACAO_EdgeSensitiveBlur_StoreOutput(imageCoord + FfxInt32x2(4 * x, y), FfxFloat32x2(ssaoVal.x, packedEdges[x][y].x), layerId); |
|||
} |
|||
outputX += 1; |
|||
if (blurPasses <= outputX && outputX < FFX_CACAO_TILE_WIDTH * FFX_CACAO_BLUR_WIDTH - blurPasses) |
|||
{ |
|||
FFX_CACAO_EdgeSensitiveBlur_StoreOutput(imageCoord + FfxInt32x2(4 * x + 1, y), FfxFloat32x2(ssaoVal.y, packedEdges[x][y].y), layerId); |
|||
} |
|||
outputX += 1; |
|||
if (blurPasses <= outputX && outputX < FFX_CACAO_TILE_WIDTH * FFX_CACAO_BLUR_WIDTH - blurPasses) |
|||
{ |
|||
FFX_CACAO_EdgeSensitiveBlur_StoreOutput(imageCoord + FfxInt32x2(4 * x + 2, y), FfxFloat32x2(ssaoVal.z, packedEdges[x][y].z), layerId); |
|||
} |
|||
outputX += 1; |
|||
if (blurPasses <= outputX && outputX < FFX_CACAO_TILE_WIDTH * FFX_CACAO_BLUR_WIDTH - blurPasses) |
|||
{ |
|||
FFX_CACAO_EdgeSensitiveBlur_StoreOutput(imageCoord + FfxInt32x2(4 * x + 3, y), FfxFloat32x2(ssaoVal.w, packedEdges[x][y].w), layerId); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
#endif //FFX_HALF |
|||
|
|||
void FFX_CACAO_EdgeSensitiveBlur1(FfxUInt32x2 tid, FfxUInt32x3 gid) |
|||
{ |
|||
FfxUInt32 layerId = gid.z; |
|||
layerId = (layerId == 1 && BlurNumPasses() == 2) ? 3 : layerId; |
|||
FFX_CACAO_LDSEdgeSensitiveBlur(1, tid, gid.xy, layerId); |
|||
} |
|||
|
|||
void FFX_CACAO_EdgeSensitiveBlur2(FfxUInt32x2 tid, FfxUInt32x3 gid) |
|||
{ |
|||
FfxUInt32 layerId = gid.z; |
|||
layerId = (layerId == 1 && BlurNumPasses() == 2) ? 3 : layerId; |
|||
FFX_CACAO_LDSEdgeSensitiveBlur(2, tid, gid.xy, layerId); |
|||
} |
|||
|
|||
void FFX_CACAO_EdgeSensitiveBlur3(FfxUInt32x2 tid, FfxUInt32x3 gid) |
|||
{ |
|||
FfxUInt32 layerId = gid.z; |
|||
layerId = (layerId == 1 && BlurNumPasses() == 2) ? 3 : layerId; |
|||
FFX_CACAO_LDSEdgeSensitiveBlur(3, tid, gid.xy, layerId); |
|||
} |
|||
|
|||
void FFX_CACAO_EdgeSensitiveBlur4(FfxUInt32x2 tid, FfxUInt32x3 gid) |
|||
{ |
|||
FfxUInt32 layerId = gid.z; |
|||
layerId = (layerId == 1 && BlurNumPasses() == 2) ? 3 : layerId; |
|||
FFX_CACAO_LDSEdgeSensitiveBlur(4, tid, gid.xy, layerId); |
|||
} |
|||
|
|||
void FFX_CACAO_EdgeSensitiveBlur5(FfxUInt32x2 tid, FfxUInt32x3 gid) |
|||
{ |
|||
FfxUInt32 layerId = gid.z; |
|||
layerId = (layerId == 1 && BlurNumPasses() == 2) ? 3 : layerId; |
|||
FFX_CACAO_LDSEdgeSensitiveBlur(5, tid, gid.xy, layerId); |
|||
} |
|||
|
|||
void FFX_CACAO_EdgeSensitiveBlur6(FfxUInt32x2 tid, FfxUInt32x3 gid) |
|||
{ |
|||
FfxUInt32 layerId = gid.z; |
|||
layerId = (layerId == 1 && BlurNumPasses() == 2) ? 3 : layerId; |
|||
FFX_CACAO_LDSEdgeSensitiveBlur(6, tid, gid.xy, layerId); |
|||
} |
|||
|
|||
void FFX_CACAO_EdgeSensitiveBlur7(FfxUInt32x2 tid, FfxUInt32x3 gid) |
|||
{ |
|||
FfxUInt32 layerId = gid.z; |
|||
layerId = (layerId == 1 && BlurNumPasses() == 2) ? 3 : layerId; |
|||
FFX_CACAO_LDSEdgeSensitiveBlur(7, tid, gid.xy, layerId); |
|||
} |
|||
|
|||
void FFX_CACAO_EdgeSensitiveBlur8(FfxUInt32x2 tid, FfxUInt32x3 gid) |
|||
{ |
|||
FfxUInt32 layerId = gid.z; |
|||
layerId = (layerId == 1 && BlurNumPasses() == 2) ? 3 : layerId; |
|||
FFX_CACAO_LDSEdgeSensitiveBlur(8, tid, gid.xy, layerId); |
|||
} |
|||
|
|||
#undef FFX_CACAO_TILE_WIDTH |
|||
#undef FFX_CACAO_TILE_HEIGHT |
|||
#undef FFX_CACAO_HALF_TILE_WIDTH |
|||
#undef FFX_CACAO_QUARTER_TILE_WIDTH |
|||
#undef FFX_CACAO_ARRAY_WIDTH |
|||
#undef FFX_CACAO_ARRAY_HEIGHT |
|||
#undef FFX_CACAO_ITERS |
|||
@ -0,0 +1,27 @@ |
|||
fileFormatVersion: 2 |
|||
guid: f57b82943d5a68a41b7f0a9fdf6a420c |
|||
PluginImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
iconMap: {} |
|||
executionOrder: {} |
|||
defineConstraints: [] |
|||
isPreloaded: 0 |
|||
isOverridable: 0 |
|||
isExplicitlyReferenced: 0 |
|||
validateReferences: 1 |
|||
platformData: |
|||
- first: |
|||
Any: |
|||
second: |
|||
enabled: 1 |
|||
settings: {} |
|||
- first: |
|||
Editor: Editor |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
DefaultValueInitialized: true |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,111 @@ |
|||
// This file is part of the FidelityFX SDK. |
|||
// |
|||
// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved. |
|||
// |
|||
// 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. |
|||
|
|||
|
|||
#include "../common/ffx_core.h" |
|||
#include "ffx_cacao_defines.h" |
|||
#include "ffx_cacao_utils.h" |
|||
|
|||
void FFX_CACAO_GenerateImportanceMap(FfxUInt32x2 tid) |
|||
{ |
|||
FfxUInt32x2 basePos = tid * 2; |
|||
|
|||
FfxFloat32x2 baseUV = (FfxFloat32x2(basePos) + 1.0f) * SSAOBufferInverseDimensions(); |
|||
|
|||
FfxFloat32 avg = 0.0; |
|||
FfxFloat32 minV = 1.0; |
|||
FfxFloat32 maxV = 0.0; |
|||
FFX_UNROLL |
|||
for (FfxInt32 i = 0; i < 4; i++) |
|||
{ |
|||
FfxFloat32x4 vals = FFX_CACAO_Importance_GatherSSAO(baseUV, i); |
|||
|
|||
// apply the same modifications that would have been applied in the main shader |
|||
vals = EffectShadowStrength() * vals; |
|||
|
|||
vals = 1 - vals; |
|||
|
|||
vals = pow(ffxSaturate(vals), FfxFloat32x4(EffectShadowPow(), EffectShadowPow(), EffectShadowPow(), EffectShadowPow())); |
|||
|
|||
avg += dot(FfxFloat32x4(vals.x, vals.y, vals.z, vals.w), FfxFloat32x4(1.0 / 16.0, 1.0 / 16.0, 1.0 / 16.0, 1.0 / 16.0)); |
|||
|
|||
maxV = max(maxV, max(max(vals.x, vals.y), max(vals.z, vals.w))); |
|||
minV = min(minV, min(min(vals.x, vals.y), min(vals.z, vals.w))); |
|||
} |
|||
|
|||
FfxFloat32 minMaxDiff = maxV - minV; |
|||
|
|||
FFX_CACAO_Importance_StoreImportance(tid, pow(ffxSaturate(minMaxDiff * 2.0), 0.8f)); |
|||
} |
|||
|
|||
FFX_STATIC const FfxFloat32 c_FFX_CACAO_SmoothenImportance = 1.0f; |
|||
|
|||
void FFX_CACAO_PostprocessImportanceMapA(FfxUInt32x2 tid) |
|||
{ |
|||
FfxFloat32x2 uv = (FfxFloat32x2(tid)+0.5f) * ImportanceMapInverseDimensions(); |
|||
|
|||
FfxFloat32 centre = FFX_CACAO_Importance_SampleImportanceA(uv); |
|||
|
|||
FfxFloat32x2 halfPixel = 0.5f * ImportanceMapInverseDimensions(); |
|||
|
|||
FfxFloat32x4 vals; |
|||
vals.x = FFX_CACAO_Importance_SampleImportanceA(uv + FfxFloat32x2(-halfPixel.x * 3, -halfPixel.y)); |
|||
vals.y = FFX_CACAO_Importance_SampleImportanceA(uv + FfxFloat32x2(+halfPixel.x, -halfPixel.y * 3)); |
|||
vals.z = FFX_CACAO_Importance_SampleImportanceA(uv + FfxFloat32x2(+halfPixel.x * 3, +halfPixel.y)); |
|||
vals.w = FFX_CACAO_Importance_SampleImportanceA(uv + FfxFloat32x2(-halfPixel.x, +halfPixel.y * 3)); |
|||
|
|||
FfxFloat32 avgVal = dot(vals, FfxFloat32x4(0.25, 0.25, 0.25, 0.25)); |
|||
vals.xy = max(vals.xy, vals.zw); |
|||
FfxFloat32 maxVal = max(centre, max(vals.x, vals.y)); |
|||
|
|||
FFX_CACAO_Importance_StoreImportanceA(tid, ffxLerp(maxVal, avgVal, c_FFX_CACAO_SmoothenImportance)); |
|||
} |
|||
|
|||
void FFX_CACAO_PostprocessImportanceMapB(FfxUInt32x2 tid) |
|||
{ |
|||
FfxFloat32x2 uv = (FfxFloat32x2(tid)+0.5f) * ImportanceMapInverseDimensions(); |
|||
|
|||
FfxFloat32 centre = FFX_CACAO_Importance_SampleImportanceB(uv); |
|||
|
|||
FfxFloat32x2 halfPixel = 0.5f * ImportanceMapInverseDimensions(); |
|||
|
|||
FfxFloat32x4 vals; |
|||
vals.x = FFX_CACAO_Importance_SampleImportanceB(uv + FfxFloat32x2(-halfPixel.x, -halfPixel.y * 3)); |
|||
vals.y = FFX_CACAO_Importance_SampleImportanceB(uv + FfxFloat32x2(+halfPixel.x * 3, -halfPixel.y)); |
|||
vals.z = FFX_CACAO_Importance_SampleImportanceB(uv + FfxFloat32x2(+halfPixel.x, +halfPixel.y * 3)); |
|||
vals.w = FFX_CACAO_Importance_SampleImportanceB(uv + FfxFloat32x2(-halfPixel.x * 3, +halfPixel.y)); |
|||
|
|||
FfxFloat32 avgVal = dot(vals, FfxFloat32x4(0.25, 0.25, 0.25, 0.25)); |
|||
vals.xy = max(vals.xy, vals.zw); |
|||
FfxFloat32 maxVal = max(centre, max(vals.x, vals.y)); |
|||
|
|||
FfxFloat32 retVal = ffxLerp(maxVal, avgVal, c_FFX_CACAO_SmoothenImportance); |
|||
FFX_CACAO_Importance_StoreImportanceB(tid, retVal); |
|||
|
|||
// sum the average; to avoid overflowing we assume max AO resolution is not bigger than 16384x16384; so quarter res (used here) will be 4096x4096, which leaves us with 8 bits per pixel |
|||
FfxUInt32 sum = FfxUInt32(ffxSaturate(retVal) * 255.0 + 0.5); |
|||
|
|||
// save every 9th to avoid InterlockedAdd congestion - since we're blurring, this is good enough; compensated by multiplying LoadCounterAvgDiv by 9 |
|||
if (((tid.x % 3) + (tid.y % 3)) == 0) |
|||
{ |
|||
FFX_CACAO_Importance_LoadCounterInterlockedAdd(sum); |
|||
} |
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
fileFormatVersion: 2 |
|||
guid: d03f7988086d61c45baba0333fc498eb |
|||
PluginImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
iconMap: {} |
|||
executionOrder: {} |
|||
defineConstraints: [] |
|||
isPreloaded: 0 |
|||
isOverridable: 0 |
|||
isExplicitlyReferenced: 0 |
|||
validateReferences: 1 |
|||
platformData: |
|||
- first: |
|||
Any: |
|||
second: |
|||
enabled: 1 |
|||
settings: {} |
|||
- first: |
|||
Editor: Editor |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
DefaultValueInitialized: true |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,310 @@ |
|||
// This file is part of the FidelityFX SDK. |
|||
// |
|||
// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved. |
|||
// |
|||
// 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. |
|||
|
|||
|
|||
#include "../common/ffx_core.h" |
|||
#include "ffx_cacao_defines.h" |
|||
#include "ffx_cacao_utils.h" |
|||
|
|||
FFX_GROUPSHARED FfxFloat32 s_FFX_CACAO_PrepareDepthsAndMipsBuffer[4][8][8]; |
|||
|
|||
FfxFloat32 FFX_CACAO_MipSmartAverage(FfxFloat32x4 depths) |
|||
{ |
|||
FfxFloat32 closest = min(min(depths.x, depths.y), min(depths.z, depths.w)); |
|||
FfxFloat32 falloffCalcMulSq = -1.0f / EffectRadius() * EffectRadius(); |
|||
FfxFloat32x4 dists = depths - closest.xxxx; |
|||
FfxFloat32x4 weights = ffxSaturate(dists * dists * falloffCalcMulSq + 1.0); |
|||
return dot(weights, depths) / dot(weights, FfxFloat32x4(1.0, 1.0, 1.0, 1.0)); |
|||
} |
|||
|
|||
void FFX_CACAO_PrepareDepthsAndMips(FfxFloat32x4 samples, FfxUInt32x2 outputCoord, FfxUInt32x2 gtid) |
|||
{ |
|||
samples = FFX_CACAO_ScreenSpaceToViewSpaceDepth(samples); |
|||
|
|||
s_FFX_CACAO_PrepareDepthsAndMipsBuffer[0][gtid.x][gtid.y] = samples.w; |
|||
s_FFX_CACAO_PrepareDepthsAndMipsBuffer[1][gtid.x][gtid.y] = samples.z; |
|||
s_FFX_CACAO_PrepareDepthsAndMipsBuffer[2][gtid.x][gtid.y] = samples.x; |
|||
s_FFX_CACAO_PrepareDepthsAndMipsBuffer[3][gtid.x][gtid.y] = samples.y; |
|||
|
|||
FFX_CACAO_Prepare_StoreDepthMip0(outputCoord, 0, samples.w); |
|||
FFX_CACAO_Prepare_StoreDepthMip0(outputCoord, 1, samples.z); |
|||
FFX_CACAO_Prepare_StoreDepthMip0(outputCoord, 2, samples.x); |
|||
FFX_CACAO_Prepare_StoreDepthMip0(outputCoord, 3, samples.y); |
|||
|
|||
FfxUInt32 depthArrayIndex = 2 * (gtid.y % 2) + (gtid.x % 2); |
|||
FfxUInt32x2 depthArrayOffset = FfxInt32x2(gtid.x % 2, gtid.y % 2); |
|||
FfxInt32x2 bufferCoord = FfxInt32x2(gtid) - FfxInt32x2(depthArrayOffset); |
|||
|
|||
outputCoord /= 2; |
|||
FFX_GROUP_MEMORY_BARRIER(); |
|||
|
|||
// if (stillAlive) <-- all threads alive here |
|||
{ |
|||
FfxFloat32 sample_00 = s_FFX_CACAO_PrepareDepthsAndMipsBuffer[depthArrayIndex][bufferCoord.x + 0][bufferCoord.y + 0]; |
|||
FfxFloat32 sample_01 = s_FFX_CACAO_PrepareDepthsAndMipsBuffer[depthArrayIndex][bufferCoord.x + 0][bufferCoord.y + 1]; |
|||
FfxFloat32 sample_10 = s_FFX_CACAO_PrepareDepthsAndMipsBuffer[depthArrayIndex][bufferCoord.x + 1][bufferCoord.y + 0]; |
|||
FfxFloat32 sample_11 = s_FFX_CACAO_PrepareDepthsAndMipsBuffer[depthArrayIndex][bufferCoord.x + 1][bufferCoord.y + 1]; |
|||
|
|||
FfxFloat32 avg = FFX_CACAO_MipSmartAverage(FfxFloat32x4(sample_00, sample_01, sample_10, sample_11)); |
|||
FFX_CACAO_Prepare_StoreDepthMip1(outputCoord, depthArrayIndex, avg); |
|||
s_FFX_CACAO_PrepareDepthsAndMipsBuffer[depthArrayIndex][bufferCoord.x][bufferCoord.y] = avg; |
|||
} |
|||
|
|||
bool stillAlive = gtid.x % 4 == depthArrayOffset.x && gtid.y % 4 == depthArrayOffset.y; |
|||
|
|||
outputCoord /= 2; |
|||
FFX_GROUP_MEMORY_BARRIER(); |
|||
|
|||
if (stillAlive) |
|||
{ |
|||
FfxFloat32 sample_00 = s_FFX_CACAO_PrepareDepthsAndMipsBuffer[depthArrayIndex][bufferCoord.x + 0][bufferCoord.y + 0]; |
|||
FfxFloat32 sample_01 = s_FFX_CACAO_PrepareDepthsAndMipsBuffer[depthArrayIndex][bufferCoord.x + 0][bufferCoord.y + 2]; |
|||
FfxFloat32 sample_10 = s_FFX_CACAO_PrepareDepthsAndMipsBuffer[depthArrayIndex][bufferCoord.x + 2][bufferCoord.y + 0]; |
|||
FfxFloat32 sample_11 = s_FFX_CACAO_PrepareDepthsAndMipsBuffer[depthArrayIndex][bufferCoord.x + 2][bufferCoord.y + 2]; |
|||
|
|||
FfxFloat32 avg = FFX_CACAO_MipSmartAverage(FfxFloat32x4(sample_00, sample_01, sample_10, sample_11)); |
|||
FFX_CACAO_Prepare_StoreDepthMip2(outputCoord, depthArrayIndex, avg); |
|||
s_FFX_CACAO_PrepareDepthsAndMipsBuffer[depthArrayIndex][bufferCoord.x][bufferCoord.y] = avg; |
|||
} |
|||
|
|||
stillAlive = gtid.x % 8 == depthArrayOffset.x && gtid.y % 8 == depthArrayOffset.y; |
|||
|
|||
outputCoord /= 2; |
|||
FFX_GROUP_MEMORY_BARRIER(); |
|||
|
|||
if (stillAlive) |
|||
{ |
|||
FfxFloat32 sample_00 = s_FFX_CACAO_PrepareDepthsAndMipsBuffer[depthArrayIndex][bufferCoord.x + 0][bufferCoord.y + 0]; |
|||
FfxFloat32 sample_01 = s_FFX_CACAO_PrepareDepthsAndMipsBuffer[depthArrayIndex][bufferCoord.x + 0][bufferCoord.y + 4]; |
|||
FfxFloat32 sample_10 = s_FFX_CACAO_PrepareDepthsAndMipsBuffer[depthArrayIndex][bufferCoord.x + 4][bufferCoord.y + 0]; |
|||
FfxFloat32 sample_11 = s_FFX_CACAO_PrepareDepthsAndMipsBuffer[depthArrayIndex][bufferCoord.x + 4][bufferCoord.y + 4]; |
|||
|
|||
FfxFloat32 avg = FFX_CACAO_MipSmartAverage(FfxFloat32x4(sample_00, sample_01, sample_10, sample_11)); |
|||
FFX_CACAO_Prepare_StoreDepthMip3(outputCoord, depthArrayIndex, avg); |
|||
} |
|||
} |
|||
|
|||
void FFX_CACAO_PrepareDownsampledDepthsAndMips(FfxUInt32x2 tid, FfxUInt32x2 gtid) |
|||
{ |
|||
FfxInt32x2 depthBufferCoord = 4 * FfxInt32x2(tid.xy); |
|||
FfxInt32x2 outputCoord = FfxInt32x2(tid); |
|||
|
|||
FfxFloat32x2 uv = (FfxFloat32x2(depthBufferCoord)+0.5f) * DepthBufferInverseDimensions(); |
|||
FfxFloat32x4 samples = FFX_CACAO_Prepare_SampleDepthOffsets(uv); |
|||
|
|||
FFX_CACAO_PrepareDepthsAndMips(samples, outputCoord, gtid); |
|||
} |
|||
|
|||
void FFX_CACAO_PrepareNativeDepthsAndMips(FfxUInt32x2 tid, FfxUInt32x2 gtid) |
|||
{ |
|||
FfxInt32x2 depthBufferCoord = 2 * FfxInt32x2(tid.xy); |
|||
FfxInt32x2 outputCoord = FfxInt32x2(tid); |
|||
|
|||
FfxFloat32x2 uv = (FfxFloat32x2(depthBufferCoord)+ 1.0f) * DepthBufferInverseDimensions(); |
|||
FfxFloat32x4 samples = FFX_CACAO_Prepare_GatherDepth(uv); |
|||
|
|||
FFX_CACAO_PrepareDepthsAndMips(samples, outputCoord, gtid); |
|||
} |
|||
|
|||
void FFX_CACAO_PrepareDepths(FfxFloat32x4 samples, FfxUInt32x2 tid) |
|||
{ |
|||
samples = FFX_CACAO_ScreenSpaceToViewSpaceDepth(samples); |
|||
FFX_CACAO_Prepare_StoreDepth(tid, 0, samples.w); |
|||
FFX_CACAO_Prepare_StoreDepth(tid, 1, samples.z); |
|||
FFX_CACAO_Prepare_StoreDepth(tid, 2, samples.x); |
|||
FFX_CACAO_Prepare_StoreDepth(tid, 3, samples.y); |
|||
} |
|||
|
|||
void FFX_CACAO_PrepareDownsampledDepths(FfxUInt32x2 tid) |
|||
{ |
|||
FfxInt32x2 depthBufferCoord = 4 * FfxInt32x2(tid.xy); |
|||
|
|||
FfxFloat32x2 uv = (FfxFloat32x2(depthBufferCoord)+0.5f) * DepthBufferInverseDimensions(); |
|||
FfxFloat32x4 samples = FFX_CACAO_Prepare_SampleDepthOffsets(uv); |
|||
|
|||
FFX_CACAO_PrepareDepths(samples, tid); |
|||
} |
|||
|
|||
void FFX_CACAO_PrepareNativeDepths(FfxUInt32x2 tid) |
|||
{ |
|||
FfxInt32x2 depthBufferCoord = 2 * FfxInt32x2(tid.xy); |
|||
|
|||
FfxFloat32x2 uv = (FfxFloat32x2(depthBufferCoord) + 1.0f) * DepthBufferInverseDimensions(); |
|||
FfxFloat32x4 samples = FFX_CACAO_Prepare_GatherDepth(uv); |
|||
|
|||
FFX_CACAO_PrepareDepths(samples, tid); |
|||
} |
|||
|
|||
void FFX_CACAO_PrepareDownsampledDepthsHalf(FfxUInt32x2 tid) |
|||
{ |
|||
FfxFloat32 sample_00 = FFX_CACAO_Prepare_LoadDepth(FfxInt32x2(4 * tid.x + 0, 4 * tid.y + 0)); |
|||
FfxFloat32 sample_11 = FFX_CACAO_Prepare_LoadDepth(FfxInt32x2(4 * tid.x + 2, 4 * tid.y + 2)); |
|||
sample_00 = FFX_CACAO_ScreenSpaceToViewSpaceDepth(sample_00); |
|||
sample_11 = FFX_CACAO_ScreenSpaceToViewSpaceDepth(sample_11); |
|||
FFX_CACAO_Prepare_StoreDepth(tid, 0, sample_00); |
|||
FFX_CACAO_Prepare_StoreDepth(tid, 3, sample_11); |
|||
} |
|||
|
|||
void FFX_CACAO_PrepareNativeDepthsHalf(FfxUInt32x2 tid) |
|||
{ |
|||
FfxFloat32 sample_00 = FFX_CACAO_Prepare_LoadDepth(FfxInt32x2(2 * tid.x + 0, 2 * tid.y + 0)); |
|||
FfxFloat32 sample_11 = FFX_CACAO_Prepare_LoadDepth(FfxInt32x2(2 * tid.x + 1, 2 * tid.y + 1)); |
|||
sample_00 = FFX_CACAO_ScreenSpaceToViewSpaceDepth(sample_00); |
|||
sample_11 = FFX_CACAO_ScreenSpaceToViewSpaceDepth(sample_11); |
|||
FFX_CACAO_Prepare_StoreDepth(tid, 0, sample_00); |
|||
FFX_CACAO_Prepare_StoreDepth(tid, 3, sample_11); |
|||
} |
|||
|
|||
struct FFX_CACAO_PrepareNormalsInputDepths |
|||
{ |
|||
FfxFloat32 depth_10; |
|||
FfxFloat32 depth_20; |
|||
|
|||
FfxFloat32 depth_01; |
|||
FfxFloat32 depth_11; |
|||
FfxFloat32 depth_21; |
|||
FfxFloat32 depth_31; |
|||
|
|||
FfxFloat32 depth_02; |
|||
FfxFloat32 depth_12; |
|||
FfxFloat32 depth_22; |
|||
FfxFloat32 depth_32; |
|||
|
|||
FfxFloat32 depth_13; |
|||
FfxFloat32 depth_23; |
|||
}; |
|||
|
|||
void FFX_CACAO_PrepareNormals(FFX_CACAO_PrepareNormalsInputDepths depths, FfxFloat32x2 uv, FfxFloat32x2 pixelSize, FfxUInt32x2 normalCoord) |
|||
{ |
|||
FfxFloat32x3 p_10 = FFX_CACAO_NDCToViewSpace(uv + FfxFloat32x2(+0.0f, -1.0f) * pixelSize, depths.depth_10); |
|||
FfxFloat32x3 p_20 = FFX_CACAO_NDCToViewSpace(uv + FfxFloat32x2(+1.0f, -1.0f) * pixelSize, depths.depth_20); |
|||
|
|||
FfxFloat32x3 p_01 = FFX_CACAO_NDCToViewSpace(uv + FfxFloat32x2(-1.0f, +0.0f) * pixelSize, depths.depth_01); |
|||
FfxFloat32x3 p_11 = FFX_CACAO_NDCToViewSpace(uv + FfxFloat32x2(+0.0f, +0.0f) * pixelSize, depths.depth_11); |
|||
FfxFloat32x3 p_21 = FFX_CACAO_NDCToViewSpace(uv + FfxFloat32x2(+1.0f, +0.0f) * pixelSize, depths.depth_21); |
|||
FfxFloat32x3 p_31 = FFX_CACAO_NDCToViewSpace(uv + FfxFloat32x2(+2.0f, +0.0f) * pixelSize, depths.depth_31); |
|||
|
|||
FfxFloat32x3 p_02 = FFX_CACAO_NDCToViewSpace(uv + FfxFloat32x2(-1.0f, +1.0f) * pixelSize, depths.depth_02); |
|||
FfxFloat32x3 p_12 = FFX_CACAO_NDCToViewSpace(uv + FfxFloat32x2(+0.0f, +1.0f) * pixelSize, depths.depth_12); |
|||
FfxFloat32x3 p_22 = FFX_CACAO_NDCToViewSpace(uv + FfxFloat32x2(+1.0f, +1.0f) * pixelSize, depths.depth_22); |
|||
FfxFloat32x3 p_32 = FFX_CACAO_NDCToViewSpace(uv + FfxFloat32x2(+2.0f, +1.0f) * pixelSize, depths.depth_32); |
|||
|
|||
FfxFloat32x3 p_13 = FFX_CACAO_NDCToViewSpace(uv + FfxFloat32x2(+0.0f, +2.0f) * pixelSize, depths.depth_13); |
|||
FfxFloat32x3 p_23 = FFX_CACAO_NDCToViewSpace(uv + FfxFloat32x2(+1.0f, +2.0f) * pixelSize, depths.depth_23); |
|||
|
|||
FfxFloat32x4 edges_11 = FFX_CACAO_CalculateEdges(p_11.z, p_01.z, p_21.z, p_10.z, p_12.z); |
|||
FfxFloat32x4 edges_21 = FFX_CACAO_CalculateEdges(p_21.z, p_11.z, p_31.z, p_20.z, p_22.z); |
|||
FfxFloat32x4 edges_12 = FFX_CACAO_CalculateEdges(p_12.z, p_02.z, p_22.z, p_11.z, p_13.z); |
|||
FfxFloat32x4 edges_22 = FFX_CACAO_CalculateEdges(p_22.z, p_12.z, p_32.z, p_21.z, p_23.z); |
|||
|
|||
FfxFloat32x3 norm_11 = FFX_CACAO_CalculateNormal(edges_11, p_11, p_01, p_21, p_10, p_12); |
|||
FfxFloat32x3 norm_21 = FFX_CACAO_CalculateNormal(edges_21, p_21, p_11, p_31, p_20, p_22); |
|||
FfxFloat32x3 norm_12 = FFX_CACAO_CalculateNormal(edges_12, p_12, p_02, p_22, p_11, p_13); |
|||
FfxFloat32x3 norm_22 = FFX_CACAO_CalculateNormal(edges_22, p_22, p_12, p_32, p_21, p_23); |
|||
|
|||
FFX_CACAO_Prepare_StoreNormal(normalCoord, 0, norm_11); |
|||
FFX_CACAO_Prepare_StoreNormal(normalCoord, 1, norm_21); |
|||
FFX_CACAO_Prepare_StoreNormal(normalCoord, 2, norm_12); |
|||
FFX_CACAO_Prepare_StoreNormal(normalCoord, 3, norm_22); |
|||
} |
|||
|
|||
void FFX_CACAO_PrepareDownsampledNormals(FfxUInt32x2 tid) |
|||
{ |
|||
FfxInt32x2 depthCoord = 4 * FfxInt32x2(tid) + DepthBufferOffset(); |
|||
|
|||
FFX_CACAO_PrepareNormalsInputDepths depths; |
|||
|
|||
depths.depth_10 = FFX_CACAO_ScreenSpaceToViewSpaceDepth(FFX_CACAO_Prepare_LoadDepthOffset(depthCoord, FfxInt32x2(+0, -2))); |
|||
depths.depth_20 = FFX_CACAO_ScreenSpaceToViewSpaceDepth(FFX_CACAO_Prepare_LoadDepthOffset(depthCoord, FfxInt32x2(+2, -2))); |
|||
|
|||
depths.depth_01 = FFX_CACAO_ScreenSpaceToViewSpaceDepth(FFX_CACAO_Prepare_LoadDepthOffset(depthCoord, FfxInt32x2(-2, +0))); |
|||
depths.depth_11 = FFX_CACAO_ScreenSpaceToViewSpaceDepth(FFX_CACAO_Prepare_LoadDepthOffset(depthCoord, FfxInt32x2(+0, +0))); |
|||
depths.depth_21 = FFX_CACAO_ScreenSpaceToViewSpaceDepth(FFX_CACAO_Prepare_LoadDepthOffset(depthCoord, FfxInt32x2(+2, +0))); |
|||
depths.depth_31 = FFX_CACAO_ScreenSpaceToViewSpaceDepth(FFX_CACAO_Prepare_LoadDepthOffset(depthCoord, FfxInt32x2(+4, +0))); |
|||
|
|||
depths.depth_02 = FFX_CACAO_ScreenSpaceToViewSpaceDepth(FFX_CACAO_Prepare_LoadDepthOffset(depthCoord, FfxInt32x2(-2, +2))); |
|||
depths.depth_12 = FFX_CACAO_ScreenSpaceToViewSpaceDepth(FFX_CACAO_Prepare_LoadDepthOffset(depthCoord, FfxInt32x2(+0, +2))); |
|||
depths.depth_22 = FFX_CACAO_ScreenSpaceToViewSpaceDepth(FFX_CACAO_Prepare_LoadDepthOffset(depthCoord, FfxInt32x2(+2, +2))); |
|||
depths.depth_32 = FFX_CACAO_ScreenSpaceToViewSpaceDepth(FFX_CACAO_Prepare_LoadDepthOffset(depthCoord, FfxInt32x2(+4, +2))); |
|||
|
|||
depths.depth_13 = FFX_CACAO_ScreenSpaceToViewSpaceDepth(FFX_CACAO_Prepare_LoadDepthOffset(depthCoord, FfxInt32x2(+0, +4))); |
|||
depths.depth_23 = FFX_CACAO_ScreenSpaceToViewSpaceDepth(FFX_CACAO_Prepare_LoadDepthOffset(depthCoord, FfxInt32x2(+2, +4))); |
|||
|
|||
FfxFloat32x2 pixelSize = 2.0f * OutputBufferInverseDimensions(); |
|||
FfxFloat32x2 uv = (FfxFloat32x2(4 * tid) + 0.5f) * OutputBufferInverseDimensions(); |
|||
|
|||
FFX_CACAO_PrepareNormals(depths, uv, pixelSize, tid); |
|||
} |
|||
|
|||
void FFX_CACAO_PrepareNativeNormals(FfxUInt32x2 tid) |
|||
{ |
|||
FfxInt32x2 depthCoord = 2 * FfxInt32x2(tid) + DepthBufferOffset(); |
|||
FfxFloat32x2 depthBufferUV = FfxFloat32x2(depthCoord) * DepthBufferInverseDimensions(); |
|||
FfxFloat32x4 samples_00 = FFX_CACAO_Prepare_GatherDepthOffset(depthBufferUV, FfxInt32x2(0, 0)); //CACAO_TODO fix gather |
|||
FfxFloat32x4 samples_10 = FFX_CACAO_Prepare_GatherDepthOffset(depthBufferUV, FfxInt32x2(2, 0)); |
|||
FfxFloat32x4 samples_01 = FFX_CACAO_Prepare_GatherDepthOffset(depthBufferUV, FfxInt32x2(0, 2)); |
|||
FfxFloat32x4 samples_11 = FFX_CACAO_Prepare_GatherDepthOffset(depthBufferUV, FfxInt32x2(2, 2)); |
|||
|
|||
FFX_CACAO_PrepareNormalsInputDepths depths; |
|||
|
|||
depths.depth_10 = FFX_CACAO_ScreenSpaceToViewSpaceDepth(samples_00.z); |
|||
depths.depth_20 = FFX_CACAO_ScreenSpaceToViewSpaceDepth(samples_10.w); |
|||
|
|||
depths.depth_01 = FFX_CACAO_ScreenSpaceToViewSpaceDepth(samples_00.x); |
|||
depths.depth_11 = FFX_CACAO_ScreenSpaceToViewSpaceDepth(samples_00.y); |
|||
depths.depth_21 = FFX_CACAO_ScreenSpaceToViewSpaceDepth(samples_10.x); |
|||
depths.depth_31 = FFX_CACAO_ScreenSpaceToViewSpaceDepth(samples_10.y); |
|||
|
|||
depths.depth_02 = FFX_CACAO_ScreenSpaceToViewSpaceDepth(samples_01.w); |
|||
depths.depth_12 = FFX_CACAO_ScreenSpaceToViewSpaceDepth(samples_01.z); |
|||
depths.depth_22 = FFX_CACAO_ScreenSpaceToViewSpaceDepth(samples_11.w); |
|||
depths.depth_32 = FFX_CACAO_ScreenSpaceToViewSpaceDepth(samples_11.z); |
|||
|
|||
depths.depth_13 = FFX_CACAO_ScreenSpaceToViewSpaceDepth(samples_01.y); |
|||
depths.depth_23 = FFX_CACAO_ScreenSpaceToViewSpaceDepth(samples_11.x); |
|||
|
|||
// use unused samples to make sure compiler doesn't overlap memory and put a sync |
|||
// between loads |
|||
FfxFloat32 epsilon = (samples_00.w + samples_10.z + samples_01.x + samples_11.y) * 1e-20f; |
|||
|
|||
FfxFloat32x2 pixelSize = OutputBufferInverseDimensions(); |
|||
FfxFloat32x2 uv = (FfxFloat32x2(2 * tid) + 0.5f + epsilon) * OutputBufferInverseDimensions(); |
|||
|
|||
FFX_CACAO_PrepareNormals(depths, uv, pixelSize, tid); |
|||
} |
|||
|
|||
void FFX_CACAO_PrepareDownsampledNormalsFromInputNormals(FfxUInt32x2 tid) |
|||
{ |
|||
FfxUInt32x2 baseCoord = 4 * tid; |
|||
FFX_CACAO_Prepare_StoreNormal(tid, 0, FFX_CACAO_Prepare_LoadNormal(baseCoord + FfxUInt32x2(0, 0))); |
|||
FFX_CACAO_Prepare_StoreNormal(tid, 1, FFX_CACAO_Prepare_LoadNormal(baseCoord + FfxUInt32x2(2, 0))); |
|||
FFX_CACAO_Prepare_StoreNormal(tid, 2, FFX_CACAO_Prepare_LoadNormal(baseCoord + FfxUInt32x2(0, 2))); |
|||
FFX_CACAO_Prepare_StoreNormal(tid, 3, FFX_CACAO_Prepare_LoadNormal(baseCoord + FfxUInt32x2(2, 2))); |
|||
} |
|||
|
|||
void FFX_CACAO_PrepareNativeNormalsFromInputNormals(FfxUInt32x2 tid) |
|||
{ |
|||
FfxUInt32x2 baseCoord = 2 * tid; |
|||
FFX_CACAO_Prepare_StoreNormal(tid, 0, FFX_CACAO_Prepare_LoadNormal(baseCoord + FfxUInt32x2(0, 0))); |
|||
FFX_CACAO_Prepare_StoreNormal(tid, 1, FFX_CACAO_Prepare_LoadNormal(baseCoord + FfxUInt32x2(1, 0))); |
|||
FFX_CACAO_Prepare_StoreNormal(tid, 2, FFX_CACAO_Prepare_LoadNormal(baseCoord + FfxUInt32x2(0, 1))); |
|||
FFX_CACAO_Prepare_StoreNormal(tid, 3, FFX_CACAO_Prepare_LoadNormal(baseCoord + FfxUInt32x2(1, 1))); |
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 1e156b1c5a7de7e45817b3d328aa0178 |
|||
PluginImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
iconMap: {} |
|||
executionOrder: {} |
|||
defineConstraints: [] |
|||
isPreloaded: 0 |
|||
isOverridable: 0 |
|||
isExplicitlyReferenced: 0 |
|||
validateReferences: 1 |
|||
platformData: |
|||
- first: |
|||
Any: |
|||
second: |
|||
enabled: 1 |
|||
settings: {} |
|||
- first: |
|||
Editor: Editor |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
DefaultValueInitialized: true |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,50 @@ |
|||
// This file is part of the FidelityFX SDK. |
|||
// |
|||
// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved. |
|||
// |
|||
// 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. |
|||
|
|||
|
|||
#ifndef FFX_CACAO_RESOURCES_H |
|||
#define FFX_CACAO_RESOURCES_H |
|||
|
|||
#if defined(FFX_CPU) || defined(FFX_GPU) |
|||
#define FFX_FSR2_RESOURCE_IDENTIFIER_NULL 0 |
|||
#define FFX_CACAO_RESOURCE_IDENTIFIER_DEPTH_IN 1 |
|||
#define FFX_CACAO_RESOURCE_IDENTIFIER_NORMAL_IN 2 |
|||
#define FFX_CACAO_RESOURCE_IDENTIFIER_DEINTERLEAVED_DEPTHS 3 |
|||
#define FFX_CACAO_RESOURCE_IDENTIFIER_DEINTERLEAVED_NORMALS 4 |
|||
#define FFX_CACAO_RESOURCE_IDENTIFIER_SSAO_BUFFER_PING 5 |
|||
#define FFX_CACAO_RESOURCE_IDENTIFIER_SSAO_BUFFER_PONG 6 |
|||
#define FFX_CACAO_RESOURCE_IDENTIFIER_IMPORTANCE_MAP 7 |
|||
#define FFX_CACAO_RESOURCE_IDENTIFIER_IMPORTANCE_MAP_PONG 8 |
|||
#define FFX_CACAO_RESOURCE_IDENTIFIER_DOWNSAMPLED_SSAO_BUFFER 9 |
|||
#define FFX_CACAO_RESOURCE_IDENTIFIER_LOAD_COUNTER_BUFFER 10 |
|||
#define FFX_CACAO_RESOURCE_IDENTIFIER_OUTPUT 11 |
|||
#define FFX_CACAO_RESOURCE_IDENTIFIER_DOWNSAMPLED_DEPTH_MIPMAP_0 12 |
|||
#define FFX_CACAO_RESOURCE_IDENTIFIER_DOWNSAMPLED_DEPTH_MIPMAP_1 13 |
|||
#define FFX_CACAO_RESOURCE_IDENTIFIER_DOWNSAMPLED_DEPTH_MIPMAP_2 14 |
|||
#define FFX_CACAO_RESOURCE_IDENTIFIER_DOWNSAMPLED_DEPTH_MIPMAP_3 15 |
|||
#define FFX_CACAO_RESOURCE_IDENTIFIER_COUNT 16 |
|||
|
|||
#define FFX_CACAO_CONSTANTBUFFER_IDENTIFIER_CACAO 0 |
|||
#define FFX_CACAO_CONSTANTBUFFER_IDENTIFIER_COUNT 1 |
|||
|
|||
#endif // #if defined(FFX_CPU) || defined(FFX_GPU) |
|||
|
|||
#endif //!defined( FFX_FSR2_RESOURCES_H ) |
|||
@ -0,0 +1,27 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 573794d721e22f94886660f44dd9de11 |
|||
PluginImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
iconMap: {} |
|||
executionOrder: {} |
|||
defineConstraints: [] |
|||
isPreloaded: 0 |
|||
isOverridable: 0 |
|||
isExplicitlyReferenced: 0 |
|||
validateReferences: 1 |
|||
platformData: |
|||
- first: |
|||
Any: |
|||
second: |
|||
enabled: 1 |
|||
settings: {} |
|||
- first: |
|||
Editor: Editor |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
DefaultValueInitialized: true |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,616 @@ |
|||
// This file is part of the FidelityFX SDK. |
|||
// |
|||
// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved. |
|||
// |
|||
// 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. |
|||
|
|||
|
|||
#include "../common/ffx_core.h" |
|||
#include "ffx_cacao_defines.h" |
|||
#include "ffx_cacao_utils.h" |
|||
|
|||
FFX_STATIC const FfxFloat32x4 g_FFX_CACAO_samplePatternMain[] = |
|||
{ |
|||
{ 0.78488064, 0.56661671, 1.500000, -0.126083}, { 0.26022232, -0.29575172, 1.500000, -1.064030}, { 0.10459357, 0.08372527, 1.110000, -2.730563}, {-0.68286800, 0.04963045, 1.090000, -0.498827}, |
|||
{-0.13570161, -0.64190155, 1.250000, -0.532765}, {-0.26193795, -0.08205118, 0.670000, -1.783245}, {-0.61177456, 0.66664219, 0.710000, -0.044234}, { 0.43675563, 0.25119025, 0.610000, -1.167283}, |
|||
{ 0.07884444, 0.86618668, 0.640000, -0.459002}, {-0.12790935, -0.29869005, 0.600000, -1.729424}, {-0.04031125, 0.02413622, 0.600000, -4.792042}, { 0.16201244, -0.52851415, 0.790000, -1.067055}, |
|||
{-0.70991218, 0.47301072, 0.640000, -0.335236}, { 0.03277707, -0.22349690, 0.600000, -1.982384}, { 0.68921727, 0.36800742, 0.630000, -0.266718}, { 0.29251814, 0.37775412, 0.610000, -1.422520}, |
|||
{-0.12224089, 0.96582592, 0.600000, -0.426142}, { 0.11071457, -0.16131058, 0.600000, -2.165947}, { 0.46562141, -0.59747696, 0.600000, -0.189760}, {-0.51548797, 0.11804193, 0.600000, -1.246800}, |
|||
{ 0.89141309, -0.42090443, 0.600000, 0.028192}, {-0.32402530, -0.01591529, 0.600000, -1.543018}, { 0.60771245, 0.41635221, 0.600000, -0.605411}, { 0.02379565, -0.08239821, 0.600000, -3.809046}, |
|||
{ 0.48951152, -0.23657045, 0.600000, -1.189011}, {-0.17611565, -0.81696892, 0.600000, -0.513724}, {-0.33930185, -0.20732205, 0.600000, -1.698047}, {-0.91974425, 0.05403209, 0.600000, 0.062246}, |
|||
{-0.15064627, -0.14949332, 0.600000, -1.896062}, { 0.53180975, -0.35210401, 0.600000, -0.758838}, { 0.41487166, 0.81442589, 0.600000, -0.505648}, {-0.24106961, -0.32721516, 0.600000, -1.665244} |
|||
}; |
|||
|
|||
#define FFX_CACAO_MAX_TAPS (32) |
|||
#define FFX_CACAO_ADAPTIVE_TAP_BASE_COUNT (5) |
|||
#define FFX_CACAO_ADAPTIVE_TAP_FLEXIBLE_COUNT (FFX_CACAO_MAX_TAPS - FFX_CACAO_ADAPTIVE_TAP_BASE_COUNT) |
|||
|
|||
// these values can be changed (up to FFX_CACAO_MAX_TAPS) with no changes required elsewhere; values for 4th and 5th preset are ignored but array needed to avoid compilation errors |
|||
// the actual number of texture samples is two times this value (each "tap" has two symmetrical depth texture samples) |
|||
FFX_STATIC const FfxUInt32 g_FFX_CACAO_numTaps[5] = {3, 5, 12, 0, 0}; |
|||
|
|||
|
|||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|||
// |
|||
// Optional parts that can be enabled for a required quality preset level and above (0 == Low, 1 == Medium, 2 == High, 3 == Highest/Adaptive, 4 == reference/unused ) |
|||
// Each has its own cost. To disable just set to 5 or above. |
|||
// |
|||
// (experimental) tilts the disk (although only half of the samples!) towards surface normal; this helps with effect uniformity between objects but reduces effect distance and has other side-effects |
|||
#define FFX_CACAO_TILT_SAMPLES_ENABLE_AT_QUALITY_PRESET (99) // to disable simply set to 99 or similar |
|||
#define FFX_CACAO_TILT_SAMPLES_AMOUNT (0.4) |
|||
// |
|||
#define FFX_CACAO_HALOING_REDUCTION_ENABLE_AT_QUALITY_PRESET (1) // to disable simply set to 99 or similar |
|||
#define FFX_CACAO_HALOING_REDUCTION_AMOUNT (0.6) // values from 0.0 - 1.0, 1.0 means max weighting (will cause artifacts, 0.8 is more reasonable) |
|||
// |
|||
#define FFX_CACAO_NORMAL_BASED_EDGES_ENABLE_AT_QUALITY_PRESET (2) //2 // to disable simply set to 99 or similar |
|||
#define FFX_CACAO_NORMAL_BASED_EDGES_DOT_THRESHOLD (0.5) // use 0-0.1 for super-sharp normal-based edges |
|||
// |
|||
#define FFX_CACAO_DETAIL_AO_ENABLE_AT_QUALITY_PRESET (1) //1 // whether to use DetailAOStrength; to disable simply set to 99 or similar |
|||
// |
|||
#define FFX_CACAO_DEPTH_MIPS_ENABLE_AT_QUALITY_PRESET (2) // !!warning!! the MIP generation on the C++ side will be enabled on quality preset 2 regardless of this value, so if changing here, change the C++ side too |
|||
#define FFX_CACAO_DEPTH_MIPS_GLOBAL_OFFSET (-4.3) // best noise/quality/performance tradeoff, found empirically |
|||
// |
|||
// !!warning!! the edge handling is hard-coded to 'disabled' on quality level 0, and enabled above, on the C++ side; while toggling it here will work for |
|||
// testing purposes, it will not yield performance gains (or correct results) |
|||
#define FFX_CACAO_DEPTH_BASED_EDGES_ENABLE_AT_QUALITY_PRESET (1) |
|||
// |
|||
#define FFX_CACAO_REDUCE_RADIUS_NEAR_SCREEN_BORDER_ENABLE_AT_QUALITY_PRESET (99) // 99 means disabled; only helpful if artifacts at the edges caused by lack of out of screen depth data are not acceptable with the depth sampler in either clamp or mirror modes |
|||
|
|||
// ======================================================================================================= |
|||
// SSAO Generation |
|||
|
|||
// calculate effect radius and fit our screen sampling pattern inside it |
|||
void FFX_CACAO_CalculateRadiusParameters(const FfxFloat32 pixCenterLength, const FfxFloat32x2 pixelDirRBViewspaceSizeAtCenterZ, out FfxFloat32 pixLookupRadiusMod, out FfxFloat32 effectRadius, out FfxFloat32 falloffCalcMulSq) |
|||
{ |
|||
effectRadius = EffectRadius(); |
|||
|
|||
// leaving this out for performance reasons: use something similar if radius needs to scale based on distance |
|||
//effectRadius *= pow( pixCenterLength, RadiusDistanceScalingFunctionPow()); |
|||
|
|||
// when too close, on-screen sampling disk will grow beyond screen size; limit this to avoid closeup temporal artifacts |
|||
const FfxFloat32 tooCloseLimitMod = ffxSaturate(pixCenterLength * EffectSamplingRadiusNearLimitRec()) * 0.8 + 0.2; |
|||
|
|||
effectRadius *= tooCloseLimitMod; |
|||
|
|||
// 0.85 is to reduce the radius to allow for more samples on a slope to still stay within influence |
|||
pixLookupRadiusMod = (0.85 * effectRadius) / pixelDirRBViewspaceSizeAtCenterZ.x; |
|||
|
|||
// used to calculate falloff (both for AO samples and per-sample weights) |
|||
falloffCalcMulSq = -1.0f / (effectRadius*effectRadius); |
|||
} |
|||
|
|||
// all vectors in viewspace |
|||
FfxFloat32 FFX_CACAO_CalculatePixelObscurance(FfxFloat32x3 pixelNormal, FfxFloat32x3 hitDelta, FfxFloat32 falloffCalcMulSq) |
|||
{ |
|||
FfxFloat32 lengthSq = dot(hitDelta, hitDelta); |
|||
FfxFloat32 NdotD = dot(pixelNormal, hitDelta) / sqrt(lengthSq); |
|||
|
|||
FfxFloat32 falloffMult = max(0.0, lengthSq * falloffCalcMulSq + 1.0); |
|||
|
|||
return max(0, NdotD - EffectHorizonAngleThreshold()) * falloffMult; |
|||
} |
|||
|
|||
void FFX_CACAO_SSAOTapInner(const FfxInt32 qualityLevel, |
|||
inout FfxFloat32 obscuranceSum, |
|||
inout FfxFloat32 weightSum, |
|||
const FfxFloat32x2 samplingUV, |
|||
const FfxFloat32 mipLevel, |
|||
const FfxFloat32x3 pixCenterPos, |
|||
const FfxFloat32x3 negViewspaceDir, |
|||
FfxFloat32x3 pixelNormal, |
|||
const FfxFloat32 falloffCalcMulSq, |
|||
const FfxFloat32 weightMod, |
|||
const FfxInt32 dbgTapIndex, |
|||
FfxUInt32 layerId) |
|||
{ |
|||
// get depth at sample |
|||
FfxFloat32 viewspaceSampleZ = FFX_CACAO_SSAOGeneration_SampleViewspaceDepthMip(samplingUV, mipLevel, layerId); |
|||
|
|||
// convert to viewspace |
|||
FfxFloat32x3 hitPos = FFX_CACAO_DepthBufferUVToViewSpace(samplingUV.xy, viewspaceSampleZ).xyz; |
|||
FfxFloat32x3 hitDelta = hitPos - pixCenterPos; |
|||
|
|||
FfxFloat32 obscurance = FFX_CACAO_CalculatePixelObscurance(pixelNormal, hitDelta, falloffCalcMulSq); |
|||
FfxFloat32 weight = 1.0; |
|||
|
|||
if (qualityLevel >= FFX_CACAO_HALOING_REDUCTION_ENABLE_AT_QUALITY_PRESET) |
|||
{ |
|||
//FfxFloat32 reduct = max( 0, dot( hitDelta, negViewspaceDir ) ); |
|||
FfxFloat32 reduct = max(0, -hitDelta.z); // cheaper, less correct version |
|||
reduct = ffxSaturate(reduct * NegRecEffectRadius() + 2.0); // ffxSaturate( 2.0 - reduct / EffectRadius() ); |
|||
weight = FFX_CACAO_HALOING_REDUCTION_AMOUNT * reduct + (1.0 - FFX_CACAO_HALOING_REDUCTION_AMOUNT); |
|||
} |
|||
weight *= weightMod; |
|||
obscuranceSum += obscurance * weight; |
|||
weightSum += weight; |
|||
} |
|||
|
|||
void FFX_CACAO_SSAOTap(const FfxInt32 qualityLevel, |
|||
inout FfxFloat32 obscuranceSum, |
|||
inout FfxFloat32 weightSum, |
|||
const FfxInt32 tapIndex, |
|||
const FfxFloat32x2x2 rotScale, |
|||
const FfxFloat32x3 pixCenterPos, |
|||
const FfxFloat32x3 negViewspaceDir, |
|||
FfxFloat32x3 pixelNormal, |
|||
const FfxFloat32x2 normalizedScreenPos, |
|||
const FfxFloat32x2 depthBufferUV, |
|||
const FfxFloat32 mipOffset, |
|||
const FfxFloat32 falloffCalcMulSq, |
|||
FfxFloat32 weightMod, |
|||
FfxFloat32x2 normXY, |
|||
FfxFloat32 normXYLength, |
|||
const FfxUInt32 layerId) |
|||
{ |
|||
FfxFloat32x2 sampleOffset; |
|||
FfxFloat32 samplePow2Len; |
|||
|
|||
// patterns |
|||
{ |
|||
FfxFloat32x4 newSample = g_FFX_CACAO_samplePatternMain[tapIndex]; |
|||
sampleOffset = FFX_TRANSFORM_VECTOR(rotScale, newSample.xy); |
|||
samplePow2Len = newSample.w; // precalculated, same as: samplePow2Len = log2( length( newSample.xy ) ); |
|||
weightMod *= newSample.z; |
|||
} |
|||
|
|||
// snap to pixel center (more correct obscurance math, avoids artifacts) |
|||
sampleOffset = round(sampleOffset); |
|||
|
|||
// calculate MIP based on the sample distance from the centre, similar to as described |
|||
// in http://graphics.cs.williams.edu/papers/SAOHPG12/. |
|||
FfxFloat32 mipLevel = (qualityLevel < FFX_CACAO_DEPTH_MIPS_ENABLE_AT_QUALITY_PRESET) ? (0) : (samplePow2Len + mipOffset); |
|||
|
|||
FfxFloat32x2 samplingUV = sampleOffset * DeinterleavedDepthBufferInverseDimensions() + depthBufferUV; |
|||
|
|||
FFX_CACAO_SSAOTapInner(qualityLevel, obscuranceSum, weightSum, samplingUV, mipLevel, pixCenterPos, negViewspaceDir, pixelNormal, falloffCalcMulSq, weightMod, tapIndex * 2, layerId); |
|||
|
|||
// for the second tap, just use the mirrored offset |
|||
FfxFloat32x2 sampleOffsetMirroredUV = -sampleOffset; |
|||
|
|||
// tilt the second set of samples so that the disk is effectively rotated by the normal |
|||
// effective at removing one set of artifacts, but too expensive for lower quality settings |
|||
if (qualityLevel >= FFX_CACAO_TILT_SAMPLES_ENABLE_AT_QUALITY_PRESET) |
|||
{ |
|||
FfxFloat32 dotNorm = dot(sampleOffsetMirroredUV, normXY); |
|||
sampleOffsetMirroredUV -= dotNorm * normXYLength * normXY; |
|||
sampleOffsetMirroredUV = round(sampleOffsetMirroredUV); |
|||
} |
|||
|
|||
// snap to pixel center (more correct obscurance math, avoids artifacts) |
|||
FfxFloat32x2 samplingMirroredUV = sampleOffsetMirroredUV * DeinterleavedDepthBufferInverseDimensions() + depthBufferUV; |
|||
|
|||
FFX_CACAO_SSAOTapInner(qualityLevel, obscuranceSum, weightSum, samplingMirroredUV, mipLevel, pixCenterPos, negViewspaceDir, pixelNormal, falloffCalcMulSq, weightMod, tapIndex * 2 + 1, layerId); |
|||
} |
|||
|
|||
struct FFX_CACAO_SSAOHits |
|||
{ |
|||
FfxFloat32x3 hits[2]; |
|||
FfxFloat32 weightMod; |
|||
}; |
|||
|
|||
struct FFX_CACAO_SSAOSampleData |
|||
{ |
|||
FfxFloat32x2 uvOffset; |
|||
FfxFloat32 mipLevel; |
|||
FfxFloat32 weightMod; |
|||
}; |
|||
|
|||
FFX_CACAO_SSAOSampleData FFX_CACAO_SSAOGetSampleData(const FfxInt32 qualityLevel, |
|||
const FfxFloat32x2x2 rotScale, |
|||
const FfxFloat32x4 newSample, |
|||
const FfxFloat32 mipOffset) |
|||
{ |
|||
FfxFloat32x2 sampleOffset = FFX_TRANSFORM_VECTOR(rotScale, newSample.xy); |
|||
sampleOffset = round(sampleOffset) * DeinterleavedDepthBufferInverseDimensions(); |
|||
|
|||
FfxFloat32 samplePow2Len = newSample.w; |
|||
FfxFloat32 mipLevel = (qualityLevel < FFX_CACAO_DEPTH_MIPS_ENABLE_AT_QUALITY_PRESET) ? (0) : (samplePow2Len + mipOffset); |
|||
|
|||
FFX_CACAO_SSAOSampleData result; |
|||
|
|||
result.uvOffset = sampleOffset; |
|||
result.mipLevel = mipLevel; |
|||
result.weightMod = newSample.z; |
|||
|
|||
return result; |
|||
} |
|||
|
|||
FFX_CACAO_SSAOHits FFX_CACAO_SSAOGetHits2(FFX_CACAO_SSAOSampleData data, const FfxFloat32x2 depthBufferUV, const FfxUInt32 layerId) |
|||
{ |
|||
FFX_CACAO_SSAOHits result; |
|||
result.weightMod = data.weightMod; |
|||
FfxFloat32x2 sampleUV = depthBufferUV + data.uvOffset; |
|||
result.hits[0] = FfxFloat32x3(sampleUV, FFX_CACAO_SSAOGeneration_SampleViewspaceDepthMip(sampleUV, data.mipLevel, layerId)); |
|||
sampleUV = depthBufferUV - data.uvOffset; |
|||
result.hits[1] = FfxFloat32x3(sampleUV, FFX_CACAO_SSAOGeneration_SampleViewspaceDepthMip(sampleUV, data.mipLevel, layerId)); |
|||
return result; |
|||
} |
|||
|
|||
void FFX_CACAO_SSAOAddHits(const FfxInt32 qualityLevel, const FfxFloat32x3 pixCenterPos, const FfxFloat32x3 pixelNormal, const FfxFloat32 falloffCalcMulSq, inout FfxFloat32 weightSum, inout FfxFloat32 obscuranceSum, FFX_CACAO_SSAOHits hits) |
|||
{ |
|||
FfxFloat32 weight = hits.weightMod; |
|||
FFX_UNROLL |
|||
for (FfxInt32 hitIndex = 0; hitIndex < 2; ++hitIndex) |
|||
{ |
|||
FfxFloat32x3 hit = hits.hits[hitIndex]; |
|||
FfxFloat32x3 hitPos = FFX_CACAO_DepthBufferUVToViewSpace(hit.xy, hit.z); |
|||
FfxFloat32x3 hitDelta = hitPos - pixCenterPos; |
|||
|
|||
FfxFloat32 obscurance = FFX_CACAO_CalculatePixelObscurance(pixelNormal, hitDelta, falloffCalcMulSq); |
|||
|
|||
if (qualityLevel >= FFX_CACAO_HALOING_REDUCTION_ENABLE_AT_QUALITY_PRESET) |
|||
{ |
|||
//FfxFloat32 reduct = max( 0, dot( hitDelta, negViewspaceDir ) ); |
|||
FfxFloat32 reduct = max(0, -hitDelta.z); // cheaper, less correct version |
|||
reduct = ffxSaturate(reduct * NegRecEffectRadius() + 2.0); // ffxSaturate( 2.0 - reduct / EffectRadius() ); |
|||
weight = FFX_CACAO_HALOING_REDUCTION_AMOUNT * reduct + (1.0 - FFX_CACAO_HALOING_REDUCTION_AMOUNT); |
|||
} |
|||
obscuranceSum += obscurance * weight; |
|||
weightSum += weight; |
|||
} |
|||
} |
|||
|
|||
void FFX_CACAO_GenerateSSAOShadowsInternal(out FfxFloat32 outShadowTerm, |
|||
out FfxFloat32x4 outEdges, |
|||
out FfxFloat32 outWeight, |
|||
const FfxFloat32x2 SVPos /*, const FfxFloat32x2 normalizedScreenPos*/, |
|||
FFX_PARAMETER_UNIFORM FfxInt32 qualityLevel, |
|||
bool adaptiveBase, |
|||
const FfxUInt32 layerId) |
|||
{ |
|||
FfxFloat32x2 SVPosRounded = trunc(SVPos); |
|||
FfxUInt32x2 SVPosui = FfxUInt32x2(SVPosRounded); //same as FfxUInt32x2( SVPos ) |
|||
|
|||
const FfxInt32 numberOfTaps = (adaptiveBase) ? (FFX_CACAO_ADAPTIVE_TAP_BASE_COUNT) : FfxInt32(g_FFX_CACAO_numTaps[qualityLevel]); |
|||
FfxFloat32 pixZ, pixLZ, pixTZ, pixRZ, pixBZ; |
|||
|
|||
FfxFloat32x2 depthBufferUVCorner = (SVPos + 1.0f) * DeinterleavedDepthBufferInverseDimensions() + DeinterleavedDepthBufferNormalisedOffset(); //Need corner to avoid gather fixed point error. |
|||
FfxFloat32x2 depthBufferUV = (SVPos + 0.5f) * DeinterleavedDepthBufferInverseDimensions() + DeinterleavedDepthBufferNormalisedOffset(); //Need center coord |
|||
FfxFloat32x4 valuesUL = FFX_CACAO_SSAOGeneration_GatherViewspaceDepthOffset(depthBufferUVCorner, FfxInt32x2(-1, -1), layerId); |
|||
FfxFloat32x4 valuesBR = FFX_CACAO_SSAOGeneration_GatherViewspaceDepthOffset(depthBufferUVCorner, FfxInt32x2(0, 0), layerId); |
|||
|
|||
|
|||
// get this pixel's viewspace depth |
|||
pixZ = valuesUL.y; |
|||
|
|||
// get left right top bottom neighbouring pixels for edge detection (gets compiled out on qualityLevel == 0) |
|||
pixLZ = valuesUL.x; |
|||
pixTZ = valuesUL.z; |
|||
pixRZ = valuesBR.z; |
|||
pixBZ = valuesBR.x; |
|||
|
|||
// FfxFloat32x2 normalizedScreenPos = SVPosRounded * Viewport2xPixelSize() + Viewport2xPixelSize_x_025(); |
|||
FfxFloat32x2 normalizedScreenPos = (SVPosRounded + 0.5f) * SSAOBufferInverseDimensions(); |
|||
FfxFloat32x3 pixCenterPos = FFX_CACAO_NDCToViewSpace(normalizedScreenPos, pixZ); // g |
|||
|
|||
// Load this pixel's viewspace normal |
|||
// FfxUInt32x2 fullResCoord = 2 * (SVPosui * 2 + PerPassFullResCoordOffset().xy); |
|||
FfxFloat32x3 pixelNormal = FFX_CACAO_SSAOGeneration_GetNormalPass(SVPosui, layerId); |
|||
|
|||
// optimized approximation of: FfxFloat32x2 pixelDirRBViewspaceSizeAtCenterZ = FFX_CACAO_NDCToViewSpace( normalizedScreenPos.xy + _ViewportPixelSize().xy, pixCenterPos.z ).xy - pixCenterPos.xy; |
|||
// const FfxFloat32x2 pixelDirRBViewspaceSizeAtCenterZ = pixCenterPos.z * NDCToViewMul() * Viewport2xPixelSize(); |
|||
const FfxFloat32x2 pixelDirRBViewspaceSizeAtCenterZ = pixCenterPos.z * NDCToViewMul() * SSAOBufferInverseDimensions(); |
|||
|
|||
FfxFloat32 pixLookupRadiusMod; |
|||
FfxFloat32 falloffCalcMulSq; |
|||
|
|||
// calculate effect radius and fit our screen sampling pattern inside it |
|||
FfxFloat32 effectViewspaceRadius; |
|||
FFX_CACAO_CalculateRadiusParameters(length(pixCenterPos), pixelDirRBViewspaceSizeAtCenterZ, pixLookupRadiusMod, effectViewspaceRadius, falloffCalcMulSq); |
|||
|
|||
// calculate samples rotation/scaling |
|||
FfxFloat32x2x2 rotScale; |
|||
{ |
|||
// reduce effect radius near the screen edges slightly; ideally, one would render a larger depth buffer (5% on each side) instead |
|||
if (!adaptiveBase && (qualityLevel >= FFX_CACAO_REDUCE_RADIUS_NEAR_SCREEN_BORDER_ENABLE_AT_QUALITY_PRESET)) |
|||
{ |
|||
FfxFloat32 nearScreenBorder = min(min(depthBufferUV.x, 1.0 - depthBufferUV.x), min(depthBufferUV.y, 1.0 - depthBufferUV.y)); |
|||
nearScreenBorder = ffxSaturate(10.0 * nearScreenBorder + 0.6); |
|||
pixLookupRadiusMod *= nearScreenBorder; |
|||
} |
|||
|
|||
// load & update pseudo-random rotation matrix |
|||
FfxUInt32 pseudoRandomIndex = FfxUInt32(SVPosRounded.y * 2 + SVPosRounded.x) % 5; |
|||
FfxFloat32x4 rs = PatternRotScaleMatrices(layerId, pseudoRandomIndex); |
|||
rotScale = FfxFloat32x2x2(rs.x * pixLookupRadiusMod, rs.y * pixLookupRadiusMod, rs.z * pixLookupRadiusMod, rs.w * pixLookupRadiusMod); |
|||
} |
|||
|
|||
// the main obscurance & sample weight storage |
|||
FfxFloat32 obscuranceSum = 0.0; |
|||
FfxFloat32 weightSum = 0.0; |
|||
|
|||
// edge mask for between this and left/right/top/bottom neighbour pixels - not used in quality level 0 so initialize to "no edge" (1 is no edge, 0 is edge) |
|||
FfxFloat32x4 edgesLRTB = FfxFloat32x4(1.0, 1.0, 1.0, 1.0); |
|||
|
|||
// Move center pixel slightly towards camera to avoid imprecision artifacts due to using of 16bit depth buffer; a lot smaller offsets needed when using 32bit floats |
|||
pixCenterPos *= DepthPrecisionOffsetMod(); |
|||
|
|||
if (!adaptiveBase && (qualityLevel >= FFX_CACAO_DEPTH_BASED_EDGES_ENABLE_AT_QUALITY_PRESET)) |
|||
{ |
|||
edgesLRTB = FFX_CACAO_CalculateEdges(pixZ, pixLZ, pixRZ, pixTZ, pixBZ); |
|||
} |
|||
|
|||
// adds a more high definition sharp effect, which gets blurred out (reuses left/right/top/bottom samples that we used for edge detection) |
|||
if (!adaptiveBase && (qualityLevel >= FFX_CACAO_DETAIL_AO_ENABLE_AT_QUALITY_PRESET)) |
|||
{ |
|||
// disable in case of quality level 4 (reference) |
|||
if (qualityLevel != 4) |
|||
{ |
|||
//approximate neighbouring pixels positions (actually just deltas or "positions - pixCenterPos" ) |
|||
FfxFloat32x3 viewspaceDirZNormalized = FfxFloat32x3(pixCenterPos.xy / pixCenterPos.zz, 1.0); |
|||
|
|||
// very close approximation of: FfxFloat32x3 pixLPos = FFX_CACAO_NDCToViewSpace( normalizedScreenPos + FfxFloat32x2( -HalfViewportPixelSize().x, 0.0 ), pixLZ ).xyz - pixCenterPos.xyz; |
|||
FfxFloat32x3 pixLDelta = FfxFloat32x3(-pixelDirRBViewspaceSizeAtCenterZ.x, 0.0, 0.0) + viewspaceDirZNormalized * (pixLZ - pixCenterPos.z); |
|||
// very close approximation of: FfxFloat32x3 pixRPos = FFX_CACAO_NDCToViewSpace( normalizedScreenPos + FfxFloat32x2( +HalfViewportPixelSize().x, 0.0 ), pixRZ ).xyz - pixCenterPos.xyz; |
|||
FfxFloat32x3 pixRDelta = FfxFloat32x3(+pixelDirRBViewspaceSizeAtCenterZ.x, 0.0, 0.0) + viewspaceDirZNormalized * (pixRZ - pixCenterPos.z); |
|||
// very close approximation of: FfxFloat32x3 pixTPos = FFX_CACAO_NDCToViewSpace( normalizedScreenPos + FfxFloat32x2( 0.0, -HalfViewportPixelSize().y ), pixTZ ).xyz - pixCenterPos.xyz; |
|||
FfxFloat32x3 pixTDelta = FfxFloat32x3(0.0, -pixelDirRBViewspaceSizeAtCenterZ.y, 0.0) + viewspaceDirZNormalized * (pixTZ - pixCenterPos.z); |
|||
// very close approximation of: FfxFloat32x3 pixBPos = FFX_CACAO_NDCToViewSpace( normalizedScreenPos + FfxFloat32x2( 0.0, +HalfViewportPixelSize().y ), pixBZ ).xyz - pixCenterPos.xyz; |
|||
FfxFloat32x3 pixBDelta = FfxFloat32x3(0.0, +pixelDirRBViewspaceSizeAtCenterZ.y, 0.0) + viewspaceDirZNormalized * (pixBZ - pixCenterPos.z); |
|||
|
|||
const FfxFloat32 rangeReductionConst = 4.0f; // this is to avoid various artifacts |
|||
const FfxFloat32 modifiedFalloffCalcMulSq = rangeReductionConst * falloffCalcMulSq; |
|||
|
|||
FfxFloat32x4 additionalObscurance; |
|||
additionalObscurance.x = FFX_CACAO_CalculatePixelObscurance(pixelNormal, pixLDelta, modifiedFalloffCalcMulSq); |
|||
additionalObscurance.y = FFX_CACAO_CalculatePixelObscurance(pixelNormal, pixRDelta, modifiedFalloffCalcMulSq); |
|||
additionalObscurance.z = FFX_CACAO_CalculatePixelObscurance(pixelNormal, pixTDelta, modifiedFalloffCalcMulSq); |
|||
additionalObscurance.w = FFX_CACAO_CalculatePixelObscurance(pixelNormal, pixBDelta, modifiedFalloffCalcMulSq); |
|||
|
|||
obscuranceSum += DetailAOStrength() * dot(additionalObscurance, edgesLRTB); |
|||
} |
|||
} |
|||
|
|||
// Sharp normals also create edges - but this adds to the cost as well |
|||
if (!adaptiveBase && (qualityLevel >= FFX_CACAO_NORMAL_BASED_EDGES_ENABLE_AT_QUALITY_PRESET)) |
|||
{ |
|||
FfxFloat32x3 neighbourNormalL = FFX_CACAO_SSAOGeneration_GetNormalPass(SVPosui + FfxInt32x2(-1, +0), layerId); |
|||
FfxFloat32x3 neighbourNormalR = FFX_CACAO_SSAOGeneration_GetNormalPass(SVPosui + FfxInt32x2(+1, +0), layerId); |
|||
FfxFloat32x3 neighbourNormalT = FFX_CACAO_SSAOGeneration_GetNormalPass(SVPosui + FfxInt32x2(+0, -1), layerId); |
|||
FfxFloat32x3 neighbourNormalB = FFX_CACAO_SSAOGeneration_GetNormalPass(SVPosui + FfxInt32x2(+0, +1), layerId); |
|||
|
|||
const FfxFloat32 dotThreshold = FFX_CACAO_NORMAL_BASED_EDGES_DOT_THRESHOLD; |
|||
|
|||
FfxFloat32x4 normalEdgesLRTB; |
|||
normalEdgesLRTB.x = ffxSaturate((dot(pixelNormal, neighbourNormalL) + dotThreshold)); |
|||
normalEdgesLRTB.y = ffxSaturate((dot(pixelNormal, neighbourNormalR) + dotThreshold)); |
|||
normalEdgesLRTB.z = ffxSaturate((dot(pixelNormal, neighbourNormalT) + dotThreshold)); |
|||
normalEdgesLRTB.w = ffxSaturate((dot(pixelNormal, neighbourNormalB) + dotThreshold)); |
|||
|
|||
//#define FFX_CACAO_SMOOTHEN_NORMALS // fixes some aliasing artifacts but kills a lot of high detail and adds to the cost - not worth it probably but feel free to play with it |
|||
#ifdef FFX_CACAO_SMOOTHEN_NORMALS |
|||
//neighbourNormalL = LoadNormal( fullResCoord, FfxInt32x2( -1, 0 ) ); |
|||
//neighbourNormalR = LoadNormal( fullResCoord, FfxInt32x2( 1, 0 ) ); |
|||
//neighbourNormalT = LoadNormal( fullResCoord, FfxInt32x2( 0, -1 ) ); |
|||
//neighbourNormalB = LoadNormal( fullResCoord, FfxInt32x2( 0, 1 ) ); |
|||
pixelNormal += neighbourNormalL * edgesLRTB.x + neighbourNormalR * edgesLRTB.y + neighbourNormalT * edgesLRTB.z + neighbourNormalB * edgesLRTB.w; |
|||
pixelNormal = normalize(pixelNormal); |
|||
#endif |
|||
|
|||
edgesLRTB *= normalEdgesLRTB; |
|||
} |
|||
|
|||
|
|||
|
|||
const FfxFloat32 globalMipOffset = FFX_CACAO_DEPTH_MIPS_GLOBAL_OFFSET; |
|||
FfxFloat32 mipOffset = (qualityLevel < FFX_CACAO_DEPTH_MIPS_ENABLE_AT_QUALITY_PRESET) ? (0) : (log2(pixLookupRadiusMod) + globalMipOffset); |
|||
|
|||
// Used to tilt the second set of samples so that the disk is effectively rotated by the normal |
|||
// effective at removing one set of artifacts, but too expensive for lower quality settings |
|||
FfxFloat32x2 normXY = FfxFloat32x2(pixelNormal.x, pixelNormal.y); |
|||
FfxFloat32 normXYLength = length(normXY); |
|||
normXY /= FfxFloat32x2(normXYLength, -normXYLength); |
|||
normXYLength *= FFX_CACAO_TILT_SAMPLES_AMOUNT; |
|||
|
|||
const FfxFloat32x3 negViewspaceDir = -normalize(pixCenterPos); |
|||
|
|||
// standard, non-adaptive approach |
|||
if ((qualityLevel != 3) || adaptiveBase) |
|||
{ |
|||
FFX_UNROLL |
|||
for (FfxInt32 i = 0; i < numberOfTaps; i++) |
|||
{ |
|||
FFX_CACAO_SSAOTap(qualityLevel, obscuranceSum, weightSum, i, rotScale, pixCenterPos, negViewspaceDir, pixelNormal, normalizedScreenPos, depthBufferUV, mipOffset, falloffCalcMulSq, 1.0, normXY, normXYLength, layerId); |
|||
} |
|||
} |
|||
else // if( qualityLevel == 3 ) adaptive approach |
|||
{ |
|||
// add new ones if needed |
|||
FfxFloat32x2 fullResUV = normalizedScreenPos + PerPassFullResUVOffset(layerId).xy; |
|||
FfxFloat32 importance = FFX_CACAO_SSAOGeneration_SampleImportance(fullResUV); |
|||
|
|||
// this is to normalize FFX_CACAO_DETAIL_AO_AMOUNT across all pixel regardless of importance |
|||
obscuranceSum *= (FFX_CACAO_ADAPTIVE_TAP_BASE_COUNT / FfxFloat32(FFX_CACAO_MAX_TAPS)) + (importance * FFX_CACAO_ADAPTIVE_TAP_FLEXIBLE_COUNT / FfxFloat32(FFX_CACAO_MAX_TAPS)); |
|||
|
|||
// load existing base values |
|||
FfxFloat32x2 baseValues = FFX_CACAO_SSAOGeneration_LoadBasePassSSAOPass(SVPosui, layerId); //PassIndex()); |
|||
weightSum += baseValues.y * FfxFloat32(FFX_CACAO_ADAPTIVE_TAP_BASE_COUNT * 4.0); |
|||
obscuranceSum += (baseValues.x) * weightSum; |
|||
|
|||
// increase importance around edges |
|||
FfxFloat32 edgeCount = dot(1.0 - edgesLRTB, FfxFloat32x4(1.0, 1.0, 1.0, 1.0)); |
|||
|
|||
FfxFloat32 avgTotalImportance = FfxFloat32(FFX_CACAO_SSAOGeneration_GetLoadCounter()) * LoadCounterAvgDiv(); |
|||
|
|||
FfxFloat32 importanceLimiter = ffxSaturate(AdaptiveSampleCountLimit() / avgTotalImportance); |
|||
importance *= importanceLimiter; |
|||
|
|||
FfxFloat32 additionalSampleCountFlt = FFX_CACAO_ADAPTIVE_TAP_FLEXIBLE_COUNT * importance; |
|||
|
|||
additionalSampleCountFlt += 1.5; |
|||
FfxUInt32 additionalSamples = FfxUInt32(additionalSampleCountFlt); |
|||
FfxUInt32 additionalSamplesTo = min(FFX_CACAO_MAX_TAPS - 1, additionalSamples + FFX_CACAO_ADAPTIVE_TAP_BASE_COUNT); |
|||
|
|||
// sample loop |
|||
{ |
|||
FfxFloat32x4 newSample = g_FFX_CACAO_samplePatternMain[FFX_CACAO_ADAPTIVE_TAP_BASE_COUNT]; |
|||
FFX_CACAO_SSAOSampleData data = FFX_CACAO_SSAOGetSampleData(qualityLevel, rotScale, newSample, mipOffset); |
|||
FFX_CACAO_SSAOHits hits = FFX_CACAO_SSAOGetHits2(data, depthBufferUV, layerId); |
|||
newSample = g_FFX_CACAO_samplePatternMain[FFX_CACAO_ADAPTIVE_TAP_BASE_COUNT + 1]; |
|||
|
|||
for (FfxUInt32 i = FFX_CACAO_ADAPTIVE_TAP_BASE_COUNT; i < additionalSamplesTo - 1; i++) |
|||
{ |
|||
data = FFX_CACAO_SSAOGetSampleData(qualityLevel, rotScale, newSample, mipOffset); |
|||
newSample = g_FFX_CACAO_samplePatternMain[i + 2]; |
|||
FFX_CACAO_SSAOHits nextHits = FFX_CACAO_SSAOGetHits2(data, depthBufferUV, layerId); |
|||
|
|||
FFX_CACAO_SSAOAddHits(qualityLevel, pixCenterPos, pixelNormal, falloffCalcMulSq, weightSum, obscuranceSum, hits); |
|||
hits = nextHits; |
|||
} |
|||
|
|||
// last loop iteration |
|||
{ |
|||
FFX_CACAO_SSAOAddHits(qualityLevel, pixCenterPos, pixelNormal, falloffCalcMulSq, weightSum, obscuranceSum, hits); |
|||
} |
|||
} |
|||
} |
|||
|
|||
// early out for adaptive base - just output weight (used for the next pass) |
|||
if (adaptiveBase) |
|||
{ |
|||
FfxFloat32 obscurance = obscuranceSum / weightSum; |
|||
|
|||
outShadowTerm = obscurance; |
|||
outEdges = FfxFloat32x4(0, 0, 0, 0); |
|||
outWeight = weightSum; |
|||
return; |
|||
} |
|||
|
|||
// calculate weighted average |
|||
FfxFloat32 obscurance = obscuranceSum / weightSum; |
|||
|
|||
// calculate fadeout (1 close, gradient, 0 far) |
|||
FfxFloat32 fadeOut = ffxSaturate(pixCenterPos.z * EffectFadeOutMul() + EffectFadeOutAdd()); |
|||
|
|||
// Reduce the SSAO shadowing if we're on the edge to remove artifacts on edges (we don't care for the lower quality one) |
|||
if (!adaptiveBase && (qualityLevel >= FFX_CACAO_DEPTH_BASED_EDGES_ENABLE_AT_QUALITY_PRESET)) |
|||
{ |
|||
// FfxFloat32 edgeCount = dot( 1.0-edgesLRTB, FfxFloat32x4( 1.0, 1.0, 1.0, 1.0 ) ); |
|||
|
|||
// when there's more than 2 opposite edges, start fading out the occlusion to reduce aliasing artifacts |
|||
FfxFloat32 edgeFadeoutFactor = ffxSaturate((1.0 - edgesLRTB.x - edgesLRTB.y) * 0.35) + ffxSaturate((1.0 - edgesLRTB.z - edgesLRTB.w) * 0.35); |
|||
|
|||
// (experimental) if you want to reduce the effect next to any edge |
|||
// edgeFadeoutFactor += 0.1 * ffxSaturate( dot( 1 - edgesLRTB, FfxFloat32x4( 1, 1, 1, 1 ) ) ); |
|||
|
|||
fadeOut *= ffxSaturate(1.0 - edgeFadeoutFactor); |
|||
} |
|||
|
|||
// same as a bove, but a lot more conservative version |
|||
// fadeOut *= ffxSaturate( dot( edgesLRTB, FfxFloat32x4( 0.9, 0.9, 0.9, 0.9 ) ) - 2.6 ); |
|||
|
|||
// strength |
|||
obscurance = EffectShadowStrength() * obscurance; |
|||
|
|||
// clamp |
|||
obscurance = min(obscurance, EffectShadowClamp()); |
|||
|
|||
// fadeout |
|||
obscurance *= fadeOut; |
|||
|
|||
// conceptually switch to occlusion with the meaning being visibility (grows with visibility, occlusion == 1 implies full visibility), |
|||
// to be in line with what is more commonly used. |
|||
FfxFloat32 occlusion = 1.0 - obscurance; |
|||
|
|||
// modify the gradient |
|||
// note: this cannot be moved to a later pass because of loss of precision after storing in the render target |
|||
occlusion = pow(ffxSaturate(occlusion), EffectShadowPow()); |
|||
|
|||
// outputs! |
|||
outShadowTerm = occlusion; // Our final 'occlusion' term (0 means fully occluded, 1 means fully lit) |
|||
outEdges = edgesLRTB; // These are used to prevent blurring across edges, 1 means no edge, 0 means edge, 0.5 means half way there, etc. |
|||
outWeight = weightSum; |
|||
} |
|||
|
|||
void FFX_CACAO_GenerateQ0(FfxUInt32x3 tid) |
|||
{ |
|||
FfxUInt32 tidCorrectedZ = tid.z % 5; |
|||
FfxUInt32 layerId = tid.z / 5; |
|||
layerId = (layerId == 1 && BlurNumPasses() == 2) ? 3 : layerId; // Choose correct layer in 2 layer case |
|||
FfxUInt32 xOffset = (tid.y * 3 + tidCorrectedZ) % 5; |
|||
FfxUInt32x2 coord = FfxUInt32x2(5 * tid.x + xOffset, tid.y); |
|||
FfxFloat32x2 inPos = FfxFloat32x2(coord); |
|||
FfxFloat32 outShadowTerm; |
|||
FfxFloat32 outWeight; |
|||
FfxFloat32x4 outEdges; |
|||
FFX_CACAO_GenerateSSAOShadowsInternal(outShadowTerm, outEdges, outWeight, inPos.xy, 0, false, layerId); |
|||
FfxFloat32x2 out0; |
|||
out0.x = outShadowTerm; |
|||
out0.y = FFX_CACAO_PackEdges(FfxFloat32x4(1, 1, 1, 1)); // no edges in low quality |
|||
FFX_CACAO_SSAOGeneration_StoreOutput(coord, out0, layerId); |
|||
} |
|||
|
|||
void FFX_CACAO_GenerateQ1(FfxUInt32x3 tid) |
|||
{ |
|||
FfxUInt32 tidCorrectedZ = tid.z % 5; |
|||
FfxUInt32 layerId = tid.z / 5; |
|||
layerId = (layerId == 1 && BlurNumPasses() == 2) ? 3 : layerId; // Choose correct layer in 2 layer case |
|||
FfxUInt32 xOffset = (tid.y * 3 + tidCorrectedZ) % 5; |
|||
FfxUInt32x2 coord = FfxUInt32x2(5 * tid.x + xOffset, tid.y); |
|||
FfxFloat32x2 inPos = FfxFloat32x2(coord); |
|||
FfxFloat32 outShadowTerm; |
|||
FfxFloat32 outWeight; |
|||
FfxFloat32x4 outEdges; |
|||
FFX_CACAO_GenerateSSAOShadowsInternal(outShadowTerm, outEdges, outWeight, inPos.xy, 1, false, layerId); |
|||
FfxFloat32x2 out0; |
|||
out0.x = outShadowTerm; |
|||
out0.y = FFX_CACAO_PackEdges(outEdges); |
|||
FFX_CACAO_SSAOGeneration_StoreOutput(coord, out0, layerId); |
|||
} |
|||
|
|||
void FFX_CACAO_GenerateQ2(FfxUInt32x3 coord) |
|||
{ |
|||
FfxFloat32x2 inPos = FfxFloat32x2(coord.xy); |
|||
FfxUInt32 layerId = coord.z; |
|||
FfxFloat32 outShadowTerm; |
|||
FfxFloat32 outWeight; |
|||
FfxFloat32x4 outEdges; |
|||
FFX_CACAO_GenerateSSAOShadowsInternal(outShadowTerm, outEdges, outWeight, inPos.xy, 2, false, layerId); |
|||
FfxFloat32x2 out0; |
|||
out0.x = outShadowTerm; |
|||
out0.y = FFX_CACAO_PackEdges(outEdges); |
|||
FFX_CACAO_SSAOGeneration_StoreOutput(coord.xy, out0, layerId); |
|||
} |
|||
|
|||
void FFX_CACAO_GenerateQ3Base(FfxUInt32x3 coord) |
|||
{ |
|||
FfxFloat32x2 inPos = FfxFloat32x2(coord.xy); |
|||
FfxUInt32 layerId = coord.z; |
|||
FfxFloat32 outShadowTerm; |
|||
FfxFloat32 outWeight; |
|||
FfxFloat32x4 outEdges; |
|||
FFX_CACAO_GenerateSSAOShadowsInternal(outShadowTerm, outEdges, outWeight, inPos.xy, 3, true, layerId); |
|||
FfxFloat32x2 out0; |
|||
out0.x = outShadowTerm; |
|||
out0.y = outWeight / (FfxFloat32(FFX_CACAO_ADAPTIVE_TAP_BASE_COUNT) * 4.0); //0.0; //frac(outWeight / 6.0);// / (FfxFloat32)(FFX_CACAO_MAX_TAPS * 4.0); |
|||
FFX_CACAO_SSAOGeneration_StoreOutput(coord.xy, out0, layerId); |
|||
} |
|||
|
|||
void FFX_CACAO_GenerateQ3(FfxUInt32x3 coord) |
|||
{ |
|||
FfxFloat32x2 inPos = FfxFloat32x2(coord.xy); |
|||
FfxUInt32 layerId = coord.z; |
|||
FfxFloat32 outShadowTerm; |
|||
FfxFloat32 outWeight; |
|||
FfxFloat32x4 outEdges; |
|||
FFX_CACAO_GenerateSSAOShadowsInternal(outShadowTerm, outEdges, outWeight, inPos.xy, 3, false, layerId); |
|||
FfxFloat32x2 out0; |
|||
out0.x = outShadowTerm; |
|||
out0.y = FFX_CACAO_PackEdges(outEdges); |
|||
FFX_CACAO_SSAOGeneration_StoreOutput(coord.xy, out0, layerId); |
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 4eb4d8ec59412ac40a64c53acbb3366e |
|||
PluginImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
iconMap: {} |
|||
executionOrder: {} |
|||
defineConstraints: [] |
|||
isPreloaded: 0 |
|||
isOverridable: 0 |
|||
isExplicitlyReferenced: 0 |
|||
validateReferences: 1 |
|||
platformData: |
|||
- first: |
|||
Any: |
|||
second: |
|||
enabled: 1 |
|||
settings: {} |
|||
- first: |
|||
Editor: Editor |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
DefaultValueInitialized: true |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,611 @@ |
|||
// This file is part of the FidelityFX SDK. |
|||
// |
|||
// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved. |
|||
// |
|||
// 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. |
|||
|
|||
|
|||
#include "../common/ffx_core.h" |
|||
#include "ffx_cacao_defines.h" |
|||
#include "ffx_cacao_utils.h" |
|||
|
|||
#define FFX_CACAO_BILATERAL_UPSCALE_BUFFER_WIDTH (FFX_CACAO_BILATERAL_UPSCALE_WIDTH + 4) |
|||
#define FFX_CACAO_BILATERAL_UPSCALE_BUFFER_HEIGHT (FFX_CACAO_BILATERAL_UPSCALE_HEIGHT + 4 + 4) |
|||
|
|||
struct FFX_CACAO_BilateralBufferVal |
|||
{ |
|||
FfxUInt32 packedDepths; |
|||
FfxUInt32 packedSsaoVals; |
|||
}; |
|||
|
|||
FFX_GROUPSHARED FFX_CACAO_BilateralBufferVal s_FFX_CACAO_BilateralUpscaleBuffer[FFX_CACAO_BILATERAL_UPSCALE_BUFFER_WIDTH][FFX_CACAO_BILATERAL_UPSCALE_BUFFER_HEIGHT]; |
|||
|
|||
void FFX_CACAO_BilateralUpscaleNxN(FfxUInt32x2 tid, FfxUInt32x2 gtid, FfxUInt32x2 gid, const FfxInt32 width, const FfxInt32 height, const bool useEdges) |
|||
{ |
|||
// fill in group shared buffer |
|||
{ |
|||
FfxUInt32 threadNum = (gtid.y * FFX_CACAO_BILATERAL_UPSCALE_WIDTH + gtid.x) * 3; |
|||
FfxUInt32x2 bufferCoord = FfxUInt32x2(threadNum % FFX_CACAO_BILATERAL_UPSCALE_BUFFER_WIDTH, threadNum / FFX_CACAO_BILATERAL_UPSCALE_BUFFER_WIDTH); |
|||
FfxUInt32x2 imageCoord = (gid * FfxUInt32x2(FFX_CACAO_BILATERAL_UPSCALE_WIDTH, FFX_CACAO_BILATERAL_UPSCALE_HEIGHT)) + bufferCoord - 2; |
|||
|
|||
if (useEdges) |
|||
{ |
|||
FfxFloat32x2 inputs[3]; |
|||
for (FfxInt32 j = 0; j < 3; ++j) |
|||
{ |
|||
FfxInt32x2 p = FfxInt32x2(imageCoord.x + j, imageCoord.y); |
|||
FfxInt32x2 pos = p / 2; |
|||
FfxInt32 index = (p.x % 2) + 2 * (p.y % 2); |
|||
inputs[j] = FFX_CACAO_BilateralUpscale_LoadSSAO(pos, index); |
|||
} |
|||
|
|||
for (FfxInt32 i = 0; i < 3; ++i) |
|||
{ |
|||
FfxInt32 mx = FfxInt32(imageCoord.x % 2); |
|||
FfxInt32 my = FfxInt32(imageCoord.y % 2); |
|||
|
|||
FfxInt32 ic = mx + my * 2; // center index |
|||
FfxInt32 ih = (1 - mx) + my * 2; // neighbouring, horizontal |
|||
FfxInt32 iv = mx + (1 - my) * 2; // neighbouring, vertical |
|||
FfxInt32 id = (1 - mx) + (1 - my) * 2; // diagonal |
|||
|
|||
FfxFloat32x2 centerVal = inputs[i]; |
|||
|
|||
FfxFloat32 ao = centerVal.x; |
|||
|
|||
FfxFloat32x4 edgesLRTB = FFX_CACAO_UnpackEdges(centerVal.y); |
|||
|
|||
// convert index shifts to sampling offsets |
|||
FfxFloat32 fmx = FfxFloat32(mx); |
|||
FfxFloat32 fmy = FfxFloat32(my); |
|||
|
|||
// in case of an edge, push sampling offsets away from the edge (towards pixel center) |
|||
FfxFloat32 fmxe = (edgesLRTB.y - edgesLRTB.x); |
|||
FfxFloat32 fmye = (edgesLRTB.w - edgesLRTB.z); |
|||
|
|||
// calculate final sampling offsets and sample using bilinear filter |
|||
FfxFloat32x2 p = imageCoord; |
|||
FfxFloat32x2 uvH = (p + FfxFloat32x2(fmx + fmxe - 0.5, 0.5 - fmy)) * 0.5 * SSAOBufferInverseDimensions(); |
|||
FfxFloat32 aoH = FFX_CACAO_BilateralUpscale_SampleSSAOLinear(uvH, ih); |
|||
FfxFloat32x2 uvV = (p + FfxFloat32x2(0.5 - fmx, fmy - 0.5 + fmye)) * 0.5 * SSAOBufferInverseDimensions(); |
|||
FfxFloat32 aoV = FFX_CACAO_BilateralUpscale_SampleSSAOLinear(uvV, iv); |
|||
FfxFloat32x2 uvD = (p + FfxFloat32x2(fmx - 0.5 + fmxe, fmy - 0.5 + fmye)) * 0.5 * SSAOBufferInverseDimensions(); |
|||
FfxFloat32 aoD = FFX_CACAO_BilateralUpscale_SampleSSAOLinear(uvD, id); |
|||
|
|||
// reduce weight for samples near edge - if the edge is on both sides, weight goes to 0 |
|||
FfxFloat32x4 blendWeights; |
|||
blendWeights.x = 1.0; |
|||
blendWeights.y = (edgesLRTB.x + edgesLRTB.y) * 0.5; |
|||
blendWeights.z = (edgesLRTB.z + edgesLRTB.w) * 0.5; |
|||
blendWeights.w = (blendWeights.y + blendWeights.z) * 0.5; |
|||
|
|||
// calculate weighted average |
|||
FfxFloat32 blendWeightsSum = dot(blendWeights, FfxFloat32x4(1.0, 1.0, 1.0, 1.0)); |
|||
ao = dot(FfxFloat32x4(ao, aoH, aoV, aoD), blendWeights) / blendWeightsSum; |
|||
|
|||
++imageCoord.x; |
|||
|
|||
FFX_CACAO_BilateralBufferVal bufferVal; |
|||
|
|||
FfxUInt32x2 depthArrayBufferCoord = FfxUInt32x2((imageCoord / 2) + DeinterleavedDepthBufferOffset()); |
|||
FfxUInt32 depthArrayBufferIndex = ic; |
|||
FfxFloat32 depth = FFX_CACAO_BilateralUpscale_LoadDownscaledDepth(depthArrayBufferCoord, depthArrayBufferIndex); |
|||
|
|||
bufferVal.packedDepths = ffxPackF32(FfxFloat32x2(depth, depth)); |
|||
bufferVal.packedSsaoVals = ffxPackF32(FfxFloat32x2(ao, ao)); |
|||
|
|||
s_FFX_CACAO_BilateralUpscaleBuffer[bufferCoord.x + i][bufferCoord.y] = bufferVal; |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
for (FfxInt32 i = 0; i < 3; ++i) |
|||
{ |
|||
FfxFloat32x2 sampleLoc0 = (FfxFloat32x2(imageCoord / 2) + 0.5f) * SSAOBufferInverseDimensions(); |
|||
FfxFloat32x2 sampleLoc1 = sampleLoc0; |
|||
FfxFloat32x2 sampleLoc2 = sampleLoc0; |
|||
FfxFloat32x2 sampleLoc3 = sampleLoc0; |
|||
switch ((imageCoord.y % 2) * 2 + (imageCoord.x % 2)) { |
|||
case 0: |
|||
sampleLoc1.x -= 0.5f * SSAOBufferInverseDimensions().x; |
|||
sampleLoc2.y -= 0.5f * SSAOBufferInverseDimensions().y; |
|||
sampleLoc3 -= 0.5f * SSAOBufferInverseDimensions(); |
|||
break; |
|||
case 1: |
|||
sampleLoc0.x += 0.5f * SSAOBufferInverseDimensions().x; |
|||
sampleLoc2 += FfxFloat32x2(0.5f, -0.5f) * SSAOBufferInverseDimensions(); |
|||
sampleLoc3.y -= 0.5f * SSAOBufferInverseDimensions().y; |
|||
break; |
|||
case 2: |
|||
sampleLoc0.y += 0.5f * SSAOBufferInverseDimensions().y; |
|||
sampleLoc1 += FfxFloat32x2(-0.5f, 0.5f) * SSAOBufferInverseDimensions(); |
|||
sampleLoc3.x -= 0.5f * SSAOBufferInverseDimensions().x; |
|||
break; |
|||
case 3: |
|||
sampleLoc0 += 0.5f * SSAOBufferInverseDimensions(); |
|||
sampleLoc1.y += 0.5f * SSAOBufferInverseDimensions().y; |
|||
sampleLoc2.x += 0.5f * SSAOBufferInverseDimensions().x; |
|||
break; |
|||
} |
|||
|
|||
FfxFloat32 ssaoVal0 = FFX_CACAO_BilateralUpscale_SampleSSAOPoint(sampleLoc0, 0); |
|||
FfxFloat32 ssaoVal1 = FFX_CACAO_BilateralUpscale_SampleSSAOPoint(sampleLoc1, 1); |
|||
FfxFloat32 ssaoVal2 = FFX_CACAO_BilateralUpscale_SampleSSAOPoint(sampleLoc2, 2); |
|||
FfxFloat32 ssaoVal3 = FFX_CACAO_BilateralUpscale_SampleSSAOPoint(sampleLoc3, 3); |
|||
|
|||
FfxUInt32x3 ssaoArrayBufferCoord = FfxUInt32x3(imageCoord / 2, 2 * (imageCoord.y % 2) + imageCoord.x % 2); |
|||
FfxUInt32x2 depthArrayBufferCoord = FfxUInt32x2(ssaoArrayBufferCoord.xy + DeinterleavedDepthBufferOffset()); |
|||
FfxUInt32 depthArrayBufferIndex = ssaoArrayBufferCoord.z; |
|||
++imageCoord.x; |
|||
|
|||
FFX_CACAO_BilateralBufferVal bufferVal; |
|||
|
|||
FfxFloat32 depth = FFX_CACAO_BilateralUpscale_LoadDownscaledDepth(depthArrayBufferCoord, depthArrayBufferIndex); |
|||
FfxFloat32 ssaoVal = (ssaoVal0 + ssaoVal1 + ssaoVal2 + ssaoVal3) * 0.25f; |
|||
|
|||
bufferVal.packedDepths = ffxPackF32(FfxFloat32x2(depth, depth)); |
|||
bufferVal.packedSsaoVals = ffxPackF32(FfxFloat32x2(ssaoVal, ssaoVal)); //CACAO_TODO half path? |
|||
|
|||
s_FFX_CACAO_BilateralUpscaleBuffer[bufferCoord.x + i][bufferCoord.y] = bufferVal; |
|||
} |
|||
} |
|||
} |
|||
|
|||
FFX_GROUP_MEMORY_BARRIER(); |
|||
|
|||
FfxFloat32 depths[4]; |
|||
// load depths |
|||
{ |
|||
FfxInt32x2 fullBufferCoord = FfxInt32x2(2 * tid); |
|||
FfxInt32x2 fullDepthBufferCoord = fullBufferCoord + DepthBufferOffset(); |
|||
|
|||
FfxFloat32x4 screenSpaceDepths = FFX_CACAO_BilateralUpscale_LoadDepths(fullDepthBufferCoord); |
|||
|
|||
depths[0] = FFX_CACAO_ScreenSpaceToViewSpaceDepth(screenSpaceDepths.x); |
|||
depths[1] = FFX_CACAO_ScreenSpaceToViewSpaceDepth(screenSpaceDepths.y); |
|||
depths[2] = FFX_CACAO_ScreenSpaceToViewSpaceDepth(screenSpaceDepths.z); |
|||
depths[3] = FFX_CACAO_ScreenSpaceToViewSpaceDepth(screenSpaceDepths.w); |
|||
} |
|||
|
|||
#if FFX_HALF |
|||
FfxFloat16x4 packedDepths = FfxFloat16x4(depths[0], depths[1], depths[2], depths[3]); |
|||
|
|||
FfxInt32x2 baseBufferCoord = FfxInt32x2(gtid) + FfxInt32x2(width, height); |
|||
|
|||
FfxFloat16 epsilonWeight = FfxFloat16(1e-3f); |
|||
FfxFloat16x2 nearestSsaoVals = ffxUnpackF16(s_FFX_CACAO_BilateralUpscaleBuffer[baseBufferCoord.x][baseBufferCoord.y].packedSsaoVals); |
|||
FfxFloat16x4 packedTotals = epsilonWeight * FfxFloat16x4(1.0f, 1.0f, 1.0f, 1.0f); |
|||
packedTotals.xy *= nearestSsaoVals; |
|||
packedTotals.zw *= nearestSsaoVals; |
|||
FfxFloat16x4 packedTotalWeights = epsilonWeight * FfxFloat16x4(1.0f, 1.0f, 1.0f, 1.0f); |
|||
|
|||
FfxFloat32 distanceSigma = BilateralSimilarityDistanceSigma(); |
|||
FfxFloat16x2 packedDistSigma = FfxFloat16x2(1.0f / distanceSigma, 1.0f / distanceSigma); |
|||
FfxFloat32 sigma = BilateralSigmaSquared(); |
|||
FfxFloat16x2 packedSigma = FfxFloat16x2(1.0f / sigma, 1.0f / sigma); |
|||
|
|||
for (FfxInt32 x = -width; x <= width; ++x) |
|||
{ |
|||
for (FfxInt32 y = -height; y <= height; ++y) |
|||
{ |
|||
FfxInt32x2 bufferCoord = baseBufferCoord + FfxInt32x2(x, y); |
|||
|
|||
FFX_CACAO_BilateralBufferVal bufferVal = s_FFX_CACAO_BilateralUpscaleBuffer[bufferCoord.x][bufferCoord.y]; |
|||
|
|||
FfxFloat16x2 u = FfxFloat16x2(x, x) - FfxFloat16x2(0.0f, 0.5f); |
|||
FfxFloat16x2 v1 = FfxFloat16x2(y, y) - FfxFloat16x2(0.0f, 0.0f); |
|||
FfxFloat16x2 v2 = FfxFloat16x2(y, y) - FfxFloat16x2(0.5f, 0.5f); |
|||
u = u * u; |
|||
v1 = v1 * v1; |
|||
v2 = v2 * v2; |
|||
|
|||
FfxFloat16x2 dist1 = u + v1; |
|||
FfxFloat16x2 dist2 = u + v2; |
|||
|
|||
FfxFloat16x2 wx1 = exp(-dist1 * packedSigma); |
|||
FfxFloat16x2 wx2 = exp(-dist2 * packedSigma); |
|||
|
|||
FfxFloat16x2 bufferPackedDepths = ffxUnpackF16(bufferVal.packedDepths); |
|||
|
|||
FfxFloat16x2 diff1 = packedDepths.xy - bufferPackedDepths; |
|||
FfxFloat16x2 diff2 = packedDepths.zw - bufferPackedDepths; |
|||
diff1 *= diff1; |
|||
diff2 *= diff2; |
|||
|
|||
FfxFloat16x2 wy1 = exp(-diff1 * packedDistSigma); |
|||
FfxFloat16x2 wy2 = exp(-diff2 * packedDistSigma); |
|||
|
|||
FfxFloat16x2 weight1 = wx1 * wy1; |
|||
FfxFloat16x2 weight2 = wx2 * wy2; |
|||
|
|||
FfxFloat16x2 packedSsaoVals = ffxUnpackF16(bufferVal.packedSsaoVals); |
|||
packedTotals.xy += packedSsaoVals * weight1; |
|||
packedTotals.zw += packedSsaoVals * weight2; |
|||
packedTotalWeights.xy += weight1; |
|||
packedTotalWeights.zw += weight2; |
|||
} |
|||
} |
|||
|
|||
FfxUInt32x2 outputCoord = 2 * tid; |
|||
FfxFloat16x4 outputValues = packedTotals / packedTotalWeights; |
|||
#else |
|||
FfxFloat32x4 packedDepths = FfxFloat32x4(depths[0], depths[1], depths[2], depths[3]); |
|||
|
|||
FfxInt32x2 baseBufferCoord = FfxInt32x2(gtid) + FfxInt32x2(width, height); |
|||
|
|||
FfxFloat32 epsilonWeight = FfxFloat32(1e-3f); |
|||
FfxFloat32x2 nearestSsaoVals = ffxUnpackF32(s_FFX_CACAO_BilateralUpscaleBuffer[baseBufferCoord.x][baseBufferCoord.y].packedSsaoVals); |
|||
FfxFloat32x4 packedTotals = epsilonWeight * FfxFloat32x4(1.0f, 1.0f, 1.0f, 1.0f); |
|||
packedTotals.xy *= nearestSsaoVals; |
|||
packedTotals.zw *= nearestSsaoVals; |
|||
FfxFloat32x4 packedTotalWeights = epsilonWeight * FfxFloat32x4(1.0f, 1.0f, 1.0f, 1.0f); |
|||
|
|||
FfxFloat32 distanceSigma = BilateralSimilarityDistanceSigma(); |
|||
FfxFloat32x2 packedDistSigma = FfxFloat32x2(1.0f / distanceSigma, 1.0f / distanceSigma); |
|||
FfxFloat32 sigma = BilateralSigmaSquared(); |
|||
FfxFloat32x2 packedSigma = FfxFloat32x2(1.0f / sigma, 1.0f / sigma); |
|||
|
|||
for (FfxInt32 x = -width; x <= width; ++x) |
|||
{ |
|||
for (FfxInt32 y = -height; y <= height; ++y) |
|||
{ |
|||
FfxInt32x2 bufferCoord = baseBufferCoord + FfxInt32x2(x, y); |
|||
|
|||
FFX_CACAO_BilateralBufferVal bufferVal = s_FFX_CACAO_BilateralUpscaleBuffer[bufferCoord.x][bufferCoord.y]; |
|||
|
|||
FfxFloat32x2 u = FfxFloat32x2(x, x) - FfxFloat32x2(0.0f, 0.5f); |
|||
FfxFloat32x2 v1 = FfxFloat32x2(y, y) - FfxFloat32x2(0.0f, 0.0f); |
|||
FfxFloat32x2 v2 = FfxFloat32x2(y, y) - FfxFloat32x2(0.5f, 0.5f); |
|||
u = u * u; |
|||
v1 = v1 * v1; |
|||
v2 = v2 * v2; |
|||
|
|||
FfxFloat32x2 dist1 = u + v1; |
|||
FfxFloat32x2 dist2 = u + v2; |
|||
|
|||
FfxFloat32x2 wx1 = exp(-dist1 * packedSigma); |
|||
FfxFloat32x2 wx2 = exp(-dist2 * packedSigma); |
|||
|
|||
FfxFloat32x2 bufferPackedDepths = ffxUnpackF32(bufferVal.packedDepths); |
|||
|
|||
FfxFloat32x2 diff1 = packedDepths.xy - bufferPackedDepths; |
|||
FfxFloat32x2 diff2 = packedDepths.zw - bufferPackedDepths; |
|||
diff1 *= diff1; |
|||
diff2 *= diff2; |
|||
|
|||
FfxFloat32x2 wy1 = exp(-diff1 * packedDistSigma); |
|||
FfxFloat32x2 wy2 = exp(-diff2 * packedDistSigma); |
|||
|
|||
FfxFloat32x2 weight1 = wx1 * wy1; |
|||
FfxFloat32x2 weight2 = wx2 * wy2; |
|||
|
|||
FfxFloat32x2 packedSsaoVals = ffxUnpackF32(bufferVal.packedSsaoVals); |
|||
packedTotals.xy += packedSsaoVals * weight1; |
|||
packedTotals.zw += packedSsaoVals * weight2; |
|||
packedTotalWeights.xy += weight1; |
|||
packedTotalWeights.zw += weight2; |
|||
} |
|||
} |
|||
|
|||
FfxUInt32x2 outputCoord = 2 * tid; |
|||
FfxFloat32x4 outputValues = packedTotals / packedTotalWeights; |
|||
outputValues = pow(outputValues, FfxFloat32x4(2.2, 2.2, 2.2, 2.2)); |
|||
#endif //FFX_HALF |
|||
FFX_CACAO_BilateralUpscale_StoreOutput(outputCoord, FfxInt32x2(0, 0), outputValues.x); // totals[0] / totalWeights[0]; |
|||
FFX_CACAO_BilateralUpscale_StoreOutput(outputCoord, FfxInt32x2(1, 0), outputValues.y); // totals[1] / totalWeights[1]; |
|||
FFX_CACAO_BilateralUpscale_StoreOutput(outputCoord, FfxInt32x2(0, 1), outputValues.z); // totals[2] / totalWeights[2]; |
|||
FFX_CACAO_BilateralUpscale_StoreOutput(outputCoord, FfxInt32x2(1, 1), outputValues.w); // totals[3] / totalWeights[3]; |
|||
} |
|||
|
|||
|
|||
void FFX_CACAO_UpscaleBilateral5x5Smart(FfxUInt32x2 tid, FfxUInt32x2 gtid, FfxUInt32x2 gid) |
|||
{ |
|||
FFX_CACAO_BilateralUpscaleNxN(tid, gtid, gid, 2, 2, true); |
|||
} |
|||
|
|||
void FFX_CACAO_UpscaleBilateral5x5NonSmart(FfxUInt32x2 tid, FfxUInt32x2 gtid, FfxUInt32x2 gid) |
|||
{ |
|||
FFX_CACAO_BilateralUpscaleNxN(tid, gtid, gid, 2, 2, false); |
|||
} |
|||
|
|||
void FFX_CACAO_UpscaleBilateral7x7(FfxUInt32x2 tid, FfxUInt32x2 gtid, FfxUInt32x2 gid) |
|||
{ |
|||
FFX_CACAO_BilateralUpscaleNxN(tid, gtid, gid, 3, 3, true); |
|||
} |
|||
|
|||
#if FFX_HALF |
|||
void FFX_CACAO_UpscaleBilateral5x5Half(FfxUInt32x2 tid, FfxUInt32x2 gtid, FfxUInt32x2 gid) |
|||
{ |
|||
const FfxInt32 width = 2, height = 2; |
|||
|
|||
// fill in group shared buffer |
|||
{ |
|||
FfxUInt32 threadNum = (gtid.y * FFX_CACAO_BILATERAL_UPSCALE_WIDTH + gtid.x) * 3; |
|||
FfxUInt32x2 bufferCoord = FfxUInt32x2(threadNum % FFX_CACAO_BILATERAL_UPSCALE_BUFFER_WIDTH, threadNum / FFX_CACAO_BILATERAL_UPSCALE_BUFFER_WIDTH); |
|||
FfxUInt32x2 imageCoord = (gid * FfxUInt32x2(FFX_CACAO_BILATERAL_UPSCALE_WIDTH, FFX_CACAO_BILATERAL_UPSCALE_HEIGHT)) + bufferCoord - 2; |
|||
|
|||
for (FfxInt32 i = 0; i < 3; ++i) |
|||
{ |
|||
FfxFloat32x2 sampleLoc0 = (FfxFloat32x2(imageCoord / 2) + 0.5f) * SSAOBufferInverseDimensions(); |
|||
FfxFloat32x2 sampleLoc1 = sampleLoc0; |
|||
switch ((imageCoord.y % 2) * 2 + (imageCoord.x % 2)) { |
|||
case 0: |
|||
sampleLoc1 -= 0.5f * SSAOBufferInverseDimensions(); |
|||
break; |
|||
case 1: |
|||
sampleLoc0.x += 0.5f * SSAOBufferInverseDimensions().x; |
|||
sampleLoc1.y -= 0.5f * SSAOBufferInverseDimensions().y; |
|||
break; |
|||
case 2: |
|||
sampleLoc0.y += 0.5f * SSAOBufferInverseDimensions().y; |
|||
sampleLoc1.x -= 0.5f * SSAOBufferInverseDimensions().x; |
|||
break; |
|||
case 3: |
|||
sampleLoc0 += 0.5f * SSAOBufferInverseDimensions(); |
|||
break; |
|||
} |
|||
|
|||
FfxFloat32 ssaoVal0 = FFX_CACAO_BilateralUpscale_SampleSSAOPoint(sampleLoc0, 0); |
|||
FfxFloat32 ssaoVal1 = FFX_CACAO_BilateralUpscale_SampleSSAOPoint(sampleLoc1, 3); |
|||
|
|||
FfxUInt32x2 depthArrayBufferCoord = FfxUInt32x2((imageCoord / 2) + DeinterleavedDepthBufferOffset()); |
|||
FfxUInt32 depthArrayBufferIndex = (imageCoord.y % 2) * 3; |
|||
++imageCoord.x; |
|||
|
|||
FFX_CACAO_BilateralBufferVal bufferVal; |
|||
|
|||
FfxFloat32 depth = FFX_CACAO_BilateralUpscale_LoadDownscaledDepth(depthArrayBufferCoord, depthArrayBufferIndex); |
|||
FfxFloat32 ssaoVal = (ssaoVal0 + ssaoVal1) * 0.5f; |
|||
|
|||
bufferVal.packedDepths = ffxPackF16(FfxFloat16x2(depth, depth)); |
|||
bufferVal.packedSsaoVals = ffxPackF16(FfxFloat16x2(ssaoVal, ssaoVal)); |
|||
|
|||
s_FFX_CACAO_BilateralUpscaleBuffer[bufferCoord.x + i][bufferCoord.y] = bufferVal; |
|||
} |
|||
} |
|||
|
|||
FFX_GROUP_MEMORY_BARRIER(); |
|||
|
|||
FfxFloat32 depths[4]; |
|||
// load depths |
|||
{ |
|||
FfxInt32x2 fullBufferCoord = FfxInt32x2(2 * tid); |
|||
FfxInt32x2 fullDepthBufferCoord = fullBufferCoord + DepthBufferOffset(); |
|||
|
|||
FfxFloat32x4 screenSpaceDepths = FFX_CACAO_BilateralUpscale_LoadDepths(fullDepthBufferCoord); |
|||
|
|||
depths[0] = FFX_CACAO_ScreenSpaceToViewSpaceDepth(screenSpaceDepths.x); |
|||
depths[1] = FFX_CACAO_ScreenSpaceToViewSpaceDepth(screenSpaceDepths.y); |
|||
depths[2] = FFX_CACAO_ScreenSpaceToViewSpaceDepth(screenSpaceDepths.z); |
|||
depths[3] = FFX_CACAO_ScreenSpaceToViewSpaceDepth(screenSpaceDepths.w); |
|||
} |
|||
FfxFloat16x4 packedDepths = FfxFloat16x4(depths[0], depths[1], depths[2], depths[3]); |
|||
|
|||
FfxInt32x2 baseBufferCoord = FfxInt32x2(gtid) + FfxInt32x2(width, height); |
|||
|
|||
FfxFloat16 epsilonWeight = FfxFloat16(1e-3f); |
|||
FfxFloat16x2 nearestSsaoVals = ffxUnpackF16(s_FFX_CACAO_BilateralUpscaleBuffer[baseBufferCoord.x][baseBufferCoord.y].packedSsaoVals); |
|||
FfxFloat16x4 packedTotals = epsilonWeight * FfxFloat16x4(1.0f, 1.0f, 1.0f, 1.0f); |
|||
packedTotals.xy *= nearestSsaoVals; |
|||
packedTotals.zw *= nearestSsaoVals; |
|||
FfxFloat16x4 packedTotalWeights = epsilonWeight * FfxFloat16x4(1.0f, 1.0f, 1.0f, 1.0f); |
|||
|
|||
FfxFloat32 distanceSigma = BilateralSimilarityDistanceSigma(); |
|||
FfxFloat16x2 packedDistSigma = FfxFloat16x2(1.0f / distanceSigma, 1.0f / distanceSigma); |
|||
FfxFloat32 sigma = BilateralSigmaSquared(); |
|||
FfxFloat16x2 packedSigma = FfxFloat16x2(1.0f / sigma, 1.0f / sigma); |
|||
|
|||
for (FfxInt32 x = -width; x <= width; ++x) |
|||
{ |
|||
for (FfxInt32 y = -height; y <= height; ++y) |
|||
{ |
|||
FfxInt32x2 bufferCoord = baseBufferCoord + FfxInt32x2(x, y); |
|||
|
|||
FFX_CACAO_BilateralBufferVal bufferVal = s_FFX_CACAO_BilateralUpscaleBuffer[bufferCoord.x][bufferCoord.y]; |
|||
|
|||
FfxFloat16x2 u = FfxFloat16x2(x, x) - FfxFloat16x2(0.0f, 0.5f); |
|||
FfxFloat16x2 v1 = FfxFloat16x2(y, y) - FfxFloat16x2(0.0f, 0.0f); |
|||
FfxFloat16x2 v2 = FfxFloat16x2(y, y) - FfxFloat16x2(0.5f, 0.5f); |
|||
u = u * u; |
|||
v1 = v1 * v1; |
|||
v2 = v2 * v2; |
|||
|
|||
FfxFloat16x2 dist1 = u + v1; |
|||
FfxFloat16x2 dist2 = u + v2; |
|||
|
|||
FfxFloat16x2 wx1 = exp(-dist1 * packedSigma); |
|||
FfxFloat16x2 wx2 = exp(-dist2 * packedSigma); |
|||
|
|||
FfxFloat16x2 bufferPackedDepths = ffxUnpackF16(bufferVal.packedDepths); |
|||
|
|||
FfxFloat16x2 diff1 = packedDepths.xy - bufferPackedDepths; |
|||
FfxFloat16x2 diff2 = packedDepths.zw - bufferPackedDepths; |
|||
diff1 *= diff1; |
|||
diff2 *= diff2; |
|||
|
|||
FfxFloat16x2 wy1 = exp(-diff1 * packedDistSigma); |
|||
FfxFloat16x2 wy2 = exp(-diff2 * packedDistSigma); |
|||
|
|||
FfxFloat16x2 weight1 = wx1 * wy1; |
|||
FfxFloat16x2 weight2 = wx2 * wy2; |
|||
|
|||
FfxFloat16x2 packedSsaoVals = ffxUnpackF16(bufferVal.packedSsaoVals); |
|||
packedTotals.xy += packedSsaoVals * weight1; |
|||
packedTotals.zw += packedSsaoVals * weight2; |
|||
packedTotalWeights.xy += weight1; |
|||
packedTotalWeights.zw += weight2; |
|||
} |
|||
} |
|||
|
|||
FfxUInt32x2 outputCoord = 2 * tid; |
|||
FfxFloat16x4 outputValues = packedTotals / packedTotalWeights; |
|||
FFX_CACAO_BilateralUpscale_StoreOutput(outputCoord, FfxInt32x2(0, 0), outputValues.x); // totals[0] / totalWeights[0]; |
|||
FFX_CACAO_BilateralUpscale_StoreOutput(outputCoord, FfxInt32x2(1, 0), outputValues.y); // totals[1] / totalWeights[1]; |
|||
FFX_CACAO_BilateralUpscale_StoreOutput(outputCoord, FfxInt32x2(0, 1), outputValues.z); // totals[2] / totalWeights[2]; |
|||
FFX_CACAO_BilateralUpscale_StoreOutput(outputCoord, FfxInt32x2(1, 1), outputValues.w); // totals[3] / totalWeights[3]; |
|||
} |
|||
#else |
|||
void FFX_CACAO_UpscaleBilateral5x5(FfxUInt32x2 tid, FfxUInt32x2 gtid, FfxUInt32x2 gid) |
|||
{ |
|||
const FfxInt32 width = 2, height = 2; |
|||
|
|||
// fill in group shared buffer |
|||
{ |
|||
FfxUInt32 threadNum = (gtid.y * FFX_CACAO_BILATERAL_UPSCALE_WIDTH + gtid.x) * 3; |
|||
FfxUInt32x2 bufferCoord = FfxUInt32x2(threadNum % FFX_CACAO_BILATERAL_UPSCALE_BUFFER_WIDTH, threadNum / FFX_CACAO_BILATERAL_UPSCALE_BUFFER_WIDTH); |
|||
FfxUInt32x2 imageCoord = (gid * FfxUInt32x2(FFX_CACAO_BILATERAL_UPSCALE_WIDTH, FFX_CACAO_BILATERAL_UPSCALE_HEIGHT)) + bufferCoord - 2; |
|||
|
|||
for (FfxInt32 i = 0; i < 3; ++i) |
|||
{ |
|||
FfxFloat32x2 sampleLoc0 = (FfxFloat32x2(imageCoord / 2) + 0.5f) * SSAOBufferInverseDimensions(); |
|||
FfxFloat32x2 sampleLoc1 = sampleLoc0; |
|||
switch ((imageCoord.y % 2) * 2 + (imageCoord.x % 2)) { |
|||
case 0: |
|||
sampleLoc1 -= 0.5f * SSAOBufferInverseDimensions(); |
|||
break; |
|||
case 1: |
|||
sampleLoc0.x += 0.5f * SSAOBufferInverseDimensions().x; |
|||
sampleLoc1.y -= 0.5f * SSAOBufferInverseDimensions().y; |
|||
break; |
|||
case 2: |
|||
sampleLoc0.y += 0.5f * SSAOBufferInverseDimensions().y; |
|||
sampleLoc1.x -= 0.5f * SSAOBufferInverseDimensions().x; |
|||
break; |
|||
case 3: |
|||
sampleLoc0 += 0.5f * SSAOBufferInverseDimensions(); |
|||
break; |
|||
} |
|||
|
|||
FfxFloat32 ssaoVal0 = FFX_CACAO_BilateralUpscale_SampleSSAOPoint(sampleLoc0, 0); |
|||
FfxFloat32 ssaoVal1 = FFX_CACAO_BilateralUpscale_SampleSSAOPoint(sampleLoc1, 3); |
|||
|
|||
FfxUInt32x2 depthArrayBufferCoord = FfxUInt32x2((imageCoord / 2) + DeinterleavedDepthBufferOffset()); |
|||
FfxUInt32 depthArrayBufferIndex = (imageCoord.y % 2) * 3; |
|||
++imageCoord.x; |
|||
|
|||
FFX_CACAO_BilateralBufferVal bufferVal; |
|||
|
|||
FfxFloat32 depth = FFX_CACAO_BilateralUpscale_LoadDownscaledDepth(depthArrayBufferCoord, depthArrayBufferIndex); |
|||
FfxFloat32 ssaoVal = (ssaoVal0 + ssaoVal1) * 0.5f; |
|||
|
|||
bufferVal.packedDepths = ffxPackF32(FfxFloat32x2(depth, depth)); |
|||
bufferVal.packedSsaoVals = ffxPackF32(FfxFloat32x2(ssaoVal, ssaoVal)); |
|||
|
|||
s_FFX_CACAO_BilateralUpscaleBuffer[bufferCoord.x + i][bufferCoord.y] = bufferVal; |
|||
} |
|||
} |
|||
|
|||
FFX_GROUP_MEMORY_BARRIER(); |
|||
|
|||
FfxFloat32 depths[4]; |
|||
// load depths |
|||
{ |
|||
FfxInt32x2 fullBufferCoord = FfxInt32x2(2 * tid); |
|||
FfxInt32x2 fullDepthBufferCoord = fullBufferCoord + DepthBufferOffset(); |
|||
|
|||
FfxFloat32x4 screenSpaceDepths = FFX_CACAO_BilateralUpscale_LoadDepths(fullDepthBufferCoord); |
|||
|
|||
depths[0] = FFX_CACAO_ScreenSpaceToViewSpaceDepth(screenSpaceDepths.x); |
|||
depths[1] = FFX_CACAO_ScreenSpaceToViewSpaceDepth(screenSpaceDepths.y); |
|||
depths[2] = FFX_CACAO_ScreenSpaceToViewSpaceDepth(screenSpaceDepths.z); |
|||
depths[3] = FFX_CACAO_ScreenSpaceToViewSpaceDepth(screenSpaceDepths.w); |
|||
} |
|||
FfxFloat32x4 packedDepths = FfxFloat32x4(depths[0], depths[1], depths[2], depths[3]); |
|||
|
|||
FfxInt32x2 baseBufferCoord = FfxInt32x2(gtid) + FfxInt32x2(width, height); |
|||
|
|||
FfxFloat32 epsilonWeight = FfxFloat32(1e-3f); |
|||
FfxFloat32x2 nearestSsaoVals = ffxUnpackF32(s_FFX_CACAO_BilateralUpscaleBuffer[baseBufferCoord.x][baseBufferCoord.y].packedSsaoVals); |
|||
FfxFloat32x4 packedTotals = epsilonWeight * FfxFloat32x4(1.0f, 1.0f, 1.0f, 1.0f); |
|||
packedTotals.xy *= nearestSsaoVals; |
|||
packedTotals.zw *= nearestSsaoVals; |
|||
FfxFloat32x4 packedTotalWeights = epsilonWeight * FfxFloat32x4(1.0f, 1.0f, 1.0f, 1.0f); |
|||
|
|||
FfxFloat32 distanceSigma = BilateralSimilarityDistanceSigma(); |
|||
FfxFloat32x2 packedDistSigma = FfxFloat32x2(1.0f / distanceSigma, 1.0f / distanceSigma); |
|||
FfxFloat32 sigma = BilateralSigmaSquared(); |
|||
FfxFloat32x2 packedSigma = FfxFloat32x2(1.0f / sigma, 1.0f / sigma); |
|||
|
|||
for (FfxInt32 x = -width; x <= width; ++x) |
|||
{ |
|||
for (FfxInt32 y = -height; y <= height; ++y) |
|||
{ |
|||
FfxInt32x2 bufferCoord = baseBufferCoord + FfxInt32x2(x, y); |
|||
|
|||
FFX_CACAO_BilateralBufferVal bufferVal = s_FFX_CACAO_BilateralUpscaleBuffer[bufferCoord.x][bufferCoord.y]; |
|||
|
|||
FfxFloat32x2 u = FfxFloat32x2(x, x) - FfxFloat32x2(0.0f, 0.5f); |
|||
FfxFloat32x2 v1 = FfxFloat32x2(y, y) - FfxFloat32x2(0.0f, 0.0f); |
|||
FfxFloat32x2 v2 = FfxFloat32x2(y, y) - FfxFloat32x2(0.5f, 0.5f); |
|||
u = u * u; |
|||
v1 = v1 * v1; |
|||
v2 = v2 * v2; |
|||
|
|||
FfxFloat32x2 dist1 = u + v1; |
|||
FfxFloat32x2 dist2 = u + v2; |
|||
|
|||
FfxFloat32x2 wx1 = exp(-dist1 * packedSigma); |
|||
FfxFloat32x2 wx2 = exp(-dist2 * packedSigma); |
|||
|
|||
FfxFloat32x2 bufferPackedDepths = ffxUnpackF32(bufferVal.packedDepths); |
|||
|
|||
FfxFloat32x2 diff1 = packedDepths.xy - bufferPackedDepths; |
|||
FfxFloat32x2 diff2 = packedDepths.zw - bufferPackedDepths; |
|||
diff1 *= diff1; |
|||
diff2 *= diff2; |
|||
|
|||
FfxFloat32x2 wy1 = exp(-diff1 * packedDistSigma); |
|||
FfxFloat32x2 wy2 = exp(-diff2 * packedDistSigma); |
|||
|
|||
FfxFloat32x2 weight1 = wx1 * wy1; |
|||
FfxFloat32x2 weight2 = wx2 * wy2; |
|||
|
|||
FfxFloat32x2 packedSsaoVals = ffxUnpackF32(bufferVal.packedSsaoVals); |
|||
packedTotals.xy += packedSsaoVals * weight1; |
|||
packedTotals.zw += packedSsaoVals * weight2; |
|||
packedTotalWeights.xy += weight1; |
|||
packedTotalWeights.zw += weight2; |
|||
} |
|||
} |
|||
|
|||
FfxUInt32x2 outputCoord = 2 * tid; |
|||
FfxFloat32x4 outputValues = packedTotals / packedTotalWeights; |
|||
FFX_CACAO_BilateralUpscale_StoreOutput(outputCoord, FfxInt32x2(0, 0), outputValues.x); // totals[0] / totalWeights[0]; |
|||
FFX_CACAO_BilateralUpscale_StoreOutput(outputCoord, FfxInt32x2(1, 0), outputValues.y); // totals[1] / totalWeights[1]; |
|||
FFX_CACAO_BilateralUpscale_StoreOutput(outputCoord, FfxInt32x2(0, 1), outputValues.z); // totals[2] / totalWeights[2]; |
|||
FFX_CACAO_BilateralUpscale_StoreOutput(outputCoord, FfxInt32x2(1, 1), outputValues.w); // totals[3] / totalWeights[3]; |
|||
} |
|||
#endif //FFX_HALF |
|||
|
|||
void FFX_CACAO_UpscaleBilateral5x5Pass(FfxUInt32x2 tid, FfxUInt32x2 gtid, FfxUInt32x2 gid) |
|||
{ |
|||
#if FFX_CACAO_OPTION_APPLY_SMART |
|||
FFX_CACAO_UpscaleBilateral5x5Smart(tid, gtid, gid); |
|||
#else |
|||
|
|||
#if FFX_HALF |
|||
FFX_CACAO_UpscaleBilateral5x5Half(tid, gtid, gid); |
|||
#else |
|||
FFX_CACAO_UpscaleBilateral5x5NonSmart(tid, gtid, gid); |
|||
#endif |
|||
|
|||
#endif |
|||
} |
|||
|
|||
#undef FFX_CACAO_BILATERAL_UPSCALE_BUFFER_WIDTH |
|||
#undef FFX_CACAO_BILATERAL_UPSCALE_BUFFER_HEIGHT |
|||
@ -0,0 +1,27 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 65c2e0f8926d7cb489d69ff3fb5f5175 |
|||
PluginImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
iconMap: {} |
|||
executionOrder: {} |
|||
defineConstraints: [] |
|||
isPreloaded: 0 |
|||
isOverridable: 0 |
|||
isExplicitlyReferenced: 0 |
|||
validateReferences: 1 |
|||
platformData: |
|||
- first: |
|||
Any: |
|||
second: |
|||
enabled: 1 |
|||
settings: {} |
|||
- first: |
|||
Editor: Editor |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
DefaultValueInitialized: true |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,112 @@ |
|||
// This file is part of the FidelityFX SDK. |
|||
// |
|||
// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved. |
|||
// |
|||
// 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. |
|||
|
|||
|
|||
// packing/unpacking for edges; 2 bits per edge mean 4 gradient values (0, 0.33, 0.66, 1) for smoother transitions! |
|||
FfxFloat32 FFX_CACAO_PackEdges(FfxFloat32x4 edgesLRTB) |
|||
{ |
|||
edgesLRTB = round(ffxSaturate(edgesLRTB) * 3.05); |
|||
return dot(edgesLRTB, FfxFloat32x4(64.0 / 255.0, 16.0 / 255.0, 4.0 / 255.0, 1.0 / 255.0)); |
|||
} |
|||
|
|||
FfxFloat32x4 FFX_CACAO_UnpackEdges(FfxFloat32 _packedVal) |
|||
{ |
|||
FfxUInt32 packedVal = FfxUInt32(_packedVal * 255.5); |
|||
FfxFloat32x4 edgesLRTB; |
|||
edgesLRTB.x = FfxFloat32((packedVal >> 6) & 0x03) / 3.0; // there's really no need for mask (as it's an 8 bit input) but I'll leave it in so it doesn't cause any trouble in the future |
|||
edgesLRTB.y = FfxFloat32((packedVal >> 4) & 0x03) / 3.0; |
|||
edgesLRTB.z = FfxFloat32((packedVal >> 2) & 0x03) / 3.0; |
|||
edgesLRTB.w = FfxFloat32((packedVal >> 0) & 0x03) / 3.0; |
|||
|
|||
return ffxSaturate(edgesLRTB + InvSharpness()); |
|||
} |
|||
|
|||
FfxFloat32 FFX_CACAO_ScreenSpaceToViewSpaceDepth(FfxFloat32 screenDepth) |
|||
{ |
|||
#if UNITY_REVERSED_Z == 1 |
|||
screenDepth = 1.0 - screenDepth; |
|||
#endif |
|||
|
|||
FfxFloat32 depthLinearizeMul = DepthUnpackConsts().x; |
|||
FfxFloat32 depthLinearizeAdd = DepthUnpackConsts().y; |
|||
|
|||
return depthLinearizeMul * ffxInvertSafe(depthLinearizeAdd - screenDepth); |
|||
} |
|||
|
|||
FfxFloat32x4 FFX_CACAO_ScreenSpaceToViewSpaceDepth(FfxFloat32x4 screenDepth) |
|||
{ |
|||
#if UNITY_REVERSED_Z == 1 |
|||
screenDepth = 1.0 - screenDepth; |
|||
#endif |
|||
|
|||
FfxFloat32 depthLinearizeMul = DepthUnpackConsts().x; |
|||
FfxFloat32 depthLinearizeAdd = DepthUnpackConsts().y; |
|||
|
|||
return depthLinearizeMul * ffxInvertSafe(depthLinearizeAdd - screenDepth); |
|||
} |
|||
|
|||
FfxFloat32x4 FFX_CACAO_CalculateEdges(const FfxFloat32 centerZ, const FfxFloat32 leftZ, const FfxFloat32 rightZ, const FfxFloat32 topZ, const FfxFloat32 bottomZ) |
|||
{ |
|||
// slope-sensitive depth-based edge detection |
|||
FfxFloat32x4 edgesLRTB = FfxFloat32x4(leftZ, rightZ, topZ, bottomZ) - centerZ; |
|||
FfxFloat32x4 edgesLRTBSlopeAdjusted = edgesLRTB + edgesLRTB.yxwz; |
|||
edgesLRTB = min(abs(edgesLRTB), abs(edgesLRTBSlopeAdjusted)); |
|||
return ffxSaturate((1.3 - edgesLRTB / (centerZ * 0.040))); |
|||
} |
|||
|
|||
FfxFloat32x3 FFX_CACAO_NDCToViewSpace(FfxFloat32x2 pos, FfxFloat32 viewspaceDepth) |
|||
{ |
|||
FfxFloat32x3 ret; |
|||
|
|||
ret.xy = (NDCToViewMul() * pos.xy + NDCToViewAdd()) * viewspaceDepth; |
|||
|
|||
ret.z = viewspaceDepth; |
|||
|
|||
return ret; |
|||
} |
|||
|
|||
FfxFloat32x3 FFX_CACAO_DepthBufferUVToViewSpace(FfxFloat32x2 pos, FfxFloat32 viewspaceDepth) |
|||
{ |
|||
FfxFloat32x3 ret; |
|||
ret.xy = (DepthBufferUVToViewMul() * pos.xy + DepthBufferUVToViewAdd()) * viewspaceDepth; |
|||
ret.z = viewspaceDepth; |
|||
return ret; |
|||
} |
|||
|
|||
FfxFloat32x3 FFX_CACAO_CalculateNormal(const FfxFloat32x4 edgesLRTB, FfxFloat32x3 pixCenterPos, FfxFloat32x3 pixLPos, FfxFloat32x3 pixRPos, FfxFloat32x3 pixTPos, FfxFloat32x3 pixBPos) |
|||
{ |
|||
// Get this pixel's viewspace normal |
|||
FfxFloat32x4 acceptedNormals = FfxFloat32x4(edgesLRTB.x*edgesLRTB.z, edgesLRTB.z*edgesLRTB.y, edgesLRTB.y*edgesLRTB.w, edgesLRTB.w*edgesLRTB.x); |
|||
|
|||
pixLPos = normalize(pixLPos - pixCenterPos); |
|||
pixRPos = normalize(pixRPos - pixCenterPos); |
|||
pixTPos = normalize(pixTPos - pixCenterPos); |
|||
pixBPos = normalize(pixBPos - pixCenterPos); |
|||
|
|||
FfxFloat32x3 pixelNormal = FfxFloat32x3(0, 0, -0.0005); |
|||
pixelNormal += (acceptedNormals.x) * cross(pixLPos, pixTPos); |
|||
pixelNormal += (acceptedNormals.y) * cross(pixTPos, pixRPos); |
|||
pixelNormal += (acceptedNormals.z) * cross(pixRPos, pixBPos); |
|||
pixelNormal += (acceptedNormals.w) * cross(pixBPos, pixLPos); |
|||
pixelNormal = normalize(pixelNormal); |
|||
|
|||
return pixelNormal; |
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
fileFormatVersion: 2 |
|||
guid: d47e972d29a45fc42bfd2c7255cdf4ad |
|||
PluginImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
iconMap: {} |
|||
executionOrder: {} |
|||
defineConstraints: [] |
|||
isPreloaded: 0 |
|||
isOverridable: 0 |
|||
isExplicitlyReferenced: 0 |
|||
validateReferences: 1 |
|||
platformData: |
|||
- first: |
|||
Any: |
|||
second: |
|||
enabled: 1 |
|||
settings: {} |
|||
- first: |
|||
Editor: Editor |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
DefaultValueInitialized: true |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,8 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 1f1bcce5304ce264ca8ec92e4ed904d7 |
|||
folderAsset: yes |
|||
DefaultImporter: |
|||
externalObjects: {} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,520 @@ |
|||
// This file is part of the FidelityFX SDK. |
|||
// |
|||
// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved. |
|||
// |
|||
// 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. |
|||
|
|||
|
|||
#ifndef FFX_COMMON_TYPES_H |
|||
#define FFX_COMMON_TYPES_H |
|||
|
|||
#if defined(FFX_CPU) |
|||
#define FFX_PARAMETER_IN |
|||
#define FFX_PARAMETER_OUT |
|||
#define FFX_PARAMETER_INOUT |
|||
#define FFX_PARAMETER_UNIFORM |
|||
#elif defined(FFX_HLSL) |
|||
#define FFX_PARAMETER_IN in |
|||
#define FFX_PARAMETER_OUT out |
|||
#define FFX_PARAMETER_INOUT inout |
|||
#define FFX_PARAMETER_UNIFORM uniform |
|||
#elif defined(FFX_GLSL) |
|||
#define FFX_PARAMETER_IN in |
|||
#define FFX_PARAMETER_OUT out |
|||
#define FFX_PARAMETER_INOUT inout |
|||
#define FFX_PARAMETER_UNIFORM const //[cacao_placeholder] until a better fit is found! |
|||
#endif // #if defined(FFX_CPU) |
|||
|
|||
#if defined(FFX_CPU) |
|||
/// A typedef for a boolean value. |
|||
/// |
|||
/// @ingroup CPUTypes |
|||
typedef bool FfxBoolean; |
|||
|
|||
/// A typedef for a unsigned 8bit integer. |
|||
/// |
|||
/// @ingroup CPUTypes |
|||
typedef uint8_t FfxUInt8; |
|||
|
|||
/// A typedef for a unsigned 16bit integer. |
|||
/// |
|||
/// @ingroup CPUTypes |
|||
typedef uint16_t FfxUInt16; |
|||
|
|||
/// A typedef for a unsigned 32bit integer. |
|||
/// |
|||
/// @ingroup CPUTypes |
|||
typedef uint32_t FfxUInt32; |
|||
|
|||
/// A typedef for a unsigned 64bit integer. |
|||
/// |
|||
/// @ingroup CPUTypes |
|||
typedef uint64_t FfxUInt64; |
|||
|
|||
/// A typedef for a signed 8bit integer. |
|||
/// |
|||
/// @ingroup CPUTypes |
|||
typedef int8_t FfxInt8; |
|||
|
|||
/// A typedef for a signed 16bit integer. |
|||
/// |
|||
/// @ingroup CPUTypes |
|||
typedef int16_t FfxInt16; |
|||
|
|||
/// A typedef for a signed 32bit integer. |
|||
/// |
|||
/// @ingroup CPUTypes |
|||
typedef int32_t FfxInt32; |
|||
|
|||
/// A typedef for a signed 64bit integer. |
|||
/// |
|||
/// @ingroup CPUTypes |
|||
typedef int64_t FfxInt64; |
|||
|
|||
/// A typedef for a floating point value. |
|||
/// |
|||
/// @ingroup CPUTypes |
|||
typedef float FfxFloat32; |
|||
|
|||
/// A typedef for a 2-dimensional floating point value. |
|||
/// |
|||
/// @ingroup CPUTypes |
|||
typedef float FfxFloat32x2[2]; |
|||
|
|||
/// A typedef for a 3-dimensional floating point value. |
|||
/// |
|||
/// @ingroup CPUTypes |
|||
typedef float FfxFloat32x3[3]; |
|||
|
|||
/// A typedef for a 4-dimensional floating point value. |
|||
/// |
|||
/// @ingroup CPUTypes |
|||
typedef float FfxFloat32x4[4]; |
|||
|
|||
/// A typedef for a 2-dimensional 32bit unsigned integer. |
|||
/// |
|||
/// @ingroup CPUTypes |
|||
typedef uint32_t FfxUInt32x2[2]; |
|||
|
|||
/// A typedef for a 3-dimensional 32bit unsigned integer. |
|||
/// |
|||
/// @ingroup CPUTypes |
|||
typedef uint32_t FfxUInt32x3[3]; |
|||
|
|||
/// A typedef for a 4-dimensional 32bit unsigned integer. |
|||
/// |
|||
/// @ingroup CPUTypes |
|||
typedef uint32_t FfxUInt32x4[4]; |
|||
#endif // #if defined(FFX_CPU) |
|||
|
|||
#if defined(FFX_HLSL) |
|||
|
|||
#define FfxFloat32Mat4 matrix <float, 4, 4> |
|||
#define FfxFloat32Mat3 matrix <float, 3, 3> |
|||
|
|||
/// A typedef for a boolean value. |
|||
/// |
|||
/// @ingroup HLSLTypes |
|||
typedef bool FfxBoolean; |
|||
|
|||
#if FFX_HLSL_SM>=62 |
|||
|
|||
/// @defgroup HLSL62Types HLSL 6.2 And Above Types |
|||
/// HLSL 6.2 and above type defines for all commonly used variables |
|||
/// |
|||
/// @ingroup HLSLTypes |
|||
|
|||
/// A typedef for a floating point value. |
|||
/// |
|||
/// @ingroup HLSL62Types |
|||
typedef float32_t FfxFloat32; |
|||
|
|||
/// A typedef for a 2-dimensional floating point value. |
|||
/// |
|||
/// @ingroup HLSL62Types |
|||
typedef float32_t2 FfxFloat32x2; |
|||
|
|||
/// A typedef for a 3-dimensional floating point value. |
|||
/// |
|||
/// @ingroup HLSL62Types |
|||
typedef float32_t3 FfxFloat32x3; |
|||
|
|||
/// A typedef for a 4-dimensional floating point value. |
|||
/// |
|||
/// @ingroup HLSL62Types |
|||
typedef float32_t4 FfxFloat32x4; |
|||
|
|||
/// A [cacao_placeholder] typedef for matrix type until confirmed. |
|||
typedef float4x4 FfxFloat32x4x4; |
|||
typedef float3x3 FfxFloat32x3x3; |
|||
typedef float2x2 FfxFloat32x2x2; |
|||
|
|||
/// A typedef for a unsigned 32bit integer. |
|||
/// |
|||
/// @ingroup HLSL62Types |
|||
typedef uint32_t FfxUInt32; |
|||
|
|||
/// A typedef for a 2-dimensional 32bit unsigned integer. |
|||
/// |
|||
/// @ingroup HLSL62Types |
|||
typedef uint32_t2 FfxUInt32x2; |
|||
|
|||
/// A typedef for a 3-dimensional 32bit unsigned integer. |
|||
/// |
|||
/// @ingroup HLSL62Types |
|||
typedef uint32_t3 FfxUInt32x3; |
|||
|
|||
/// A typedef for a 4-dimensional 32bit unsigned integer. |
|||
/// |
|||
/// @ingroup HLSL62Types |
|||
typedef uint32_t4 FfxUInt32x4; |
|||
|
|||
/// A typedef for a signed 32bit integer. |
|||
/// |
|||
/// @ingroup HLSL62Types |
|||
typedef int32_t FfxInt32; |
|||
|
|||
/// A typedef for a 2-dimensional signed 32bit integer. |
|||
/// |
|||
/// @ingroup HLSL62Types |
|||
typedef int32_t2 FfxInt32x2; |
|||
|
|||
/// A typedef for a 3-dimensional signed 32bit integer. |
|||
/// |
|||
/// @ingroup HLSL62Types |
|||
typedef int32_t3 FfxInt32x3; |
|||
|
|||
/// A typedef for a 4-dimensional signed 32bit integer. |
|||
/// |
|||
/// @ingroup HLSL62Types |
|||
typedef int32_t4 FfxInt32x4; |
|||
|
|||
#else // #if FFX_HLSL_SM>=62 |
|||
|
|||
/// @defgroup HLSLBaseTypes HLSL 6.1 And Below Types |
|||
/// HLSL 6.1 and below type defines for all commonly used variables |
|||
/// |
|||
/// @ingroup HLSLTypes |
|||
|
|||
#define FfxFloat32 float |
|||
#define FfxFloat32x2 float2 |
|||
#define FfxFloat32x3 float3 |
|||
#define FfxFloat32x4 float4 |
|||
|
|||
/// A [cacao_placeholder] typedef for matrix type until confirmed. |
|||
#define FfxFloat32x4x4 float4x4 |
|||
#define FfxFloat32x3x3 float3x3 |
|||
#define FfxFloat32x2x2 float2x2 |
|||
|
|||
/// A typedef for a unsigned 32bit integer. |
|||
/// |
|||
/// @ingroup GPU |
|||
typedef uint FfxUInt32; |
|||
typedef uint2 FfxUInt32x2; |
|||
typedef uint3 FfxUInt32x3; |
|||
typedef uint4 FfxUInt32x4; |
|||
|
|||
typedef int FfxInt32; |
|||
typedef int2 FfxInt32x2; |
|||
typedef int3 FfxInt32x3; |
|||
typedef int4 FfxInt32x4; |
|||
|
|||
#endif // #if FFX_HLSL_SM>=62 |
|||
|
|||
#if FFX_HALF |
|||
|
|||
#if FFX_HLSL_SM >= 62 |
|||
|
|||
typedef float16_t FfxFloat16; |
|||
typedef float16_t2 FfxFloat16x2; |
|||
typedef float16_t3 FfxFloat16x3; |
|||
typedef float16_t4 FfxFloat16x4; |
|||
|
|||
/// A typedef for an unsigned 16bit integer. |
|||
/// |
|||
/// @ingroup HLSLTypes |
|||
typedef uint16_t FfxUInt16; |
|||
typedef uint16_t2 FfxUInt16x2; |
|||
typedef uint16_t3 FfxUInt16x3; |
|||
typedef uint16_t4 FfxUInt16x4; |
|||
|
|||
/// A typedef for a signed 16bit integer. |
|||
/// |
|||
/// @ingroup HLSLTypes |
|||
typedef int16_t FfxInt16; |
|||
typedef int16_t2 FfxInt16x2; |
|||
typedef int16_t3 FfxInt16x3; |
|||
typedef int16_t4 FfxInt16x4; |
|||
#else // #if FFX_HLSL_SM>=62 |
|||
typedef min16float FfxFloat16; |
|||
typedef min16float2 FfxFloat16x2; |
|||
typedef min16float3 FfxFloat16x3; |
|||
typedef min16float4 FfxFloat16x4; |
|||
|
|||
/// A typedef for an unsigned 16bit integer. |
|||
/// |
|||
/// @ingroup HLSLTypes |
|||
typedef min16uint FfxUInt16; |
|||
typedef min16uint2 FfxUInt16x2; |
|||
typedef min16uint3 FfxUInt16x3; |
|||
typedef min16uint4 FfxUInt16x4; |
|||
|
|||
/// A typedef for a signed 16bit integer. |
|||
/// |
|||
/// @ingroup HLSLTypes |
|||
typedef min16int FfxInt16; |
|||
typedef min16int2 FfxInt16x2; |
|||
typedef min16int3 FfxInt16x3; |
|||
typedef min16int4 FfxInt16x4; |
|||
#endif // #if FFX_HLSL_SM>=62 |
|||
|
|||
#endif // FFX_HALF |
|||
|
|||
#endif // #if defined(FFX_HLSL) |
|||
|
|||
#if defined(FFX_GLSL) |
|||
|
|||
#define FfxFloat32Mat4 mat4 |
|||
#define FfxFloat32Mat3 mat3 |
|||
|
|||
/// A typedef for a boolean value. |
|||
/// |
|||
/// @ingroup GLSLTypes |
|||
#define FfxBoolean bool |
|||
#define FfxFloat32 float |
|||
#define FfxFloat32x2 vec2 |
|||
#define FfxFloat32x3 vec3 |
|||
#define FfxFloat32x4 vec4 |
|||
#define FfxUInt32 uint |
|||
#define FfxUInt32x2 uvec2 |
|||
#define FfxUInt32x3 uvec3 |
|||
#define FfxUInt32x4 uvec4 |
|||
#define FfxInt32 int |
|||
#define FfxInt32x2 ivec2 |
|||
#define FfxInt32x3 ivec3 |
|||
#define FfxInt32x4 ivec4 |
|||
|
|||
/// A [cacao_placeholder] typedef for matrix type until confirmed. |
|||
#define FfxFloat32x4x4 mat4 |
|||
#define FfxFloat32x3x3 mat3 |
|||
#define FfxFloat32x2x2 mat2 |
|||
|
|||
#if FFX_HALF |
|||
#define FfxFloat16 float16_t |
|||
#define FfxFloat16x2 f16vec2 |
|||
#define FfxFloat16x3 f16vec3 |
|||
#define FfxFloat16x4 f16vec4 |
|||
#define FfxUInt16 uint16_t |
|||
#define FfxUInt16x2 u16vec2 |
|||
#define FfxUInt16x3 u16vec3 |
|||
#define FfxUInt16x4 u16vec4 |
|||
#define FfxInt16 int16_t |
|||
#define FfxInt16x2 i16vec2 |
|||
#define FfxInt16x3 i16vec3 |
|||
#define FfxInt16x4 i16vec4 |
|||
#endif // FFX_HALF |
|||
#endif // #if defined(FFX_GLSL) |
|||
|
|||
// Global toggles: |
|||
// #define FFX_HALF (1) |
|||
// #define FFX_HLSL_SM (62) |
|||
|
|||
#if FFX_HALF |
|||
|
|||
#if FFX_HLSL_SM >= 62 |
|||
|
|||
#define FFX_MIN16_SCALAR( TypeName, BaseComponentType ) typedef BaseComponentType##16_t TypeName; |
|||
#define FFX_MIN16_VECTOR( TypeName, BaseComponentType, COL ) typedef vector<BaseComponentType##16_t, COL> TypeName; |
|||
#define FFX_MIN16_MATRIX( TypeName, BaseComponentType, ROW, COL ) typedef matrix<BaseComponentType##16_t, ROW, COL> TypeName; |
|||
|
|||
#define FFX_16BIT_SCALAR( TypeName, BaseComponentType ) typedef BaseComponentType##16_t TypeName; |
|||
#define FFX_16BIT_VECTOR( TypeName, BaseComponentType, COL ) typedef vector<BaseComponentType##16_t, COL> TypeName; |
|||
#define FFX_16BIT_MATRIX( TypeName, BaseComponentType, ROW, COL ) typedef matrix<BaseComponentType##16_t, ROW, COL> TypeName; |
|||
|
|||
#else //FFX_HLSL_SM>=62 |
|||
|
|||
#define FFX_MIN16_SCALAR( TypeName, BaseComponentType ) typedef min16##BaseComponentType TypeName; |
|||
#define FFX_MIN16_VECTOR( TypeName, BaseComponentType, COL ) typedef vector<min16##BaseComponentType, COL> TypeName; |
|||
#define FFX_MIN16_MATRIX( TypeName, BaseComponentType, ROW, COL ) typedef matrix<min16##BaseComponentType, ROW, COL> TypeName; |
|||
|
|||
#define FFX_16BIT_SCALAR( TypeName, BaseComponentType ) FFX_MIN16_SCALAR( TypeName, BaseComponentType ); |
|||
#define FFX_16BIT_VECTOR( TypeName, BaseComponentType, COL ) FFX_MIN16_VECTOR( TypeName, BaseComponentType, COL ); |
|||
#define FFX_16BIT_MATRIX( TypeName, BaseComponentType, ROW, COL ) FFX_MIN16_MATRIX( TypeName, BaseComponentType, ROW, COL ); |
|||
|
|||
#endif //FFX_HLSL_SM>=62 |
|||
|
|||
#else //FFX_HALF |
|||
|
|||
#define FFX_MIN16_SCALAR( TypeName, BaseComponentType ) typedef BaseComponentType TypeName; |
|||
#define FFX_MIN16_VECTOR( TypeName, BaseComponentType, COL ) typedef vector<BaseComponentType, COL> TypeName; |
|||
#define FFX_MIN16_MATRIX( TypeName, BaseComponentType, ROW, COL ) typedef matrix<BaseComponentType, ROW, COL> TypeName; |
|||
|
|||
#define FFX_16BIT_SCALAR( TypeName, BaseComponentType ) typedef BaseComponentType TypeName; |
|||
#define FFX_16BIT_VECTOR( TypeName, BaseComponentType, COL ) typedef vector<BaseComponentType, COL> TypeName; |
|||
#define FFX_16BIT_MATRIX( TypeName, BaseComponentType, ROW, COL ) typedef matrix<BaseComponentType, ROW, COL> TypeName; |
|||
|
|||
#endif //FFX_HALF |
|||
|
|||
#if defined(FFX_GPU) |
|||
// Common typedefs: |
|||
#if defined(FFX_HLSL) |
|||
FFX_MIN16_SCALAR( FFX_MIN16_F , float ); |
|||
FFX_MIN16_VECTOR( FFX_MIN16_F2, float, 2 ); |
|||
FFX_MIN16_VECTOR( FFX_MIN16_F3, float, 3 ); |
|||
FFX_MIN16_VECTOR( FFX_MIN16_F4, float, 4 ); |
|||
|
|||
FFX_MIN16_SCALAR( FFX_MIN16_I, int ); |
|||
FFX_MIN16_VECTOR( FFX_MIN16_I2, int, 2 ); |
|||
FFX_MIN16_VECTOR( FFX_MIN16_I3, int, 3 ); |
|||
FFX_MIN16_VECTOR( FFX_MIN16_I4, int, 4 ); |
|||
|
|||
FFX_MIN16_SCALAR( FFX_MIN16_U, uint ); |
|||
FFX_MIN16_VECTOR( FFX_MIN16_U2, uint, 2 ); |
|||
FFX_MIN16_VECTOR( FFX_MIN16_U3, uint, 3 ); |
|||
FFX_MIN16_VECTOR( FFX_MIN16_U4, uint, 4 ); |
|||
|
|||
FFX_16BIT_SCALAR( FFX_F16_t , float ); |
|||
FFX_16BIT_VECTOR( FFX_F16_t2, float, 2 ); |
|||
FFX_16BIT_VECTOR( FFX_F16_t3, float, 3 ); |
|||
FFX_16BIT_VECTOR( FFX_F16_t4, float, 4 ); |
|||
|
|||
FFX_16BIT_SCALAR( FFX_I16_t, int ); |
|||
FFX_16BIT_VECTOR( FFX_I16_t2, int, 2 ); |
|||
FFX_16BIT_VECTOR( FFX_I16_t3, int, 3 ); |
|||
FFX_16BIT_VECTOR( FFX_I16_t4, int, 4 ); |
|||
|
|||
FFX_16BIT_SCALAR( FFX_U16_t, uint ); |
|||
FFX_16BIT_VECTOR( FFX_U16_t2, uint, 2 ); |
|||
FFX_16BIT_VECTOR( FFX_U16_t3, uint, 3 ); |
|||
FFX_16BIT_VECTOR( FFX_U16_t4, uint, 4 ); |
|||
|
|||
#define TYPEDEF_MIN16_TYPES(Prefix) \ |
|||
typedef FFX_MIN16_F Prefix##_F; \ |
|||
typedef FFX_MIN16_F2 Prefix##_F2; \ |
|||
typedef FFX_MIN16_F3 Prefix##_F3; \ |
|||
typedef FFX_MIN16_F4 Prefix##_F4; \ |
|||
typedef FFX_MIN16_I Prefix##_I; \ |
|||
typedef FFX_MIN16_I2 Prefix##_I2; \ |
|||
typedef FFX_MIN16_I3 Prefix##_I3; \ |
|||
typedef FFX_MIN16_I4 Prefix##_I4; \ |
|||
typedef FFX_MIN16_U Prefix##_U; \ |
|||
typedef FFX_MIN16_U2 Prefix##_U2; \ |
|||
typedef FFX_MIN16_U3 Prefix##_U3; \ |
|||
typedef FFX_MIN16_U4 Prefix##_U4; |
|||
|
|||
#define TYPEDEF_16BIT_TYPES(Prefix) \ |
|||
typedef FFX_16BIT_F Prefix##_F; \ |
|||
typedef FFX_16BIT_F2 Prefix##_F2; \ |
|||
typedef FFX_16BIT_F3 Prefix##_F3; \ |
|||
typedef FFX_16BIT_F4 Prefix##_F4; \ |
|||
typedef FFX_16BIT_I Prefix##_I; \ |
|||
typedef FFX_16BIT_I2 Prefix##_I2; \ |
|||
typedef FFX_16BIT_I3 Prefix##_I3; \ |
|||
typedef FFX_16BIT_I4 Prefix##_I4; \ |
|||
typedef FFX_16BIT_U Prefix##_U; \ |
|||
typedef FFX_16BIT_U2 Prefix##_U2; \ |
|||
typedef FFX_16BIT_U3 Prefix##_U3; \ |
|||
typedef FFX_16BIT_U4 Prefix##_U4; |
|||
|
|||
#define TYPEDEF_FULL_PRECISION_TYPES(Prefix) \ |
|||
typedef FfxFloat32 Prefix##_F; \ |
|||
typedef FfxFloat32x2 Prefix##_F2; \ |
|||
typedef FfxFloat32x3 Prefix##_F3; \ |
|||
typedef FfxFloat32x4 Prefix##_F4; \ |
|||
typedef FfxInt32 Prefix##_I; \ |
|||
typedef FfxInt32x2 Prefix##_I2; \ |
|||
typedef FfxInt32x3 Prefix##_I3; \ |
|||
typedef FfxInt32x4 Prefix##_I4; \ |
|||
typedef FfxUInt32 Prefix##_U; \ |
|||
typedef FfxUInt32x2 Prefix##_U2; \ |
|||
typedef FfxUInt32x3 Prefix##_U3; \ |
|||
typedef FfxUInt32x4 Prefix##_U4; |
|||
#endif // #if defined(FFX_HLSL) |
|||
|
|||
#if defined(FFX_GLSL) |
|||
|
|||
#if FFX_HALF |
|||
|
|||
#define FFX_MIN16_F float16_t |
|||
#define FFX_MIN16_F2 f16vec2 |
|||
#define FFX_MIN16_F3 f16vec3 |
|||
#define FFX_MIN16_F4 f16vec4 |
|||
|
|||
#define FFX_MIN16_I int16_t |
|||
#define FFX_MIN16_I2 i16vec2 |
|||
#define FFX_MIN16_I3 i16vec3 |
|||
#define FFX_MIN16_I4 i16vec4 |
|||
|
|||
#define FFX_MIN16_U uint16_t |
|||
#define FFX_MIN16_U2 u16vec2 |
|||
#define FFX_MIN16_U3 u16vec3 |
|||
#define FFX_MIN16_U4 u16vec4 |
|||
|
|||
#define FFX_16BIT_F float16_t |
|||
#define FFX_16BIT_F2 f16vec2 |
|||
#define FFX_16BIT_F3 f16vec3 |
|||
#define FFX_16BIT_F4 f16vec4 |
|||
|
|||
#define FFX_16BIT_I int16_t |
|||
#define FFX_16BIT_I2 i16vec2 |
|||
#define FFX_16BIT_I3 i16vec3 |
|||
#define FFX_16BIT_I4 i16vec4 |
|||
|
|||
#define FFX_16BIT_U uint16_t |
|||
#define FFX_16BIT_U2 u16vec2 |
|||
#define FFX_16BIT_U3 u16vec3 |
|||
#define FFX_16BIT_U4 u16vec4 |
|||
|
|||
#else // FFX_HALF |
|||
|
|||
#define FFX_MIN16_F float |
|||
#define FFX_MIN16_F2 vec2 |
|||
#define FFX_MIN16_F3 vec3 |
|||
#define FFX_MIN16_F4 vec4 |
|||
|
|||
#define FFX_MIN16_I int |
|||
#define FFX_MIN16_I2 ivec2 |
|||
#define FFX_MIN16_I3 ivec3 |
|||
#define FFX_MIN16_I4 ivec4 |
|||
|
|||
#define FFX_MIN16_U uint |
|||
#define FFX_MIN16_U2 uvec2 |
|||
#define FFX_MIN16_U3 uvec3 |
|||
#define FFX_MIN16_U4 uvec4 |
|||
|
|||
#define FFX_16BIT_F float |
|||
#define FFX_16BIT_F2 vec2 |
|||
#define FFX_16BIT_F3 vec3 |
|||
#define FFX_16BIT_F4 vec4 |
|||
|
|||
#define FFX_16BIT_I int |
|||
#define FFX_16BIT_I2 ivec2 |
|||
#define FFX_16BIT_I3 ivec3 |
|||
#define FFX_16BIT_I4 ivec4 |
|||
|
|||
#define FFX_16BIT_U uint |
|||
#define FFX_16BIT_U2 uvec2 |
|||
#define FFX_16BIT_U3 uvec3 |
|||
#define FFX_16BIT_U4 uvec4 |
|||
|
|||
#endif // FFX_HALF |
|||
|
|||
#endif // #if defined(FFX_GLSL) |
|||
|
|||
#endif // #if defined(FFX_GPU) |
|||
#endif // #ifndef FFX_COMMON_TYPES_H |
|||
@ -0,0 +1,27 @@ |
|||
fileFormatVersion: 2 |
|||
guid: d35d3e7c8170d6e4fbbae530b3609c03 |
|||
PluginImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
iconMap: {} |
|||
executionOrder: {} |
|||
defineConstraints: [] |
|||
isPreloaded: 0 |
|||
isOverridable: 0 |
|||
isExplicitlyReferenced: 0 |
|||
validateReferences: 1 |
|||
platformData: |
|||
- first: |
|||
Any: |
|||
second: |
|||
enabled: 1 |
|||
settings: {} |
|||
- first: |
|||
Editor: Editor |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
DefaultValueInitialized: true |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,80 @@ |
|||
// This file is part of the FidelityFX SDK. |
|||
// |
|||
// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved. |
|||
// |
|||
// 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. |
|||
|
|||
|
|||
/// @defgroup FfxGPU GPU |
|||
/// The FidelityFX SDK GPU References |
|||
/// |
|||
/// @ingroup ffxSDK |
|||
|
|||
/// @defgroup FfxHLSL HLSL References |
|||
/// FidelityFX SDK HLSL GPU References |
|||
/// |
|||
/// @ingroup FfxGPU |
|||
|
|||
/// @defgroup FfxGLSL GLSL References |
|||
/// FidelityFX SDK GLSL GPU References |
|||
/// |
|||
/// @ingroup FfxGPU |
|||
|
|||
/// @defgroup FfxGPUEffects FidelityFX GPU References |
|||
/// FidelityFX Effect GPU Reference Documentation |
|||
/// |
|||
/// @ingroup FfxGPU |
|||
|
|||
/// @defgroup GPUCore GPU Core |
|||
/// GPU defines and functions |
|||
/// |
|||
/// @ingroup FfxGPU |
|||
|
|||
#if !defined(FFX_CORE_H) |
|||
#define FFX_CORE_H |
|||
|
|||
#ifdef __hlsl_dx_compiler |
|||
#pragma dxc diagnostic push |
|||
#pragma dxc diagnostic ignored "-Wambig-lit-shift" |
|||
#endif //__hlsl_dx_compiler |
|||
|
|||
#include "ffx_common_types.h" |
|||
|
|||
#if defined(FFX_CPU) |
|||
#include "ffx_core_cpu.h" |
|||
#endif // #if defined(FFX_CPU) |
|||
|
|||
#if defined(FFX_GLSL) && defined(FFX_GPU) |
|||
#include "ffx_core_glsl.h" |
|||
#endif // #if defined(FFX_GLSL) && defined(FFX_GPU) |
|||
|
|||
#if defined(FFX_HLSL) && defined(FFX_GPU) |
|||
#include "ffx_core_hlsl.h" |
|||
#endif // #if defined(FFX_HLSL) && defined(FFX_GPU) |
|||
|
|||
#if defined(FFX_GPU) |
|||
#include "ffx_core_gpu_common.h" |
|||
#include "ffx_core_gpu_common_half.h" |
|||
#include "ffx_core_portability.h" |
|||
#endif // #if defined(FFX_GPU) |
|||
|
|||
#ifdef __hlsl_dx_compiler |
|||
#pragma dxc diagnostic pop |
|||
#endif //__hlsl_dx_compiler |
|||
|
|||
#endif // #if !defined(FFX_CORE_H) |
|||
@ -0,0 +1,27 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 24c2d56ea3ea55041971558d150af28f |
|||
PluginImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
iconMap: {} |
|||
executionOrder: {} |
|||
defineConstraints: [] |
|||
isPreloaded: 0 |
|||
isOverridable: 0 |
|||
isExplicitlyReferenced: 0 |
|||
validateReferences: 1 |
|||
platformData: |
|||
- first: |
|||
Any: |
|||
second: |
|||
enabled: 1 |
|||
settings: {} |
|||
- first: |
|||
Editor: Editor |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
DefaultValueInitialized: true |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,338 @@ |
|||
// This file is part of the FidelityFX SDK. |
|||
// |
|||
// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved. |
|||
// |
|||
// 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. |
|||
|
|||
|
|||
/// A define for a true value in a boolean expression. |
|||
/// |
|||
/// @ingroup CPUTypes |
|||
#define FFX_TRUE (1) |
|||
|
|||
/// A define for a false value in a boolean expression. |
|||
/// |
|||
/// @ingroup CPUTypes |
|||
#define FFX_FALSE (0) |
|||
|
|||
#if !defined(FFX_STATIC) |
|||
/// A define to abstract declaration of static variables and functions. |
|||
/// |
|||
/// @ingroup CPUTypes |
|||
#define FFX_STATIC static |
|||
#endif // #if !defined(FFX_STATIC) |
|||
|
|||
/// @defgroup CPUCore CPU Core |
|||
/// Core CPU-side defines and functions |
|||
/// |
|||
/// @ingroup ffxHost |
|||
|
|||
#ifdef __clang__ |
|||
#pragma clang diagnostic ignored "-Wunused-variable" |
|||
#endif |
|||
|
|||
/// Interpret the bit layout of an IEEE-754 floating point value as an unsigned integer. |
|||
/// |
|||
/// @param [in] x A 32bit floating value. |
|||
/// |
|||
/// @returns |
|||
/// An unsigned 32bit integer value containing the bit pattern of <c><i>x</i></c>. |
|||
/// |
|||
/// @ingroup CPUCore |
|||
FFX_STATIC FfxUInt32 ffxAsUInt32(FfxFloat32 x) |
|||
{ |
|||
union |
|||
{ |
|||
FfxFloat32 f; |
|||
FfxUInt32 u; |
|||
} bits; |
|||
|
|||
bits.f = x; |
|||
return bits.u; |
|||
} |
|||
|
|||
FFX_STATIC FfxFloat32 ffxDot2(FfxFloat32x2 a, FfxFloat32x2 b) |
|||
{ |
|||
return a[0] * b[0] + a[1] * b[1]; |
|||
} |
|||
|
|||
FFX_STATIC FfxFloat32 ffxDot3(FfxFloat32x3 a, FfxFloat32x3 b) |
|||
{ |
|||
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; |
|||
} |
|||
|
|||
FFX_STATIC FfxFloat32 ffxDot4(FfxFloat32x4 a, FfxFloat32x4 b) |
|||
{ |
|||
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3]; |
|||
} |
|||
|
|||
/// Compute the linear interopation between two values. |
|||
/// |
|||
/// Implemented by calling the GLSL <c><i>mix</i></c> instrinsic function. Implements the |
|||
/// following math: |
|||
/// |
|||
/// (1 - t) * x + t * y |
|||
/// |
|||
/// @param [in] x The first value to lerp between. |
|||
/// @param [in] y The second value to lerp between. |
|||
/// @param [in] t The value to determine how much of <c><i>x</i></c> and how much of <c><i>y</i></c>. |
|||
/// |
|||
/// @returns |
|||
/// A linearly interpolated value between <c><i>x</i></c> and <c><i>y</i></c> according to <c><i>t</i></c>. |
|||
/// |
|||
/// @ingroup CPUCore |
|||
FFX_STATIC FfxFloat32 ffxLerp(FfxFloat32 x, FfxFloat32 y, FfxFloat32 t) |
|||
{ |
|||
return y * t + (-x * t + x); |
|||
} |
|||
|
|||
/// Compute the reciprocal of a value. |
|||
/// |
|||
/// @param [in] x The value to compute the reciprocal for. |
|||
/// |
|||
/// @returns |
|||
/// The reciprocal value of <c><i>x</i></c>. |
|||
/// |
|||
/// @ingroup CPUCore |
|||
FFX_STATIC FfxFloat32 ffxReciprocal(FfxFloat32 x) |
|||
{ |
|||
return 1.0f / x; |
|||
} |
|||
|
|||
/// Compute the square root of a value. |
|||
/// |
|||
/// @param [in] x The first value to compute the min of. |
|||
/// |
|||
/// @returns |
|||
/// The the square root of <c><i>x</i></c>. |
|||
/// |
|||
/// @ingroup CPUCore |
|||
FFX_STATIC FfxFloat32 ffxSqrt(FfxFloat32 x) |
|||
{ |
|||
return sqrt(x); |
|||
} |
|||
|
|||
FFX_STATIC FfxUInt32 AShrSU1(FfxUInt32 a, FfxUInt32 b) |
|||
{ |
|||
return FfxUInt32(FfxInt32(a) >> FfxInt32(b)); |
|||
} |
|||
|
|||
/// Compute the factional part of a decimal value. |
|||
/// |
|||
/// This function calculates <c><i>x - floor(x)</i></c>. |
|||
/// |
|||
/// @param [in] x The value to compute the fractional part from. |
|||
/// |
|||
/// @returns |
|||
/// The fractional part of <c><i>x</i></c>. |
|||
/// |
|||
/// @ingroup CPUCore |
|||
FFX_STATIC FfxFloat32 ffxFract(FfxFloat32 x) |
|||
{ |
|||
return x - floor(x); |
|||
} |
|||
|
|||
/// Compute the reciprocal square root of a value. |
|||
/// |
|||
/// @param [in] x The value to compute the reciprocal for. |
|||
/// |
|||
/// @returns |
|||
/// The reciprocal square root value of <c><i>x</i></c>. |
|||
/// |
|||
/// @ingroup CPUCore |
|||
FFX_STATIC FfxFloat32 rsqrt(FfxFloat32 x) |
|||
{ |
|||
return ffxReciprocal(ffxSqrt(x)); |
|||
} |
|||
|
|||
FFX_STATIC FfxFloat32 ffxMin(FfxFloat32 x, FfxFloat32 y) |
|||
{ |
|||
return x < y ? x : y; |
|||
} |
|||
|
|||
FFX_STATIC FfxUInt32 ffxMin(FfxUInt32 x, FfxUInt32 y) |
|||
{ |
|||
return x < y ? x : y; |
|||
} |
|||
|
|||
FFX_STATIC FfxFloat32 ffxMax(FfxFloat32 x, FfxFloat32 y) |
|||
{ |
|||
return x > y ? x : y; |
|||
} |
|||
|
|||
FFX_STATIC FfxUInt32 ffxMax(FfxUInt32 x, FfxUInt32 y) |
|||
{ |
|||
return x > y ? x : y; |
|||
} |
|||
|
|||
/// Clamp a value to a [0..1] range. |
|||
/// |
|||
/// @param [in] x The value to clamp to [0..1] range. |
|||
/// |
|||
/// @returns |
|||
/// The clamped version of <c><i>x</i></c>. |
|||
/// |
|||
/// @ingroup CPUCore |
|||
FFX_STATIC FfxFloat32 ffxSaturate(FfxFloat32 x) |
|||
{ |
|||
return ffxMin(1.0f, ffxMax(0.0f, x)); |
|||
} |
|||
|
|||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|||
|
|||
FFX_STATIC void opAAddOneF3(FfxFloat32x3 d, FfxFloat32x3 a, FfxFloat32 b) |
|||
{ |
|||
d[0] = a[0] + b; |
|||
d[1] = a[1] + b; |
|||
d[2] = a[2] + b; |
|||
return; |
|||
} |
|||
|
|||
FFX_STATIC void opACpyF3(FfxFloat32x3 d, FfxFloat32x3 a) |
|||
{ |
|||
d[0] = a[0]; |
|||
d[1] = a[1]; |
|||
d[2] = a[2]; |
|||
return; |
|||
} |
|||
|
|||
FFX_STATIC void opAMulF3(FfxFloat32x3 d, FfxFloat32x3 a, FfxFloat32x3 b) |
|||
{ |
|||
d[0] = a[0] * b[0]; |
|||
d[1] = a[1] * b[1]; |
|||
d[2] = a[2] * b[2]; |
|||
return; |
|||
} |
|||
|
|||
FFX_STATIC void opAMulOneF3(FfxFloat32x3 d, FfxFloat32x3 a, FfxFloat32 b) |
|||
{ |
|||
d[0] = a[0] * b; |
|||
d[1] = a[1] * b; |
|||
d[2] = a[2] * b; |
|||
return; |
|||
} |
|||
|
|||
FFX_STATIC void opARcpF3(FfxFloat32x3 d, FfxFloat32x3 a) |
|||
{ |
|||
d[0] = ffxReciprocal(a[0]); |
|||
d[1] = ffxReciprocal(a[1]); |
|||
d[2] = ffxReciprocal(a[2]); |
|||
return; |
|||
} |
|||
|
|||
/// Convert FfxFloat32 to half (in lower 16-bits of output). |
|||
/// |
|||
/// This function implements the same fast technique that is documented here: ftp://ftp.fox-toolkit.org/pub/fasthalffloatconversion.pdf |
|||
/// |
|||
/// The function supports denormals. |
|||
/// |
|||
/// Some conversion rules are to make computations possibly "safer" on the GPU, |
|||
/// -INF & -NaN -> -65504 |
|||
/// +INF & +NaN -> +65504 |
|||
/// |
|||
/// @param [in] f The 32bit floating point value to convert. |
|||
/// |
|||
/// @returns |
|||
/// The closest 16bit floating point value to <c><i>f</i></c>. |
|||
/// |
|||
/// @ingroup CPUCore |
|||
FFX_STATIC FfxUInt32 f32tof16(FfxFloat32 f) |
|||
{ |
|||
static FfxUInt16 base[512] = { |
|||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, |
|||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, |
|||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, |
|||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, |
|||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, |
|||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, |
|||
0x0800, 0x0c00, 0x1000, 0x1400, 0x1800, 0x1c00, 0x2000, 0x2400, 0x2800, 0x2c00, 0x3000, 0x3400, 0x3800, 0x3c00, 0x4000, 0x4400, 0x4800, 0x4c00, 0x5000, |
|||
0x5400, 0x5800, 0x5c00, 0x6000, 0x6400, 0x6800, 0x6c00, 0x7000, 0x7400, 0x7800, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, |
|||
0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, |
|||
0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, |
|||
0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, |
|||
0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, |
|||
0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, |
|||
0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, |
|||
0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, |
|||
0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, |
|||
0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, |
|||
0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, |
|||
0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8001, 0x8002, |
|||
0x8004, 0x8008, 0x8010, 0x8020, 0x8040, 0x8080, 0x8100, 0x8200, 0x8400, 0x8800, 0x8c00, 0x9000, 0x9400, 0x9800, 0x9c00, 0xa000, 0xa400, 0xa800, 0xac00, |
|||
0xb000, 0xb400, 0xb800, 0xbc00, 0xc000, 0xc400, 0xc800, 0xcc00, 0xd000, 0xd400, 0xd800, 0xdc00, 0xe000, 0xe400, 0xe800, 0xec00, 0xf000, 0xf400, 0xf800, |
|||
0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, |
|||
0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, |
|||
0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, |
|||
0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, |
|||
0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, |
|||
0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff |
|||
}; |
|||
|
|||
static FfxUInt8 shift[512] = { |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, |
|||
0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, |
|||
0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 |
|||
}; |
|||
|
|||
union |
|||
{ |
|||
FfxFloat32 f; |
|||
FfxUInt32 u; |
|||
} bits; |
|||
|
|||
bits.f = f; |
|||
FfxUInt32 u = bits.u; |
|||
FfxUInt32 i = u >> 23; |
|||
return (FfxUInt32)(base[i]) + ((u & 0x7fffff) >> shift[i]); |
|||
} |
|||
|
|||
/// Pack 2x32-bit floating point values in a single 32bit value. |
|||
/// |
|||
/// This function first converts each component of <c><i>value</i></c> into their nearest 16-bit floating |
|||
/// point representation, and then stores the X and Y components in the lower and upper 16 bits of the |
|||
/// 32bit unsigned integer respectively. |
|||
/// |
|||
/// @param [in] x A 2-dimensional floating point value to convert and pack. |
|||
/// |
|||
/// @returns |
|||
/// A packed 32bit value containing 2 16bit floating point values. |
|||
/// |
|||
/// @ingroup CPUCore |
|||
FFX_STATIC FfxUInt32 packHalf2x16(FfxFloat32x2 x) |
|||
{ |
|||
return f32tof16(x[0]) + (f32tof16(x[1]) << 16); |
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
fileFormatVersion: 2 |
|||
guid: b4fa972f29be29f458a9328974e75422 |
|||
PluginImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
iconMap: {} |
|||
executionOrder: {} |
|||
defineConstraints: [] |
|||
isPreloaded: 0 |
|||
isOverridable: 0 |
|||
isExplicitlyReferenced: 0 |
|||
validateReferences: 1 |
|||
platformData: |
|||
- first: |
|||
Any: |
|||
second: |
|||
enabled: 1 |
|||
settings: {} |
|||
- first: |
|||
Editor: Editor |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
DefaultValueInitialized: true |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
2784
com.unity.render-pipelines.high-definition/Runtime/FidelityFX/shaders/common/ffx_core_gpu_common.h
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,27 @@ |
|||
fileFormatVersion: 2 |
|||
guid: d8df66f0babbe60479b6c8059ac30456 |
|||
PluginImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
iconMap: {} |
|||
executionOrder: {} |
|||
defineConstraints: [] |
|||
isPreloaded: 0 |
|||
isOverridable: 0 |
|||
isExplicitlyReferenced: 0 |
|||
validateReferences: 1 |
|||
platformData: |
|||
- first: |
|||
Any: |
|||
second: |
|||
enabled: 1 |
|||
settings: {} |
|||
- first: |
|||
Editor: Editor |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
DefaultValueInitialized: true |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
2979
com.unity.render-pipelines.high-definition/Runtime/FidelityFX/shaders/common/ffx_core_gpu_common_half.h
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,27 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 4ab08f75b4851484bada56a1e9e7d2be |
|||
PluginImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
iconMap: {} |
|||
executionOrder: {} |
|||
defineConstraints: [] |
|||
isPreloaded: 0 |
|||
isOverridable: 0 |
|||
isExplicitlyReferenced: 0 |
|||
validateReferences: 1 |
|||
platformData: |
|||
- first: |
|||
Any: |
|||
second: |
|||
enabled: 1 |
|||
settings: {} |
|||
- first: |
|||
Editor: Editor |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
DefaultValueInitialized: true |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
1651
com.unity.render-pipelines.high-definition/Runtime/FidelityFX/shaders/common/ffx_core_hlsl.h
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,27 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 28ad36ea51c530a428c047d4f6532d60 |
|||
PluginImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
iconMap: {} |
|||
executionOrder: {} |
|||
defineConstraints: [] |
|||
isPreloaded: 0 |
|||
isOverridable: 0 |
|||
isExplicitlyReferenced: 0 |
|||
validateReferences: 1 |
|||
platformData: |
|||
- first: |
|||
Any: |
|||
second: |
|||
enabled: 1 |
|||
settings: {} |
|||
- first: |
|||
Editor: Editor |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
DefaultValueInitialized: true |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,51 @@ |
|||
// This file is part of the FidelityFX SDK. |
|||
// |
|||
// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved. |
|||
// |
|||
// 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. |
|||
|
|||
|
|||
FfxFloat32x3 opAAddOneF3(FfxFloat32x3 d, FfxFloat32x3 a, FfxFloat32 b) |
|||
{ |
|||
d = a + ffxBroadcast3(b); |
|||
return d; |
|||
} |
|||
|
|||
FfxFloat32x3 opACpyF3(FfxFloat32x3 d, FfxFloat32x3 a) |
|||
{ |
|||
d = a; |
|||
return d; |
|||
} |
|||
|
|||
FfxFloat32x3 opAMulF3(FfxFloat32x3 d, FfxFloat32x3 a, FfxFloat32x3 b) |
|||
{ |
|||
d = a * b; |
|||
return d; |
|||
} |
|||
|
|||
FfxFloat32x3 opAMulOneF3(FfxFloat32x3 d, FfxFloat32x3 a, FfxFloat32 b) |
|||
{ |
|||
d = a * ffxBroadcast3(b); |
|||
return d; |
|||
} |
|||
|
|||
FfxFloat32x3 opARcpF3(FfxFloat32x3 d, FfxFloat32x3 a) |
|||
{ |
|||
d = rcp(a); |
|||
return d; |
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 9a5c372d4f6f2f243ade445c5e8a06e5 |
|||
PluginImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
iconMap: {} |
|||
executionOrder: {} |
|||
defineConstraints: [] |
|||
isPreloaded: 0 |
|||
isOverridable: 0 |
|||
isExplicitlyReferenced: 0 |
|||
validateReferences: 1 |
|||
platformData: |
|||
- first: |
|||
Any: |
|||
second: |
|||
enabled: 1 |
|||
settings: {} |
|||
- first: |
|||
Editor: Editor |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
DefaultValueInitialized: true |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,66 @@ |
|||
// This file is part of the FidelityFX SDK. |
|||
// |
|||
// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved. |
|||
// |
|||
// 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. |
|||
|
|||
|
|||
#define CACAO_BIND_SRV_SSAO_BUFFER_PING 0 |
|||
#define CACAO_BIND_UAV_OUTPUT 0 |
|||
|
|||
#define CACAO_BIND_CB_CACAO 0 |
|||
|
|||
#include "cacao/ffx_cacao_callbacks_hlsl.h" |
|||
#include "cacao/ffx_cacao_apply.h" |
|||
|
|||
#ifndef FFX_CACAO_THREAD_GROUP_WIDTH |
|||
#define FFX_CACAO_THREAD_GROUP_WIDTH 8 |
|||
#endif // #ifndef FFX_CACAO_THREAD_GROUP_WIDTH |
|||
#ifndef FFX_CACAO_THREAD_GROUP_HEIGHT |
|||
#define FFX_CACAO_THREAD_GROUP_HEIGHT 8 |
|||
#endif // FFX_CACAO_THREAD_GROUP_HEIGHT |
|||
#ifndef FFX_CACAO_THREAD_GROUP_DEPTH |
|||
#define FFX_CACAO_THREAD_GROUP_DEPTH 1 |
|||
#endif // #ifndef FFX_CACAO_THREAD_GROUP_DEPTH |
|||
#ifndef FFX_CACAO_NUM_THREADS |
|||
#define FFX_CACAO_NUM_THREADS [numthreads(FFX_CACAO_THREAD_GROUP_WIDTH, FFX_CACAO_THREAD_GROUP_HEIGHT, FFX_CACAO_THREAD_GROUP_DEPTH)] |
|||
#endif // #ifndef FFX_CACAO_NUM_THREADS |
|||
|
|||
FFX_PREFER_WAVE64 |
|||
FFX_CACAO_NUM_THREADS |
|||
FFX_CACAO_EMBED_ROOTSIG_CONTENT |
|||
void CS_Smart(uint2 coord : SV_DispatchThreadID) |
|||
{ |
|||
FFX_CACAO_Apply(coord); |
|||
} |
|||
|
|||
FFX_PREFER_WAVE64 |
|||
FFX_CACAO_NUM_THREADS |
|||
FFX_CACAO_EMBED_ROOTSIG_CONTENT |
|||
void CS_NonSmart(uint2 coord : SV_DispatchThreadID) |
|||
{ |
|||
FFX_CACAO_NonSmartApply(coord); |
|||
} |
|||
|
|||
FFX_PREFER_WAVE64 |
|||
FFX_CACAO_NUM_THREADS |
|||
FFX_CACAO_EMBED_ROOTSIG_CONTENT |
|||
void CS_NonSmartHalf(uint2 coord : SV_DispatchThreadID) |
|||
{ |
|||
FFX_CACAO_NonSmartHalfApply(coord); |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 5528421cb21137640be0b56ccc271a0f |
|||
ShaderIncludeImporter: |
|||
externalObjects: {} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,106 @@ |
|||
// This file is part of the FidelityFX SDK. |
|||
// |
|||
// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved. |
|||
// |
|||
// 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. |
|||
|
|||
|
|||
#define CACAO_BIND_SRV_SSAO_BUFFER_PING 0 |
|||
#define CACAO_BIND_UAV_SSAO_BUFFER_PONG 0 |
|||
|
|||
#define CACAO_BIND_CB_CACAO 0 |
|||
|
|||
#include "cacao/ffx_cacao_callbacks_hlsl.h" |
|||
#include "cacao/ffx_cacao_edge_sensitive_blur.h" |
|||
|
|||
#ifndef FFX_CACAO_THREAD_GROUP_WIDTH |
|||
#define FFX_CACAO_THREAD_GROUP_WIDTH 16 |
|||
#endif // #ifndef FFX_CACAO_THREAD_GROUP_WIDTH |
|||
#ifndef FFX_CACAO_THREAD_GROUP_HEIGHT |
|||
#define FFX_CACAO_THREAD_GROUP_HEIGHT 16 |
|||
#endif // FFX_CACAO_THREAD_GROUP_HEIGHT |
|||
#ifndef FFX_CACAO_THREAD_GROUP_DEPTH |
|||
#define FFX_CACAO_THREAD_GROUP_DEPTH 1 |
|||
#endif // #ifndef FFX_CACAO_THREAD_GROUP_DEPTH |
|||
#ifndef FFX_CACAO_NUM_THREADS |
|||
#define FFX_CACAO_NUM_THREADS [numthreads(FFX_CACAO_THREAD_GROUP_WIDTH, FFX_CACAO_THREAD_GROUP_HEIGHT, FFX_CACAO_THREAD_GROUP_DEPTH)] |
|||
#endif // #ifndef FFX_CACAO_NUM_THREADS |
|||
|
|||
FFX_PREFER_WAVE64 |
|||
FFX_CACAO_NUM_THREADS |
|||
FFX_CACAO_EMBED_ROOTSIG_CONTENT |
|||
void CS_1Pass(uint2 tid : SV_GroupThreadID, uint3 gid : SV_GroupID) |
|||
{ |
|||
FFX_CACAO_EdgeSensitiveBlur1(tid, gid); |
|||
} |
|||
|
|||
FFX_PREFER_WAVE64 |
|||
FFX_CACAO_NUM_THREADS |
|||
FFX_CACAO_EMBED_ROOTSIG_CONTENT |
|||
void CS_2Pass(uint2 tid : SV_GroupThreadID, uint3 gid : SV_GroupID) |
|||
{ |
|||
FFX_CACAO_EdgeSensitiveBlur2(tid, gid); |
|||
} |
|||
|
|||
FFX_PREFER_WAVE64 |
|||
FFX_CACAO_NUM_THREADS |
|||
FFX_CACAO_EMBED_ROOTSIG_CONTENT |
|||
void CS_3Pass(uint2 tid : SV_GroupThreadID, uint3 gid : SV_GroupID) |
|||
{ |
|||
FFX_CACAO_EdgeSensitiveBlur3(tid, gid); |
|||
} |
|||
|
|||
FFX_PREFER_WAVE64 |
|||
FFX_CACAO_NUM_THREADS |
|||
FFX_CACAO_EMBED_ROOTSIG_CONTENT |
|||
void CS_4Pass(uint2 tid : SV_GroupThreadID, uint3 gid : SV_GroupID) |
|||
{ |
|||
FFX_CACAO_EdgeSensitiveBlur4(tid, gid); |
|||
} |
|||
|
|||
FFX_PREFER_WAVE64 |
|||
FFX_CACAO_NUM_THREADS |
|||
FFX_CACAO_EMBED_ROOTSIG_CONTENT |
|||
void CS_5Pass(uint2 tid : SV_GroupThreadID, uint3 gid : SV_GroupID) |
|||
{ |
|||
FFX_CACAO_EdgeSensitiveBlur5(tid, gid); |
|||
} |
|||
|
|||
FFX_PREFER_WAVE64 |
|||
FFX_CACAO_NUM_THREADS |
|||
FFX_CACAO_EMBED_ROOTSIG_CONTENT |
|||
void CS_6Pass(uint2 tid : SV_GroupThreadID, uint3 gid : SV_GroupID) |
|||
{ |
|||
FFX_CACAO_EdgeSensitiveBlur6(tid, gid); |
|||
} |
|||
|
|||
FFX_PREFER_WAVE64 |
|||
FFX_CACAO_NUM_THREADS |
|||
FFX_CACAO_EMBED_ROOTSIG_CONTENT |
|||
void CS_7Pass(uint2 tid : SV_GroupThreadID, uint3 gid : SV_GroupID) |
|||
{ |
|||
FFX_CACAO_EdgeSensitiveBlur7(tid, gid); |
|||
} |
|||
|
|||
FFX_PREFER_WAVE64 |
|||
FFX_CACAO_NUM_THREADS |
|||
FFX_CACAO_EMBED_ROOTSIG_CONTENT |
|||
void CS_8Pass(uint2 tid : SV_GroupThreadID, uint3 gid : SV_GroupID) |
|||
{ |
|||
FFX_CACAO_EdgeSensitiveBlur8(tid, gid); |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 3daae962062d57a428cc8195e335e175 |
|||
ShaderIncludeImporter: |
|||
externalObjects: {} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,70 @@ |
|||
// This file is part of the FidelityFX SDK. |
|||
// |
|||
// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved. |
|||
// |
|||
// 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. |
|||
|
|||
|
|||
#define CACAO_BIND_SRV_SSAO_BUFFER_PONG 0 |
|||
#define CACAO_BIND_SRV_IMPORTANCE_MAP 1 |
|||
#define CACAO_BIND_SRV_IMPORTANCE_MAP_PONG 2 |
|||
#define CACAO_BIND_UAV_LOAD_COUNTER 0 |
|||
#define CACAO_BIND_UAV_IMPORTANCE_MAP 1 |
|||
#define CACAO_BIND_UAV_IMPORTANCE_MAP_PONG 2 |
|||
|
|||
#define CACAO_BIND_CB_CACAO 0 |
|||
|
|||
#include "cacao/ffx_cacao_callbacks_hlsl.h" |
|||
#include "cacao/ffx_cacao_importance_map.h" |
|||
|
|||
#ifndef FFX_CACAO_THREAD_GROUP_WIDTH |
|||
#define FFX_CACAO_THREAD_GROUP_WIDTH 8 |
|||
#endif // #ifndef FFX_CACAO_THREAD_GROUP_WIDTH |
|||
#ifndef FFX_CACAO_THREAD_GROUP_HEIGHT |
|||
#define FFX_CACAO_THREAD_GROUP_HEIGHT 8 |
|||
#endif // FFX_CACAO_THREAD_GROUP_HEIGHT |
|||
#ifndef FFX_CACAO_THREAD_GROUP_DEPTH |
|||
#define FFX_CACAO_THREAD_GROUP_DEPTH 1 |
|||
#endif // #ifndef FFX_CACAO_THREAD_GROUP_DEPTH |
|||
#ifndef FFX_CACAO_NUM_THREADS |
|||
#define FFX_CACAO_NUM_THREADS [numthreads(FFX_CACAO_THREAD_GROUP_WIDTH, FFX_CACAO_THREAD_GROUP_HEIGHT, FFX_CACAO_THREAD_GROUP_DEPTH)] |
|||
#endif // #ifndef FFX_CACAO_NUM_THREADS |
|||
|
|||
FFX_PREFER_WAVE64 |
|||
FFX_CACAO_NUM_THREADS |
|||
FFX_CACAO_EMBED_ROOTSIG_CONTENT |
|||
void CS_Generate(uint2 tid : SV_DispatchThreadID) |
|||
{ |
|||
FFX_CACAO_GenerateImportanceMap(tid); |
|||
} |
|||
|
|||
FFX_PREFER_WAVE64 |
|||
FFX_CACAO_NUM_THREADS |
|||
FFX_CACAO_EMBED_ROOTSIG_CONTENT |
|||
void CS_PostprocessA(uint2 tid : SV_DispatchThreadID) |
|||
{ |
|||
FFX_CACAO_PostprocessImportanceMapA(tid); |
|||
} |
|||
|
|||
FFX_PREFER_WAVE64 |
|||
FFX_CACAO_NUM_THREADS |
|||
FFX_CACAO_EMBED_ROOTSIG_CONTENT |
|||
void CS_PostprocessB(uint2 tid : SV_DispatchThreadID) |
|||
{ |
|||
FFX_CACAO_PostprocessImportanceMapB(tid); |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 6fa8aa563c4b8904ba31f550495313e1 |
|||
ShaderIncludeImporter: |
|||
externalObjects: {} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,86 @@ |
|||
// This file is part of the FidelityFX SDK. |
|||
// |
|||
// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved. |
|||
// |
|||
// 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. |
|||
|
|||
|
|||
#define CACAO_BIND_SRV_LOAD_COUNTER 0 |
|||
#define CACAO_BIND_SRV_DEINTERLEAVED_DEPTHS 1 |
|||
#define CACAO_BIND_SRV_DEINTERLEAVED_NORMALS 2 |
|||
#define CACAO_BIND_SRV_SSAO_BUFFER_PONG 3 |
|||
#define CACAO_BIND_SRV_IMPORTANCE_MAP 4 |
|||
#define CACAO_BIND_UAV_SSAO_BUFFER_PING 0 |
|||
|
|||
#define CACAO_BIND_CB_CACAO 0 |
|||
|
|||
#include "cacao/ffx_cacao_callbacks_hlsl.h" |
|||
#include "cacao/ffx_cacao_ssao_generation.h" |
|||
|
|||
#ifndef FFX_CACAO_THREAD_GROUP_WIDTH |
|||
#define FFX_CACAO_THREAD_GROUP_WIDTH 8 |
|||
#endif // #ifndef FFX_CACAO_THREAD_GROUP_WIDTH |
|||
#ifndef FFX_CACAO_THREAD_GROUP_HEIGHT |
|||
#define FFX_CACAO_THREAD_GROUP_HEIGHT 8 |
|||
#endif // FFX_CACAO_THREAD_GROUP_HEIGHT |
|||
#ifndef FFX_CACAO_THREAD_GROUP_DEPTH |
|||
#define FFX_CACAO_THREAD_GROUP_DEPTH 1 |
|||
#endif // #ifndef FFX_CACAO_THREAD_GROUP_DEPTH |
|||
#ifndef FFX_CACAO_NUM_THREADS |
|||
#define FFX_CACAO_NUM_THREADS [numthreads(FFX_CACAO_THREAD_GROUP_WIDTH, FFX_CACAO_THREAD_GROUP_HEIGHT, FFX_CACAO_THREAD_GROUP_DEPTH)] |
|||
#endif // #ifndef FFX_CACAO_NUM_THREADS |
|||
|
|||
FFX_PREFER_WAVE64 |
|||
FFX_CACAO_NUM_THREADS |
|||
FFX_CACAO_EMBED_ROOTSIG_CONTENT |
|||
void CS_Q0(uint3 tid : SV_DispatchThreadID) |
|||
{ |
|||
FFX_CACAO_GenerateQ0(tid); |
|||
} |
|||
|
|||
FFX_PREFER_WAVE64 |
|||
FFX_CACAO_NUM_THREADS |
|||
FFX_CACAO_EMBED_ROOTSIG_CONTENT |
|||
void CS_Q1(uint3 tid : SV_DispatchThreadID) |
|||
{ |
|||
FFX_CACAO_GenerateQ1(tid); |
|||
} |
|||
|
|||
FFX_PREFER_WAVE64 |
|||
FFX_CACAO_NUM_THREADS |
|||
FFX_CACAO_EMBED_ROOTSIG_CONTENT |
|||
void CS_Q2(uint3 tid : SV_DispatchThreadID) |
|||
{ |
|||
FFX_CACAO_GenerateQ2(tid); |
|||
} |
|||
|
|||
FFX_PREFER_WAVE64 |
|||
FFX_CACAO_NUM_THREADS |
|||
FFX_CACAO_EMBED_ROOTSIG_CONTENT |
|||
void CS_Q3Base(uint3 tid : SV_DispatchThreadID) |
|||
{ |
|||
FFX_CACAO_GenerateQ3Base(tid); |
|||
} |
|||
|
|||
FFX_PREFER_WAVE64 |
|||
FFX_CACAO_NUM_THREADS |
|||
FFX_CACAO_EMBED_ROOTSIG_CONTENT |
|||
void CS_Q3(uint3 tid : SV_DispatchThreadID) |
|||
{ |
|||
FFX_CACAO_GenerateQ3(tid); |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
fileFormatVersion: 2 |
|||
guid: c392ff7be072a7c4794ae035504d4c76 |
|||
ShaderIncludeImporter: |
|||
externalObjects: {} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,91 @@ |
|||
// This file is part of the FidelityFX SDK. |
|||
// |
|||
// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved. |
|||
// |
|||
// 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. |
|||
|
|||
|
|||
#define CACAO_BIND_SRV_DEPTH_IN 0 |
|||
#define CACAO_BIND_UAV_DEPTH_DOWNSAMPLED_MIPS 0 |
|||
#define CACAO_BIND_UAV_DEINTERLEAVED_DEPTHS 0 |
|||
|
|||
#define CACAO_BIND_CB_CACAO 0 |
|||
|
|||
#include "cacao/ffx_cacao_callbacks_hlsl.h" |
|||
#include "cacao/ffx_cacao_prepare.h" |
|||
|
|||
#ifndef FFX_CACAO_THREAD_GROUP_WIDTH |
|||
#define FFX_CACAO_THREAD_GROUP_WIDTH 8 |
|||
#endif // #ifndef FFX_CACAO_THREAD_GROUP_WIDTH |
|||
#ifndef FFX_CACAO_THREAD_GROUP_HEIGHT |
|||
#define FFX_CACAO_THREAD_GROUP_HEIGHT 8 |
|||
#endif // FFX_CACAO_THREAD_GROUP_HEIGHT |
|||
#ifndef FFX_CACAO_THREAD_GROUP_DEPTH |
|||
#define FFX_CACAO_THREAD_GROUP_DEPTH 1 |
|||
#endif // #ifndef FFX_CACAO_THREAD_GROUP_DEPTH |
|||
#ifndef FFX_CACAO_NUM_THREADS |
|||
#define FFX_CACAO_NUM_THREADS [numthreads(FFX_CACAO_THREAD_GROUP_WIDTH, FFX_CACAO_THREAD_GROUP_HEIGHT, FFX_CACAO_THREAD_GROUP_DEPTH)] |
|||
#endif // #ifndef FFX_CACAO_NUM_THREADS |
|||
|
|||
FFX_PREFER_WAVE64 |
|||
FFX_CACAO_NUM_THREADS |
|||
FFX_CACAO_EMBED_ROOTSIG_CONTENT |
|||
void CS_Native(uint2 tid : SV_DispatchThreadID) |
|||
{ |
|||
FFX_CACAO_PrepareNativeDepths(tid); |
|||
} |
|||
|
|||
FFX_PREFER_WAVE64 |
|||
FFX_CACAO_NUM_THREADS |
|||
FFX_CACAO_EMBED_ROOTSIG_CONTENT |
|||
void CS_NativeHalf(uint2 tid : SV_DispatchThreadID) |
|||
{ |
|||
FFX_CACAO_PrepareNativeDepthsHalf(tid); |
|||
} |
|||
|
|||
FFX_PREFER_WAVE64 |
|||
FFX_CACAO_NUM_THREADS |
|||
FFX_CACAO_EMBED_ROOTSIG_CONTENT |
|||
void CS_NativeAndMips(uint2 tid : SV_DispatchThreadID, uint2 gtid : SV_GroupThreadID) |
|||
{ |
|||
FFX_CACAO_PrepareNativeDepthsAndMips(tid, gtid); |
|||
} |
|||
|
|||
FFX_PREFER_WAVE64 |
|||
FFX_CACAO_NUM_THREADS |
|||
FFX_CACAO_EMBED_ROOTSIG_CONTENT |
|||
void CS_Downsampled(uint2 tid : SV_DispatchThreadID) |
|||
{ |
|||
FFX_CACAO_PrepareDownsampledDepths(tid); |
|||
} |
|||
|
|||
FFX_PREFER_WAVE64 |
|||
FFX_CACAO_NUM_THREADS |
|||
FFX_CACAO_EMBED_ROOTSIG_CONTENT |
|||
void CS_DownsampledHalf(uint2 tid : SV_DispatchThreadID) |
|||
{ |
|||
FFX_CACAO_PrepareDownsampledDepthsHalf(tid); |
|||
} |
|||
|
|||
FFX_PREFER_WAVE64 |
|||
FFX_CACAO_NUM_THREADS |
|||
FFX_CACAO_EMBED_ROOTSIG_CONTENT |
|||
void CS_DownsampledAndMips(uint2 tid : SV_DispatchThreadID, uint2 gtid : SV_GroupThreadID) |
|||
{ |
|||
FFX_CACAO_PrepareDownsampledDepthsAndMips(tid, gtid); |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
fileFormatVersion: 2 |
|||
guid: f203546befe69324290d22798d70a2e8 |
|||
ShaderIncludeImporter: |
|||
externalObjects: {} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,75 @@ |
|||
// This file is part of the FidelityFX SDK. |
|||
// |
|||
// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved. |
|||
// |
|||
// 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. |
|||
|
|||
|
|||
#define CACAO_BIND_SRV_DEPTH_IN 0 |
|||
#define CACAO_BIND_SRV_NORMAL_IN 0 |
|||
#define CACAO_BIND_UAV_DEINTERLEAVED_NORMALS 0 |
|||
|
|||
#define CACAO_BIND_CB_CACAO 0 |
|||
|
|||
#include "cacao/ffx_cacao_callbacks_hlsl.h" |
|||
#include "cacao/ffx_cacao_prepare.h" |
|||
|
|||
#ifndef FFX_CACAO_THREAD_GROUP_WIDTH |
|||
#define FFX_CACAO_THREAD_GROUP_WIDTH 8 |
|||
#endif // #ifndef FFX_CACAO_THREAD_GROUP_WIDTH |
|||
#ifndef FFX_CACAO_THREAD_GROUP_HEIGHT |
|||
#define FFX_CACAO_THREAD_GROUP_HEIGHT 8 |
|||
#endif // FFX_CACAO_THREAD_GROUP_HEIGHT |
|||
#ifndef FFX_CACAO_THREAD_GROUP_DEPTH |
|||
#define FFX_CACAO_THREAD_GROUP_DEPTH 1 |
|||
#endif // #ifndef FFX_CACAO_THREAD_GROUP_DEPTH |
|||
#ifndef FFX_CACAO_NUM_THREADS |
|||
#define FFX_CACAO_NUM_THREADS [numthreads(FFX_CACAO_THREAD_GROUP_WIDTH, FFX_CACAO_THREAD_GROUP_HEIGHT, FFX_CACAO_THREAD_GROUP_DEPTH)] |
|||
#endif // #ifndef FFX_CACAO_NUM_THREADS |
|||
|
|||
FFX_PREFER_WAVE64 |
|||
FFX_CACAO_NUM_THREADS |
|||
FFX_CACAO_EMBED_ROOTSIG_CONTENT |
|||
void CS_Native(uint2 tid : SV_DispatchThreadID) |
|||
{ |
|||
FFX_CACAO_PrepareNativeNormals(tid); |
|||
} |
|||
|
|||
FFX_PREFER_WAVE64 |
|||
FFX_CACAO_NUM_THREADS |
|||
FFX_CACAO_EMBED_ROOTSIG_CONTENT |
|||
void CS_NativeFromInputNormals(uint2 tid : SV_DispatchThreadID) |
|||
{ |
|||
FFX_CACAO_PrepareNativeNormalsFromInputNormals(tid); |
|||
} |
|||
|
|||
FFX_PREFER_WAVE64 |
|||
FFX_CACAO_NUM_THREADS |
|||
FFX_CACAO_EMBED_ROOTSIG_CONTENT |
|||
void CS_Downsampled(uint2 tid : SV_DispatchThreadID) |
|||
{ |
|||
FFX_CACAO_PrepareDownsampledNormals(tid); |
|||
} |
|||
|
|||
FFX_PREFER_WAVE64 |
|||
FFX_CACAO_NUM_THREADS |
|||
FFX_CACAO_EMBED_ROOTSIG_CONTENT |
|||
void CS_DownsampledFromInputNormals(uint2 tid : SV_DispatchThreadID) |
|||
{ |
|||
FFX_CACAO_PrepareDownsampledNormalsFromInputNormals(tid); |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
fileFormatVersion: 2 |
|||
guid: e6711b0dba6aaf64b9493249e2481ec7 |
|||
ShaderIncludeImporter: |
|||
externalObjects: {} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,68 @@ |
|||
// This file is part of the FidelityFX SDK. |
|||
// |
|||
// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved. |
|||
// |
|||
// 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. |
|||
|
|||
|
|||
#define CACAO_BIND_SRV_DEPTH_IN 0 |
|||
#define CACAO_BIND_SRV_DEINTERLEAVED_DEPTHS 1 |
|||
#define CACAO_BIND_SRV_SSAO_BUFFER_PING 2 |
|||
#define CACAO_BIND_UAV_OUTPUT 0 |
|||
|
|||
#define CACAO_BIND_CB_CACAO 0 |
|||
|
|||
#include "cacao/ffx_cacao_callbacks_hlsl.h" |
|||
#include "cacao/ffx_cacao_upscale.h" |
|||
|
|||
#ifndef FFX_CACAO_THREAD_GROUP_WIDTH |
|||
#define FFX_CACAO_THREAD_GROUP_WIDTH 8 |
|||
#endif // #ifndef FFX_CACAO_THREAD_GROUP_WIDTH |
|||
#ifndef FFX_CACAO_THREAD_GROUP_HEIGHT |
|||
#define FFX_CACAO_THREAD_GROUP_HEIGHT 8 |
|||
#endif // FFX_CACAO_THREAD_GROUP_HEIGHT |
|||
#ifndef FFX_CACAO_THREAD_GROUP_DEPTH |
|||
#define FFX_CACAO_THREAD_GROUP_DEPTH 1 |
|||
#endif // #ifndef FFX_CACAO_THREAD_GROUP_DEPTH |
|||
#ifndef FFX_CACAO_NUM_THREADS |
|||
#define FFX_CACAO_NUM_THREADS [numthreads(FFX_CACAO_THREAD_GROUP_WIDTH, FFX_CACAO_THREAD_GROUP_HEIGHT, FFX_CACAO_THREAD_GROUP_DEPTH)] |
|||
#endif // #ifndef FFX_CACAO_NUM_THREADS |
|||
|
|||
FFX_PREFER_WAVE64 |
|||
FFX_CACAO_NUM_THREADS |
|||
FFX_CACAO_EMBED_ROOTSIG_CONTENT |
|||
void CS_5x5Smart(int2 tid : SV_DispatchThreadID, uint2 gtid : SV_GroupThreadID, uint2 gid : SV_GroupID) |
|||
{ |
|||
FFX_CACAO_UpscaleBilateral5x5Pass(tid, gtid, gid); |
|||
} |
|||
|
|||
FFX_PREFER_WAVE64 |
|||
FFX_CACAO_NUM_THREADS |
|||
FFX_CACAO_EMBED_ROOTSIG_CONTENT |
|||
void CS_5x5NonSmart(int2 tid : SV_DispatchThreadID, uint2 gtid : SV_GroupThreadID, uint2 gid : SV_GroupID) |
|||
{ |
|||
FFX_CACAO_UpscaleBilateral5x5Pass(tid, gtid, gid); |
|||
} |
|||
|
|||
FFX_PREFER_WAVE64 |
|||
FFX_CACAO_NUM_THREADS |
|||
FFX_CACAO_EMBED_ROOTSIG_CONTENT |
|||
void CS_5x5Half(int2 tid : SV_DispatchThreadID, uint2 gtid : SV_GroupThreadID, uint2 gid : SV_GroupID) |
|||
{ |
|||
FFX_CACAO_UpscaleBilateral5x5Pass(tid, gtid, gid); |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
fileFormatVersion: 2 |
|||
guid: d350911a7fdedfd41bb3752bca83023e |
|||
ShaderIncludeImporter: |
|||
externalObjects: {} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue