2021-09-09 20:42:29 -04:00

185 lines
6.9 KiB
Plaintext

Shader "Hidden/HDRP/FinalPass"
{
HLSLINCLUDE
#pragma target 4.5
#pragma editor_sync_compilation
#pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch
#pragma multi_compile_local _ FXAA
#pragma multi_compile_local _ GRAIN
#pragma multi_compile_local _ DITHER
#pragma multi_compile_local _ ENABLE_ALPHA
#pragma multi_compile_local _ APPLY_AFTER_POST
#pragma multi_compile_local _ BILINEAR CATMULL_ROM_4 LANCZOS CONTRASTADAPTIVESHARPEN
#define DEBUG_UPSCALE_POINT 0
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Shaders/FXAA.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Shaders/PostProcessDefines.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Shaders/RTUpscale.hlsl"
TEXTURE2D_X(_InputTexture);
TEXTURE2D(_GrainTexture);
TEXTURE2D_X(_AfterPostProcessTexture);
TEXTURE2D_ARRAY(_BlueNoiseTexture);
TEXTURE2D_X(_AlphaTexture);
SAMPLER(sampler_LinearClamp);
SAMPLER(sampler_LinearRepeat);
float2 _GrainParams; // x: intensity, y: response
float4 _GrainTextureParams; // xy: _ScreenSize.xy / GrainTextureSize.xy, zw: (random offset in UVs) * _GrainTextureParams.xy
float3 _DitherParams; // xy: _ScreenSize.xy / DitherTextureSize.xy, z: texture_id
float4 _UVTransform;
float4 _ViewPortSize;
float _KeepAlpha;
struct Attributes
{
uint vertexID : SV_VertexID;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct Varyings
{
float4 positionCS : SV_POSITION;
float2 texcoord : TEXCOORD0;
UNITY_VERTEX_OUTPUT_STEREO
};
Varyings Vert(Attributes input)
{
Varyings output;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
output.positionCS = GetFullScreenTriangleVertexPosition(input.vertexID);
output.texcoord = GetFullScreenTriangleTexCoord(input.vertexID);
return output;
}
CTYPE UpscaledResult(float2 UV)
{
#if DEBUG_UPSCALE_POINT
return Nearest(_InputTexture, UV);
#else
#if BILINEAR
return Bilinear(_InputTexture, UV);
#elif CATMULL_ROM_4
return CatmullRomFourSamples(_InputTexture, UV);
#elif LANCZOS
return Lanczos(_InputTexture, UV, _ViewPortSize.xy);
#else
return Nearest(_InputTexture, UV);
#endif
#endif
}
float4 Frag(Varyings input) : SV_Target0
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
float2 positionNDC = input.texcoord;
uint2 positionSS = input.texcoord * _ScreenSize.xy;
// Flip logic
positionSS = positionSS * _UVTransform.xy + _UVTransform.zw * (_ScreenSize.xy - 1.0);
positionNDC = positionNDC * _UVTransform.xy + _UVTransform.zw;
#if defined(BILINEAR) || defined(CATMULL_ROM_4) || defined(LANCZOS)
CTYPE outColor = UpscaledResult(positionNDC.xy);
#elif defined(CONTRASTADAPTIVESHARPEN)
CTYPE outColor = LOAD_TEXTURE2D_X(_InputTexture, ((input.texcoord.xy * _UVTransform.xy) + _UVTransform.zw) * _ViewPortSize.xy).CTYPE_SWIZZLE;
#else
CTYPE outColor = LOAD_TEXTURE2D_X(_InputTexture, positionSS).CTYPE_SWIZZLE;
#endif
#if !defined(ENABLE_ALPHA)
float outAlpha = (_KeepAlpha == 1.0) ? LOAD_TEXTURE2D_X(_AlphaTexture, positionSS).x : 1.0;
#endif
#if FXAA
CTYPE beforeFXAA = outColor;
RunFXAA(_InputTexture, sampler_LinearClamp, outColor, positionSS, positionNDC);
#if defined(ENABLE_ALPHA)
// When alpha processing is enabled, FXAA should not affect pixels with zero alpha
outColor.xyz = outColor.a > 0 ? outColor.xyz : beforeFXAA.xyz;
#endif
#endif //FXAA
// Saturate is only needed for dither or grain to work. Otherwise we don't saturate because output might be HDR
#if defined(GRAIN) || defined(DITHER)
outColor = saturate(outColor);
#endif
#if GRAIN
{
// Grain in range [0;1] with neutral at 0.5
float grain = SAMPLE_TEXTURE2D(_GrainTexture, s_linear_repeat_sampler, (positionNDC * _GrainTextureParams.xy) + _GrainTextureParams.zw).w;
// Remap [-1;1]
grain = (grain - 0.5) * 2.0;
// Noisiness response curve based on scene luminance
float lum = 1.0 - sqrt(Luminance(outColor));
lum = lerp(1.0, lum, _GrainParams.y);
outColor.xyz += outColor.xyz * grain * _GrainParams.x * lum;
}
#endif
#if DITHER
// sRGB 8-bit dithering
{
float3 ditherParams = _DitherParams;
// Symmetric triangular distribution on [-1,1] with maximal density at 0
float noise = SAMPLE_TEXTURE2D_ARRAY(_BlueNoiseTexture, s_linear_repeat_sampler, positionNDC * ditherParams.xy, ditherParams.z).a;
float3 sRGBColor = LinearToSRGB(outColor.xyz);
noise = noise * 2.0 - 1.0;
noise = FastSign(noise) * (1.0 - sqrt(1.0 - abs(noise)));
//outColor += noise / 255.0;
outColor.xyz = SRGBToLinear(sRGBColor + noise / 255.0);
}
#endif
// Apply AfterPostProcess target
#if APPLY_AFTER_POST
float4 afterPostColor = SAMPLE_TEXTURE2D_X_LOD(_AfterPostProcessTexture, s_point_clamp_sampler, positionNDC.xy * _RTHandleScale.xy, 0);
// After post objects are blended according to the method described here: https://developer.nvidia.com/gpugems/GPUGems3/gpugems3_ch23.html
outColor.xyz = afterPostColor.a * outColor.xyz + afterPostColor.xyz;
#endif
#if !defined(ENABLE_ALPHA)
return float4(outColor, outAlpha);
#else
return outColor;
#endif
}
ENDHLSL
SubShader
{
Tags{ "RenderPipeline" = "HDRenderPipeline" }
Pass
{
Cull Off ZWrite Off ZTest Always
HLSLPROGRAM
#pragma vertex Vert
#pragma fragment Frag
ENDHLSL
}
}
}