You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
257 lines
8.1 KiB
257 lines
8.1 KiB
///
|
|
/// FidelityFX Super Resolution (FSR) Common Shader Code
|
|
///
|
|
/// This file provides shader helper functions which are intended to be used with the C# helper functions in
|
|
/// FSRUtils.cs. The main purpose of this file is to simplify the usage of the external FSR shader functions within
|
|
/// the Unity shader environment.
|
|
///
|
|
/// Usage:
|
|
/// - Call SetXConstants function on a command buffer in C#
|
|
/// - Launch shader (via draw or dispatch)
|
|
/// - Call associated ApplyX function provided by this file
|
|
///
|
|
/// The following preprocessor parameters MUST be defined before including this file:
|
|
/// - FSR_INPUT_TEXTURE
|
|
/// - The texture to use as input for the FSR passes
|
|
/// - FSR_INPUT_SAMPLER
|
|
/// - The sample to use for FSR_INPUT_TEXTURE
|
|
///
|
|
/// The following preprocessor parameters are optional and MAY be defined before including this file:
|
|
/// - FSR_ENABLE_ALPHA
|
|
/// - Enables alpha pass-through functionality for the RCAS pass
|
|
///
|
|
|
|
// Ensure that the shader including this file is targeting an adequate shader level
|
|
#if SHADER_TARGET < 45
|
|
#error FidelityFX Super Resolution requires a shader target of 4.5 or greater
|
|
#endif
|
|
|
|
// Indicate that we'll be using the HLSL implementation of FSR
|
|
#define A_GPU 1
|
|
#define A_HLSL 1
|
|
|
|
// Enable either the 16-bit or the 32-bit implementation of FSR depending on platform support
|
|
// Note: There are known issues relating to the math approximation functions on some DX11 drivers when FP16 is used.
|
|
// Due to this issue, we currently prevent the 16-bit implementation from being used when DX11 is detected.
|
|
#if REAL_IS_HALF && !defined(SHADER_API_D3D11)
|
|
#define A_HALF
|
|
#define FSR_EASU_H 1
|
|
#define FSR_RCAS_H 1
|
|
#else
|
|
#define FSR_EASU_F 1
|
|
#define FSR_RCAS_F 1
|
|
#endif
|
|
|
|
// Enable the RCAS passthrough alpha feature when the alpha channel is in use
|
|
#if FSR_ENABLE_ALPHA
|
|
#define FSR_RCAS_PASSTHROUGH_ALPHA 1
|
|
#endif
|
|
|
|
// Include the external FSR HLSL files
|
|
#include "Packages/com.unity.render-pipelines.core/Runtime/PostProcessing/Shaders/ffx/ffx_a.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.core/Runtime/PostProcessing/Shaders/ffx/ffx_fsr1.hlsl"
|
|
|
|
/// Bindings for FSR EASU constants provided by the CPU
|
|
///
|
|
/// Helper functions that set these constants can be found in FSRUtils
|
|
float4 _FsrEasuConstants0;
|
|
float4 _FsrEasuConstants1;
|
|
float4 _FsrEasuConstants2;
|
|
float4 _FsrEasuConstants3;
|
|
|
|
// Unity doesn't currently have a way to bind uint4 types so we reinterpret float4 as uint4 using macros below
|
|
#define FSR_EASU_CONSTANTS_0 asuint(_FsrEasuConstants0)
|
|
#define FSR_EASU_CONSTANTS_1 asuint(_FsrEasuConstants1)
|
|
#define FSR_EASU_CONSTANTS_2 asuint(_FsrEasuConstants2)
|
|
#define FSR_EASU_CONSTANTS_3 asuint(_FsrEasuConstants3)
|
|
|
|
/// EASU glue functions
|
|
///
|
|
/// These are used by the EASU implementation to access texture data
|
|
#if FSR_EASU_H
|
|
AH4 FsrEasuRH(AF2 p)
|
|
{
|
|
#ifdef FSR_CLAMP_COORD
|
|
p = FSR_CLAMP_COORD(p);
|
|
#endif
|
|
|
|
return (AH4)GATHER_RED_TEXTURE2D_X(FSR_INPUT_TEXTURE, FSR_INPUT_SAMPLER, p);
|
|
}
|
|
AH4 FsrEasuGH(AF2 p)
|
|
{
|
|
#ifdef FSR_CLAMP_COORD
|
|
p = FSR_CLAMP_COORD(p);
|
|
#endif
|
|
|
|
return (AH4)GATHER_GREEN_TEXTURE2D_X(FSR_INPUT_TEXTURE, FSR_INPUT_SAMPLER, p);
|
|
}
|
|
AH4 FsrEasuBH(AF2 p)
|
|
{
|
|
#ifdef FSR_CLAMP_COORD
|
|
p = FSR_CLAMP_COORD(p);
|
|
#endif
|
|
|
|
return (AH4)GATHER_BLUE_TEXTURE2D_X(FSR_INPUT_TEXTURE, FSR_INPUT_SAMPLER, p);
|
|
}
|
|
|
|
void FsrEasuProcessInput(inout AH4 r, inout AH4 g, inout AH4 b)
|
|
{
|
|
// HDRP only. URP use an upscaling pass before EASU pass where this operation can be done.
|
|
#ifdef HDR_INPUT
|
|
AH3 s0 = FastTonemap(AH3(r.x, g.x, b.x) * FSR_EASU_ONE_OVER_PAPER_WHITE);
|
|
AH3 s1 = FastTonemap(AH3(r.y, g.y, b.y) * FSR_EASU_ONE_OVER_PAPER_WHITE);
|
|
AH3 s2 = FastTonemap(AH3(r.z, g.z, b.z) * FSR_EASU_ONE_OVER_PAPER_WHITE);
|
|
AH3 s3 = FastTonemap(AH3(r.w, g.w, b.w) * FSR_EASU_ONE_OVER_PAPER_WHITE);
|
|
|
|
r = AH4(s0.r, s1.r, s2.r, s3.r);
|
|
g = AH4(s0.g, s1.g, s2.g, s3.g);
|
|
b = AH4(s0.b, s1.b, s2.b, s3.b);
|
|
#endif
|
|
}
|
|
#else
|
|
AF4 FsrEasuRF(AF2 p)
|
|
{
|
|
#ifdef FSR_CLAMP_COORD
|
|
p = FSR_CLAMP_COORD(p);
|
|
#endif
|
|
|
|
return GATHER_RED_TEXTURE2D_X(FSR_INPUT_TEXTURE, FSR_INPUT_SAMPLER, p);
|
|
}
|
|
AF4 FsrEasuGF(AF2 p)
|
|
{
|
|
#ifdef FSR_CLAMP_COORD
|
|
p = FSR_CLAMP_COORD(p);
|
|
#endif
|
|
|
|
return GATHER_GREEN_TEXTURE2D_X(FSR_INPUT_TEXTURE, FSR_INPUT_SAMPLER, p);
|
|
}
|
|
AF4 FsrEasuBF(AF2 p)
|
|
{
|
|
#ifdef FSR_CLAMP_COORD
|
|
p = FSR_CLAMP_COORD(p);
|
|
#endif
|
|
|
|
return GATHER_BLUE_TEXTURE2D_X(FSR_INPUT_TEXTURE, FSR_INPUT_SAMPLER, p);
|
|
}
|
|
|
|
void FsrEasuProcessInput(inout AF4 r, inout AF4 g, inout AF4 b)
|
|
{
|
|
// HDRP only. URP use an upscaling pass before EASU pass where this operation can be done.
|
|
#ifdef HDR_INPUT
|
|
#ifndef FSR_EASU_ONE_OVER_PAPER_WHITE
|
|
#error missing definition of FSR_EASU_ONE_OVER_PAPER_WHITE
|
|
#endif
|
|
float3 s0 = FastTonemap(float3(r.x, g.x, b.x) * FSR_EASU_ONE_OVER_PAPER_WHITE);
|
|
float3 s1 = FastTonemap(float3(r.y, g.y, b.y) * FSR_EASU_ONE_OVER_PAPER_WHITE);
|
|
float3 s2 = FastTonemap(float3(r.z, g.z, b.z) * FSR_EASU_ONE_OVER_PAPER_WHITE);
|
|
float3 s3 = FastTonemap(float3(r.w, g.w, b.w) * FSR_EASU_ONE_OVER_PAPER_WHITE);
|
|
|
|
r = float4(s0.r, s1.r, s2.r, s3.r);
|
|
g = float4(s0.g, s1.g, s2.g, s3.g);
|
|
b = float4(s0.b, s1.b, s2.b, s3.b);
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
/// Applies FidelityFX Super Resolution Edge Adaptive Spatial Upsampling at the provided pixel position
|
|
///
|
|
/// The source texture must be provided before this file is included via the FSR_INPUT_TEXTURE preprocessor symbol
|
|
/// Ex: #define FSR_INPUT_TEXTURE _SourceTex
|
|
///
|
|
/// A valid sampler must also be provided via the FSR_INPUT_SAMPLER preprocessor symbol
|
|
/// Ex: #define FSR_INPUT_SAMPLER sampler_LinearClamp
|
|
///
|
|
/// The color data stored in the source texture should be in gamma 2.0 color space
|
|
real3 ApplyEASU(uint2 positionSS)
|
|
{
|
|
#if FSR_EASU_H
|
|
// Execute 16-bit EASU
|
|
AH3 color;
|
|
FsrEasuH(
|
|
#else
|
|
// Execute 32-bit EASU
|
|
AF3 color;
|
|
FsrEasuF(
|
|
#endif
|
|
color, positionSS, FSR_EASU_CONSTANTS_0, FSR_EASU_CONSTANTS_1, FSR_EASU_CONSTANTS_2, FSR_EASU_CONSTANTS_3
|
|
);
|
|
return color;
|
|
}
|
|
|
|
/// Bindings for FSR RCAS constants provided by the CPU
|
|
///
|
|
/// Helper functions that set these constants can be found in FSRUtils
|
|
float4 _FsrRcasConstants;
|
|
|
|
// Unity doesn't currently have a way to bind uint4 types so we reinterpret float4 as uint4 using macros below
|
|
#define FSR_RCAS_CONSTANTS asuint(_FsrRcasConstants)
|
|
|
|
/// RCAS glue functions
|
|
///
|
|
/// These are used by the RCAS implementation to access texture data and perform color space conversion if necessary
|
|
#if FSR_RCAS_H
|
|
AH4 FsrRcasLoadH(ASW2 p)
|
|
{
|
|
return (AH4)LOAD_TEXTURE2D_X(FSR_INPUT_TEXTURE, p);
|
|
}
|
|
void FsrRcasInputH(inout AH1 r, inout AH1 g, inout AH1 b)
|
|
{
|
|
// No conversion to linear necessary since it's always performed during EASU output
|
|
}
|
|
#else
|
|
AF4 FsrRcasLoadF(ASU2 p)
|
|
{
|
|
return LOAD_TEXTURE2D_X(FSR_INPUT_TEXTURE, p);
|
|
}
|
|
void FsrRcasInputF(inout AF1 r, inout AF1 g, inout AF1 b)
|
|
{
|
|
// No conversion to linear necessary since it's always performed during EASU output
|
|
}
|
|
#endif
|
|
|
|
/// Applies FidelityFX Super Resolution Robust Contrast Adaptive Sharpening at the provided pixel position
|
|
///
|
|
/// The source texture must be provided before this file is included via the FSR_INPUT_TEXTURE preprocessor symbol
|
|
/// Ex: #define FSR_INPUT_TEXTURE _SourceTex
|
|
///
|
|
/// A valid sampler must also be provided via the FSR_INPUT_SAMPLER preprocessor symbol
|
|
/// Ex: #define FSR_INPUT_SAMPLER sampler_LinearClamp
|
|
///
|
|
/// RCAS supports an optional alpha passthrough that can be enabled via the FSR_ENABLE_ALPHA preprocessor symbol
|
|
/// When passthrough is enabled, this function will return the input texture's alpha channel unmodified
|
|
///
|
|
/// The color data stored in the source texture should be in linear color space
|
|
#if FSR_ENABLE_ALPHA
|
|
real4 ApplyRCAS(uint2 positionSS)
|
|
#else
|
|
real3 ApplyRCAS(uint2 positionSS)
|
|
#endif
|
|
{
|
|
#if FSR_RCAS_H
|
|
// Execute 16-bit RCAS
|
|
#if FSR_ENABLE_ALPHA
|
|
AH4 color;
|
|
#else
|
|
AH3 color;
|
|
#endif
|
|
FsrRcasH(
|
|
#else
|
|
// Execute 32-bit RCAS
|
|
#if FSR_ENABLE_ALPHA
|
|
AF4 color;
|
|
#else
|
|
AF3 color;
|
|
#endif
|
|
FsrRcasF(
|
|
#endif
|
|
color.r,
|
|
color.g,
|
|
color.b,
|
|
#if FSR_ENABLE_ALPHA
|
|
color.a,
|
|
#endif
|
|
positionSS,
|
|
FSR_RCAS_CONSTANTS
|
|
);
|
|
return color;
|
|
}
|