239 lines
8.7 KiB
Plaintext
239 lines
8.7 KiB
Plaintext
#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.core/ShaderLibrary/Filtering.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Shaders/UberPostFeatures.cs.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Shaders/BloomCommon.hlsl"
|
|
|
|
#pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch
|
|
|
|
#pragma kernel Uber
|
|
|
|
#pragma multi_compile _ CHROMATIC_ABERRATION
|
|
#pragma multi_compile _ VIGNETTE
|
|
#pragma multi_compile _ LENS_DISTORTION
|
|
#pragma multi_compile _ ENABLE_ALPHA
|
|
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Shaders/PostProcessDefines.hlsl"
|
|
|
|
TEXTURE2D_X(_InputTexture);
|
|
TEXTURE2D_X(_BloomTexture);
|
|
TEXTURE2D(_BloomDirtTexture);
|
|
TEXTURE2D(_ChromaSpectralLut);
|
|
TEXTURE3D(_LogLut3D);
|
|
TEXTURE2D(_VignetteMask);
|
|
|
|
RW_TEXTURE2D_X(CTYPE, _OutputTexture);
|
|
|
|
SAMPLER(sampler_LinearClamp);
|
|
SAMPLER(sampler_ChromaSpectralLut);
|
|
SAMPLER(sampler_LogLut3D);
|
|
SAMPLER(sampler_VignetteMask);
|
|
|
|
CBUFFER_START(cb0)
|
|
float4 _ChromaParams;
|
|
float4 _VignetteParams1;
|
|
float4 _VignetteParams2;
|
|
float4 _VignetteColor;
|
|
float4 _DistortionParams1;
|
|
float4 _DistortionParams2;
|
|
float4 _LogLut3D_Params; // x: 1 / lut_size, y: lut_size - 1, z: postexposure, w: unused
|
|
float4 _BloomParams;
|
|
float4 _BloomThreshold;
|
|
float4 _BloomTint;
|
|
float4 _BloomDirtScaleOffset;
|
|
float4 _BloomBicubicParams;
|
|
float4 _DebugFlags;
|
|
float4 _AlphaScaleBias;
|
|
CBUFFER_END
|
|
|
|
#define DistCenter _DistortionParams1.xy
|
|
#define DistAxis _DistortionParams1.zw
|
|
#define DistTheta _DistortionParams2.x
|
|
#define DistSigma _DistortionParams2.y
|
|
#define DistScale _DistortionParams2.z
|
|
#define DistIntensity _DistortionParams2.w
|
|
|
|
#define ChromaAmount _ChromaParams.x
|
|
#define ChromaMaxSamples int(_ChromaParams.y)
|
|
|
|
#define VignetteCenter _VignetteParams1.xy
|
|
#define VignetteMode uint(_VignetteParams1.z)
|
|
#define VignetteIntensity _VignetteParams2.x
|
|
#define VignetteSmoothness _VignetteParams2.y
|
|
#define VignetteRoundness _VignetteParams2.z
|
|
#define VignetteRounded _VignetteParams2.w
|
|
#define VignetteColor _VignetteColor.xyz
|
|
#define VignetteOpacity _VignetteColor.w
|
|
|
|
#define PostExposure _LogLut3D_Params.z
|
|
|
|
#define BloomTint _BloomTint.xyz
|
|
#define BloomIntensity _BloomParams.x
|
|
#define DirtIntensity _BloomParams.y
|
|
#define BloomEnabled _BloomParams.z
|
|
#define DirtEnabled _BloomParams.w
|
|
#define DirtScale _BloomDirtScaleOffset.xy
|
|
#define DirtOffset _BloomDirtScaleOffset.zw
|
|
|
|
#define OutputLogEnabled _DebugFlags.x
|
|
|
|
#define AlphaScale _AlphaScaleBias.x
|
|
#define AlphaBias _AlphaScaleBias.y
|
|
|
|
float2 DistortUV(float2 uv)
|
|
{
|
|
// Lens distortion
|
|
// Note: this variant should never be set with XR
|
|
#ifdef LENS_DISTORTION
|
|
uv = (uv - 0.5) * DistScale + 0.5;
|
|
float2 ruv = DistAxis * (uv - 0.5 - DistCenter);
|
|
float ru = length(float2(ruv));
|
|
|
|
UNITY_BRANCH
|
|
if (DistIntensity > 0.0)
|
|
{
|
|
float wu = ru * DistTheta;
|
|
ru = tan(wu) * (rcp(ru * DistSigma));
|
|
uv = uv + ruv * (ru - 1.0);
|
|
}
|
|
else
|
|
{
|
|
ru = rcp(ru) * DistTheta * atan(ru * DistSigma);
|
|
uv = uv + ruv * (ru - 1.0);
|
|
}
|
|
#endif
|
|
|
|
return uv;
|
|
}
|
|
|
|
#define GROUP_SIZE 8
|
|
|
|
[numthreads(GROUP_SIZE, GROUP_SIZE, 1)]
|
|
void Uber(uint3 dispatchThreadId : SV_DispatchThreadID)
|
|
{
|
|
UNITY_XR_ASSIGN_VIEW_INDEX(dispatchThreadId.z);
|
|
PositionInputs posInputs = GetPositionInput(float2(dispatchThreadId.xy), _ScreenSize.zw, uint2(GROUP_SIZE, GROUP_SIZE));
|
|
float2 uv = posInputs.positionNDC;
|
|
float2 uvDistorted = DistortUV(uv);
|
|
CTYPE color = 0.0;
|
|
CTYPE inputColor = 0.0;
|
|
|
|
// Chromatic aberration
|
|
// Inspired by the method described in "Rendering Inside" [Playdead 2016]
|
|
// https://twitter.com/pixelmager/status/717019757766123520
|
|
#ifdef CHROMATIC_ABERRATION
|
|
float2 coords = 2.0 * uv - 1.0;
|
|
float2 end = uv - coords * dot(coords, coords) * ChromaAmount;
|
|
float2 diff = end - uv;
|
|
int samples = clamp(int(length(_ScreenSize.xy * diff / 2.0)), 3, ChromaMaxSamples);
|
|
float2 delta = diff / samples;
|
|
float2 pos = uv;
|
|
float3 sum = 0.0, filterSum = 0.0;
|
|
|
|
for (int i = 0; i < samples; i++)
|
|
{
|
|
float t = (i + 0.5) / samples;
|
|
float3 s = SAMPLE_TEXTURE2D_X_LOD(_InputTexture, sampler_LinearClamp, ClampAndScaleUVForBilinear(DistortUV(pos)), 0.0).xyz;
|
|
float3 filter = SAMPLE_TEXTURE2D_LOD(_ChromaSpectralLut, sampler_ChromaSpectralLut, float2(t, 0.0), 0).xyz;
|
|
|
|
sum += s * filter;
|
|
filterSum += filter;
|
|
pos += delta;
|
|
}
|
|
|
|
color.xyz = sum / filterSum;
|
|
#ifdef ENABLE_ALPHA
|
|
inputColor = SAMPLE_TEXTURE2D_X_LOD(_InputTexture, sampler_LinearClamp, ClampAndScaleUVForBilinear(uvDistorted), 0.0);
|
|
color.w = inputColor.w;
|
|
#endif
|
|
|
|
#else
|
|
color = SAMPLE_TEXTURE2D_X_LOD(_InputTexture, sampler_LinearClamp, ClampAndScaleUVForBilinear(uvDistorted), 0.0).CTYPE_SWIZZLE;
|
|
inputColor = color;
|
|
#endif
|
|
|
|
// Bloom
|
|
UNITY_BRANCH
|
|
if (BloomEnabled)
|
|
{
|
|
#if 0 // Bilinear
|
|
float3 bloom = SAMPLE_TEXTURE2D_X_LOD(_BloomTexture, sampler_LinearClamp, ClampAndScaleUVForBilinear(uvDistorted), 0.0).xyz;
|
|
#else
|
|
float3 bloom = SampleTexture2DBicubic(TEXTURE2D_X_ARGS(_BloomTexture, sampler_LinearClamp), uvDistorted * _RTHandleScale.xy, _BloomBicubicParams, _RTHandleScale.xy, unity_StereoEyeIndex).xyz;
|
|
#endif
|
|
|
|
float3 thresholdedColor = QuadraticThreshold(color.xyz, _BloomThreshold.x, _BloomThreshold.yzw);
|
|
color.xyz = lerp(color.xyz, (color.xyz - thresholdedColor) + (bloom * BloomTint), BloomIntensity);
|
|
|
|
UNITY_BRANCH
|
|
if (DirtEnabled)
|
|
{
|
|
// UVs for the dirt texture should be DistortUV(uv * DirtScale + DirtOffset) but
|
|
// considering we use a cover-style scale on the dirt texture the difference isn't massive
|
|
// so we chose to save a few ALUs here instead in case lens distortion is active
|
|
float3 dirt = SAMPLE_TEXTURE2D_LOD(_BloomDirtTexture, sampler_LinearClamp, uvDistorted * DirtScale + DirtOffset, 0.0).xyz;
|
|
color.xyz += bloom * dirt * DirtIntensity;
|
|
}
|
|
|
|
#ifdef ENABLE_ALPHA
|
|
// Bloom should also spread in areas with zero alpha, so we save the image with bloom here to do the mixing at the end of the shader
|
|
inputColor.xyz = color.xyz;
|
|
#endif
|
|
}
|
|
|
|
// Vignette
|
|
#ifdef VIGNETTE
|
|
|
|
UNITY_BRANCH
|
|
if (VignetteMode == 0u) // Procedural
|
|
{
|
|
float2 d = abs(uvDistorted - VignetteCenter) * VignetteIntensity;
|
|
d.x *= lerp(1.0, _ScreenSize.x / _ScreenSize.y, VignetteRounded);
|
|
d = pow(saturate(d), VignetteRoundness);
|
|
float vfactor = pow(saturate(1.0 - dot(d, d)), VignetteSmoothness);
|
|
color.xyz *= lerp(VignetteColor, (1.0).xxx, vfactor);
|
|
}
|
|
else // Masked
|
|
{
|
|
float vfactor = SAMPLE_TEXTURE2D_LOD(_VignetteMask, sampler_VignetteMask, uvDistorted, 0).w;
|
|
vfactor = FastSRGBToLinear(vfactor);
|
|
float3 newColor = color.xyz * lerp(VignetteColor, (1.0).xxx, vfactor);
|
|
color.xyz = lerp(color.xyz, newColor, VignetteOpacity);
|
|
}
|
|
|
|
#endif
|
|
|
|
// Grading, tonemapping
|
|
// The branch is only used for frame settings & exr log export - else grading is always enabled
|
|
UNITY_BRANCH
|
|
if (OutputLogEnabled)
|
|
{
|
|
// Output in log space for debug & exr export (external grading)
|
|
color.xyz = saturate(LinearToLogC(color.xyz));
|
|
}
|
|
else
|
|
{
|
|
// Artist request to fine tune exposure in post without affecting bloom, dof etc
|
|
color.xyz *= PostExposure;
|
|
|
|
// Move from linear to LogC
|
|
float3 colorLutSpace = saturate(LinearToLogC(color.xyz));
|
|
|
|
// Color lookup in the LogC lut
|
|
color.xyz = ApplyLut3D(TEXTURE3D_ARGS(_LogLut3D, sampler_LogLut3D), colorLutSpace, _LogLut3D_Params.xy);
|
|
}
|
|
|
|
// Alpha mask
|
|
#ifdef ENABLE_ALPHA
|
|
// Post processing is not applied on pixels with zero alpha
|
|
// The alpha scale and bias control how steep is the transition between the post-processed and plain regions
|
|
float alpha = inputColor.a * AlphaScale + AlphaBias;
|
|
// Saturate is necessary to avoid issues when additive blending pushes the alpha over 1.
|
|
color.xyz = lerp(inputColor.xyz, color.xyz, saturate(alpha));
|
|
#endif
|
|
|
|
// Done
|
|
_OutputTexture[COORD_TEXTURE2D_X(posInputs.positionSS)] = color;
|
|
}
|