This commit is contained in:
2021-06-13 10:28:03 +02:00
parent eb70603c85
commit df2d24cbd3
7487 changed files with 943244 additions and 0 deletions

View File

@@ -0,0 +1,214 @@
Shader "Hidden/Universal Render Pipeline/Bloom"
{
HLSLINCLUDE
#pragma exclude_renderers gles
#pragma multi_compile_local _ _USE_RGBM
#pragma multi_compile _ _USE_DRAW_PROCEDURAL
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Filtering.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/PostProcessing/Common.hlsl"
TEXTURE2D_X(_SourceTex);
float4 _SourceTex_TexelSize;
TEXTURE2D_X(_SourceTexLowMip);
float4 _SourceTexLowMip_TexelSize;
float4 _Params; // x: scatter, y: clamp, z: threshold (linear), w: threshold knee
#define Scatter _Params.x
#define ClampMax _Params.y
#define Threshold _Params.z
#define ThresholdKnee _Params.w
half4 EncodeHDR(half3 color)
{
#if _USE_RGBM
half4 outColor = EncodeRGBM(color);
#else
half4 outColor = half4(color, 1.0);
#endif
#if UNITY_COLORSPACE_GAMMA
return half4(sqrt(outColor.xyz), outColor.w); // linear to γ
#else
return outColor;
#endif
}
half3 DecodeHDR(half4 color)
{
#if UNITY_COLORSPACE_GAMMA
color.xyz *= color.xyz; // γ to linear
#endif
#if _USE_RGBM
return DecodeRGBM(color);
#else
return color.xyz;
#endif
}
half4 FragPrefilter(Varyings input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
float2 uv = UnityStereoTransformScreenSpaceTex(input.uv);
#if _BLOOM_HQ
float texelSize = _SourceTex_TexelSize.x;
half4 A = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv + texelSize * float2(-1.0, -1.0));
half4 B = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv + texelSize * float2(0.0, -1.0));
half4 C = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv + texelSize * float2(1.0, -1.0));
half4 D = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv + texelSize * float2(-0.5, -0.5));
half4 E = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv + texelSize * float2(0.5, -0.5));
half4 F = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv + texelSize * float2(-1.0, 0.0));
half4 G = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv);
half4 H = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv + texelSize * float2(1.0, 0.0));
half4 I = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv + texelSize * float2(-0.5, 0.5));
half4 J = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv + texelSize * float2(0.5, 0.5));
half4 K = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv + texelSize * float2(-1.0, 1.0));
half4 L = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv + texelSize * float2(0.0, 1.0));
half4 M = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv + texelSize * float2(1.0, 1.0));
half2 div = (1.0 / 4.0) * half2(0.5, 0.125);
half4 o = (D + E + I + J) * div.x;
o += (A + B + G + F) * div.y;
o += (B + C + H + G) * div.y;
o += (F + G + L + K) * div.y;
o += (G + H + M + L) * div.y;
half3 color = o.xyz;
#else
half3 color = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv).xyz;
#endif
// User controlled clamp to limit crazy high broken spec
color = min(ClampMax, color);
// Thresholding
half brightness = Max3(color.r, color.g, color.b);
half softness = clamp(brightness - Threshold + ThresholdKnee, 0.0, 2.0 * ThresholdKnee);
softness = (softness * softness) / (4.0 * ThresholdKnee + 1e-4);
half multiplier = max(brightness - Threshold, softness) / max(brightness, 1e-4);
color *= multiplier;
return EncodeHDR(color);
}
half4 FragBlurH(Varyings input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
float texelSize = _SourceTex_TexelSize.x * 2.0;
float2 uv = UnityStereoTransformScreenSpaceTex(input.uv);
// 9-tap gaussian blur on the downsampled source
half3 c0 = DecodeHDR(SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv - float2(texelSize * 4.0, 0.0)));
half3 c1 = DecodeHDR(SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv - float2(texelSize * 3.0, 0.0)));
half3 c2 = DecodeHDR(SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv - float2(texelSize * 2.0, 0.0)));
half3 c3 = DecodeHDR(SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv - float2(texelSize * 1.0, 0.0)));
half3 c4 = DecodeHDR(SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv ));
half3 c5 = DecodeHDR(SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv + float2(texelSize * 1.0, 0.0)));
half3 c6 = DecodeHDR(SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv + float2(texelSize * 2.0, 0.0)));
half3 c7 = DecodeHDR(SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv + float2(texelSize * 3.0, 0.0)));
half3 c8 = DecodeHDR(SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv + float2(texelSize * 4.0, 0.0)));
half3 color = c0 * 0.01621622 + c1 * 0.05405405 + c2 * 0.12162162 + c3 * 0.19459459
+ c4 * 0.22702703
+ c5 * 0.19459459 + c6 * 0.12162162 + c7 * 0.05405405 + c8 * 0.01621622;
return EncodeHDR(color);
}
half4 FragBlurV(Varyings input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
float texelSize = _SourceTex_TexelSize.y;
float2 uv = UnityStereoTransformScreenSpaceTex(input.uv);
// Optimized bilinear 5-tap gaussian on the same-sized source (9-tap equivalent)
half3 c0 = DecodeHDR(SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv - float2(0.0, texelSize * 3.23076923)));
half3 c1 = DecodeHDR(SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv - float2(0.0, texelSize * 1.38461538)));
half3 c2 = DecodeHDR(SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv ));
half3 c3 = DecodeHDR(SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv + float2(0.0, texelSize * 1.38461538)));
half3 c4 = DecodeHDR(SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv + float2(0.0, texelSize * 3.23076923)));
half3 color = c0 * 0.07027027 + c1 * 0.31621622
+ c2 * 0.22702703
+ c3 * 0.31621622 + c4 * 0.07027027;
return EncodeHDR(color);
}
half3 Upsample(float2 uv)
{
half3 highMip = DecodeHDR(SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv));
#if _BLOOM_HQ && !defined(SHADER_API_GLES)
half3 lowMip = DecodeHDR(SampleTexture2DBicubic(TEXTURE2D_X_ARGS(_SourceTexLowMip, sampler_LinearClamp), uv, _SourceTexLowMip_TexelSize.zwxy, (1.0).xx, unity_StereoEyeIndex));
#else
half3 lowMip = DecodeHDR(SAMPLE_TEXTURE2D_X(_SourceTexLowMip, sampler_LinearClamp, uv));
#endif
return lerp(highMip, lowMip, Scatter);
}
half4 FragUpsample(Varyings input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
half3 color = Upsample(UnityStereoTransformScreenSpaceTex(input.uv));
return EncodeHDR(color);
}
ENDHLSL
SubShader
{
Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline"}
LOD 100
ZTest Always ZWrite Off Cull Off
Pass
{
Name "Bloom Prefilter"
HLSLPROGRAM
#pragma vertex FullscreenVert
#pragma fragment FragPrefilter
#pragma multi_compile_local _ _BLOOM_HQ
ENDHLSL
}
Pass
{
Name "Bloom Blur Horizontal"
HLSLPROGRAM
#pragma vertex FullscreenVert
#pragma fragment FragBlurH
ENDHLSL
}
Pass
{
Name "Bloom Blur Vertical"
HLSLPROGRAM
#pragma vertex FullscreenVert
#pragma fragment FragBlurV
ENDHLSL
}
Pass
{
Name "Bloom Upsample"
HLSLPROGRAM
#pragma vertex FullscreenVert
#pragma fragment FragUpsample
#pragma multi_compile_local _ _BLOOM_HQ
ENDHLSL
}
}
}

View File

@@ -0,0 +1,356 @@
Shader "Hidden/Universal Render Pipeline/BokehDepthOfField"
{
HLSLINCLUDE
#pragma exclude_renderers gles
#pragma multi_compile_local_fragment _ _USE_FAST_SRGB_LINEAR_CONVERSION
#pragma multi_compile _ _USE_DRAW_PROCEDURAL
#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.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/PostProcessing/Common.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl"
// Do not change this without changing PostProcessPass.PrepareBokehKernel()
#define SAMPLE_COUNT 42
// Toggle this to reduce flickering - note that it will reduce overall bokeh energy and add
// a small cost to the pre-filtering pass
#define COC_LUMA_WEIGHTING 0
TEXTURE2D_X(_SourceTex);
TEXTURE2D_X(_DofTexture);
TEXTURE2D_X(_FullCoCTexture);
float4 _SourceSize;
float4 _HalfSourceSize;
float4 _DownSampleScaleFactor;
float4 _CoCParams;
float4 _BokehKernel[SAMPLE_COUNT];
#define FocusDist _CoCParams.x
#define MaxCoC _CoCParams.y
#define MaxRadius _CoCParams.z
#define RcpAspect _CoCParams.w
half FragCoC(Varyings input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
float2 uv = UnityStereoTransformScreenSpaceTex(input.uv);
float depth = LOAD_TEXTURE2D_X(_CameraDepthTexture, _SourceSize.xy * uv).x;
float linearEyeDepth = LinearEyeDepth(depth, _ZBufferParams);
half coc = (1.0 - FocusDist / linearEyeDepth) * MaxCoC;
half nearCoC = clamp(coc, -1.0, 0.0);
half farCoC = saturate(coc);
return saturate((farCoC + nearCoC + 1.0) * 0.5);
}
half4 FragPrefilter(Varyings input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
float2 uv = UnityStereoTransformScreenSpaceTex(input.uv);
#if SHADER_TARGET >= 45 && defined(PLATFORM_SUPPORT_GATHER)
// Sample source colors
half4 cr = GATHER_RED_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv);
half4 cg = GATHER_GREEN_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv);
half4 cb = GATHER_BLUE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv);
half3 c0 = half3(cr.x, cg.x, cb.x);
half3 c1 = half3(cr.y, cg.y, cb.y);
half3 c2 = half3(cr.z, cg.z, cb.z);
half3 c3 = half3(cr.w, cg.w, cb.w);
// Sample CoCs
half4 cocs = GATHER_TEXTURE2D_X(_FullCoCTexture, sampler_LinearClamp, uv) * 2.0 - 1.0;
half coc0 = cocs.x;
half coc1 = cocs.y;
half coc2 = cocs.z;
half coc3 = cocs.w;
#else
float3 duv = _SourceSize.zwz * float3(0.5, 0.5, -0.5);
float2 uv0 = uv - duv.xy;
float2 uv1 = uv - duv.zy;
float2 uv2 = uv + duv.zy;
float2 uv3 = uv + duv.xy;
// Sample source colors
half3 c0 = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv0).xyz;
half3 c1 = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv1).xyz;
half3 c2 = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv2).xyz;
half3 c3 = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv3).xyz;
// Sample CoCs
half coc0 = SAMPLE_TEXTURE2D_X(_FullCoCTexture, sampler_LinearClamp, uv0).x * 2.0 - 1.0;
half coc1 = SAMPLE_TEXTURE2D_X(_FullCoCTexture, sampler_LinearClamp, uv1).x * 2.0 - 1.0;
half coc2 = SAMPLE_TEXTURE2D_X(_FullCoCTexture, sampler_LinearClamp, uv2).x * 2.0 - 1.0;
half coc3 = SAMPLE_TEXTURE2D_X(_FullCoCTexture, sampler_LinearClamp, uv3).x * 2.0 - 1.0;
#endif
#if COC_LUMA_WEIGHTING
// Apply CoC and luma weights to reduce bleeding and flickering
half w0 = abs(coc0) / (Max3(c0.x, c0.y, c0.z) + 1.0);
half w1 = abs(coc1) / (Max3(c1.x, c1.y, c1.z) + 1.0);
half w2 = abs(coc2) / (Max3(c2.x, c2.y, c2.z) + 1.0);
half w3 = abs(coc3) / (Max3(c3.x, c3.y, c3.z) + 1.0);
// Weighted average of the color samples
half3 avg = c0 * w0 + c1 * w1 + c2 * w2 + c3 * w3;
avg /= max(w0 + w1 + w2 + w3, 1e-5);
#else
half3 avg = (c0 + c1 + c2 + c3) / 4.0;
#endif
// Select the largest CoC value
half cocMin = min(coc0, Min3(coc1, coc2, coc3));
half cocMax = max(coc0, Max3(coc1, coc2, coc3));
half coc = (-cocMin > cocMax ? cocMin : cocMax) * MaxRadius;
// Premultiply CoC
avg *= smoothstep(0, _SourceSize.w * 2.0, abs(coc));
#if defined(UNITY_COLORSPACE_GAMMA)
avg = GetSRGBToLinear(avg);
#endif
return half4(avg, coc);
}
void Accumulate(float4 samp0, float2 uv, float2 disp, inout half4 farAcc, inout half4 nearAcc)
{
float dist = length(disp);
float2 duv = float2(disp.x * RcpAspect, disp.y);
half4 samp = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv + duv);
// Compare CoC of the current sample and the center sample and select smaller one
half farCoC = max(min(samp0.a, samp.a), 0.0);
// Compare the CoC to the sample distance & add a small margin to smooth out
const half margin = _SourceSize.w * _DownSampleScaleFactor.w * 2.0;
half farWeight = saturate((farCoC - dist + margin) / margin);
half nearWeight = saturate((-samp.a - dist + margin) / margin);
// Cut influence from focused areas because they're darkened by CoC premultiplying. This is only
// needed for near field
nearWeight *= step(_SourceSize.w * _DownSampleScaleFactor.w, -samp.a);
// Accumulation
farAcc += half4(samp.rgb, 1.0) * farWeight;
nearAcc += half4(samp.rgb, 1.0) * nearWeight;
}
half4 FragBlur(Varyings input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
float2 uv = UnityStereoTransformScreenSpaceTex(input.uv);
half4 samp0 = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv);
half4 farAcc = 0.0; // Background: far field bokeh
half4 nearAcc = 0.0; // Foreground: near field bokeh
// Center sample isn't in the kernel array, accumulate it separately
Accumulate(samp0, uv, 0.0, farAcc, nearAcc);
UNITY_LOOP
for (int si = 0; si < SAMPLE_COUNT; si++)
{
float2 disp = _BokehKernel[si].xy * MaxRadius;
Accumulate(samp0, uv, disp, farAcc, nearAcc);
}
// Get the weighted average
farAcc.rgb /= farAcc.a + (farAcc.a == 0.0); // Zero-div guard
nearAcc.rgb /= nearAcc.a + (nearAcc.a == 0.0);
// Normalize the total of the weights for the near field
nearAcc.a *= PI / (SAMPLE_COUNT + 1);
// Alpha premultiplying
half alpha = saturate(nearAcc.a);
half3 rgb = lerp(farAcc.rgb, nearAcc.rgb, alpha);
return half4(rgb, alpha);
}
half4 FragPostBlur(Varyings input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
float2 uv = UnityStereoTransformScreenSpaceTex(input.uv);
// 9-tap tent filter with 4 bilinear samples
float4 duv = _SourceSize.zwzw * _DownSampleScaleFactor.zwzw * float4(0.5, 0.5, -0.5, 0);
half4 acc;
acc = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv - duv.xy);
acc += SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv - duv.zy);
acc += SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv + duv.zy);
acc += SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv + duv.xy);
return acc * 0.25;
}
half4 FragComposite(Varyings input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
float2 uv = UnityStereoTransformScreenSpaceTex(input.uv);
half4 dof = SAMPLE_TEXTURE2D_X(_DofTexture, sampler_LinearClamp, uv);
half coc = SAMPLE_TEXTURE2D_X(_FullCoCTexture, sampler_LinearClamp, uv).r;
coc = (coc - 0.5) * 2.0 * MaxRadius;
// Convert CoC to far field alpha value
float ffa = smoothstep(_SourceSize.w * 2.0, _SourceSize.w * 4.0, coc);
half4 color = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv);
#if defined(UNITY_COLORSPACE_GAMMA)
color = GetSRGBToLinear(color);
#endif
half alpha = Max3(dof.r, dof.g, dof.b);
color = lerp(color, half4(dof.rgb, alpha), ffa + dof.a - ffa * dof.a);
#if defined(UNITY_COLORSPACE_GAMMA)
color = GetLinearToSRGB(color);
#endif
return color;
}
ENDHLSL
SubShader
{
Tags { "RenderPipeline" = "UniversalPipeline" }
LOD 100
ZTest Always ZWrite Off Cull Off
Pass
{
Name "Bokeh Depth Of Field CoC"
HLSLPROGRAM
#pragma vertex FullscreenVert
#pragma fragment FragCoC
#pragma target 4.5
ENDHLSL
}
Pass
{
Name "Bokeh Depth Of Field Prefilter"
HLSLPROGRAM
#pragma vertex FullscreenVert
#pragma fragment FragPrefilter
#pragma target 4.5
ENDHLSL
}
Pass
{
Name "Bokeh Depth Of Field Blur"
HLSLPROGRAM
#pragma vertex FullscreenVert
#pragma fragment FragBlur
#pragma target 4.5
ENDHLSL
}
Pass
{
Name "Bokeh Depth Of Field Post Blur"
HLSLPROGRAM
#pragma vertex FullscreenVert
#pragma fragment FragPostBlur
#pragma target 4.5
ENDHLSL
}
Pass
{
Name "Bokeh Depth Of Field Composite"
HLSLPROGRAM
#pragma vertex FullscreenVert
#pragma fragment FragComposite
#pragma target 4.5
ENDHLSL
}
}
// SM3.5 fallbacks - needed because of the use of Gather
SubShader
{
Tags { "RenderPipeline" = "UniversalPipeline" }
LOD 100
ZTest Always ZWrite Off Cull Off
Pass
{
Name "Bokeh Depth Of Field CoC"
HLSLPROGRAM
#pragma vertex FullscreenVert
#pragma fragment FragCoC
#pragma target 3.5
ENDHLSL
}
Pass
{
Name "Bokeh Depth Of Field Prefilter"
HLSLPROGRAM
#pragma vertex FullscreenVert
#pragma fragment FragPrefilter
#pragma target 3.5
ENDHLSL
}
Pass
{
Name "Bokeh Depth Of Field Blur"
HLSLPROGRAM
#pragma vertex FullscreenVert
#pragma fragment FragBlur
#pragma target 3.5
ENDHLSL
}
Pass
{
Name "Bokeh Depth Of Field Post Blur"
HLSLPROGRAM
#pragma vertex FullscreenVert
#pragma fragment FragPostBlur
#pragma target 3.5
ENDHLSL
}
Pass
{
Name "Bokeh Depth Of Field Composite"
HLSLPROGRAM
#pragma vertex FullscreenVert
#pragma fragment FragComposite
#pragma target 3.5
ENDHLSL
}
}
}

View File

@@ -0,0 +1,170 @@
Shader "Hidden/Universal Render Pipeline/CameraMotionBlur"
{
HLSLINCLUDE
#pragma exclude_renderers gles
#pragma multi_compile _ _USE_DRAW_PROCEDURAL
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Random.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/PostProcessing/Common.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl"
TEXTURE2D_X(_SourceTex);
#if defined(USING_STEREO_MATRICES)
float4x4 _PrevViewProjMStereo[2];
#define _PrevViewProjM _PrevViewProjMStereo[unity_StereoEyeIndex]
#define _ViewProjM unity_MatrixVP
#else
float4x4 _ViewProjM;
float4x4 _PrevViewProjM;
#endif
float _Intensity;
float _Clamp;
float4 _SourceSize;
struct VaryingsCMB
{
float4 positionCS : SV_POSITION;
float4 uv : TEXCOORD0;
UNITY_VERTEX_OUTPUT_STEREO
};
VaryingsCMB VertCMB(Attributes input)
{
VaryingsCMB output;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
#if _USE_DRAW_PROCEDURAL
GetProceduralQuad(input.vertexID, output.positionCS, output.uv.xy);
#else
output.positionCS = TransformObjectToHClip(input.positionOS.xyz);
output.uv.xy = input.uv;
#endif
float4 projPos = output.positionCS * 0.5;
projPos.xy = projPos.xy + projPos.w;
output.uv.zw = projPos.xy;
return output;
}
float2 ClampVelocity(float2 velocity, float maxVelocity)
{
float len = length(velocity);
return (len > 0.0) ? min(len, maxVelocity) * (velocity * rcp(len)) : 0.0;
}
// Per-pixel camera velocity
float2 GetCameraVelocity(float4 uv)
{
float depth = SAMPLE_TEXTURE2D_X(_CameraDepthTexture, sampler_PointClamp, uv.xy).r;
#if UNITY_REVERSED_Z
depth = 1.0 - depth;
#endif
depth = 2.0 * depth - 1.0;
float3 viewPos = ComputeViewSpacePosition(uv.zw, depth, unity_CameraInvProjection);
float4 worldPos = float4(mul(unity_CameraToWorld, float4(viewPos, 1.0)).xyz, 1.0);
float4 prevPos = worldPos;
float4 prevClipPos = mul(_PrevViewProjM, prevPos);
float4 curClipPos = mul(_ViewProjM, worldPos);
float2 prevPosCS = prevClipPos.xy / prevClipPos.w;
float2 curPosCS = curClipPos.xy / curClipPos.w;
return ClampVelocity(prevPosCS - curPosCS, _Clamp);
}
float3 GatherSample(float sampleNumber, float2 velocity, float invSampleCount, float2 centerUV, float randomVal, float velocitySign)
{
float offsetLength = (sampleNumber + 0.5) + (velocitySign * (randomVal - 0.5));
float2 sampleUV = centerUV + (offsetLength * invSampleCount) * velocity * velocitySign;
return SAMPLE_TEXTURE2D_X(_SourceTex, sampler_PointClamp, sampleUV).xyz;
}
half4 DoMotionBlur(VaryingsCMB input, int iterations)
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
float2 uv = UnityStereoTransformScreenSpaceTex(input.uv.xy);
float2 velocity = GetCameraVelocity(float4(uv, input.uv.zw)) * _Intensity;
float randomVal = InterleavedGradientNoise(uv * _SourceSize.xy, 0);
float invSampleCount = rcp(iterations * 2.0);
half3 color = 0.0;
UNITY_UNROLL
for (int i = 0; i < iterations; i++)
{
color += GatherSample(i, velocity, invSampleCount, uv, randomVal, -1.0);
color += GatherSample(i, velocity, invSampleCount, uv, randomVal, 1.0);
}
return half4(color * invSampleCount, 1.0);
}
ENDHLSL
SubShader
{
Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline"}
LOD 100
ZTest Always ZWrite Off Cull Off
Pass
{
Name "Camera Motion Blur - Low Quality"
HLSLPROGRAM
#pragma vertex VertCMB
#pragma fragment Frag
half4 Frag(VaryingsCMB input) : SV_Target
{
return DoMotionBlur(input, 2);
}
ENDHLSL
}
Pass
{
Name "Camera Motion Blur - Medium Quality"
HLSLPROGRAM
#pragma vertex VertCMB
#pragma fragment Frag
half4 Frag(VaryingsCMB input) : SV_Target
{
return DoMotionBlur(input, 3);
}
ENDHLSL
}
Pass
{
Name "Camera Motion Blur - High Quality"
HLSLPROGRAM
#pragma vertex VertCMB
#pragma fragment Frag
half4 Frag(VaryingsCMB input) : SV_Target
{
return DoMotionBlur(input, 4);
}
ENDHLSL
}
}
}

View File

@@ -0,0 +1,198 @@
#ifndef UNIVERSAL_POSTPROCESSING_COMMON_INCLUDED
#define UNIVERSAL_POSTPROCESSING_COMMON_INCLUDED
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/Fullscreen.hlsl"
// ----------------------------------------------------------------------------------
// Render fullscreen mesh by using a matrix set directly by the pipeline instead of
// relying on the matrix set by the C++ engine to avoid issues with XR
float4x4 _FullscreenProjMat;
float4 TransformFullscreenMesh(half3 positionOS)
{
return mul(_FullscreenProjMat, half4(positionOS, 1));
}
Varyings VertFullscreenMesh(Attributes input)
{
Varyings output;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
#if _USE_DRAW_PROCEDURAL
GetProceduralQuad(input.vertexID, output.positionCS, output.uv);
#else
output.positionCS = TransformFullscreenMesh(input.positionOS.xyz);
output.uv = input.uv;
#endif
return output;
}
// ----------------------------------------------------------------------------------
// Samplers
SAMPLER(sampler_LinearClamp);
SAMPLER(sampler_LinearRepeat);
SAMPLER(sampler_PointClamp);
SAMPLER(sampler_PointRepeat);
// ----------------------------------------------------------------------------------
// Utility functions
half GetLuminance(half3 colorLinear)
{
#if _TONEMAP_ACES
return AcesLuminance(colorLinear);
#else
return Luminance(colorLinear);
#endif
}
real3 GetSRGBToLinear(real3 c)
{
#if _USE_FAST_SRGB_LINEAR_CONVERSION
return FastSRGBToLinear(c);
#else
return SRGBToLinear(c);
#endif
}
real4 GetSRGBToLinear(real4 c)
{
#if _USE_FAST_SRGB_LINEAR_CONVERSION
return FastSRGBToLinear(c);
#else
return SRGBToLinear(c);
#endif
}
real3 GetLinearToSRGB(real3 c)
{
#if _USE_FAST_SRGB_LINEAR_CONVERSION
return FastLinearToSRGB(c);
#else
return LinearToSRGB(c);
#endif
}
real4 GetLinearToSRGB(real4 c)
{
#if _USE_FAST_SRGB_LINEAR_CONVERSION
return FastLinearToSRGB(c);
#else
return LinearToSRGB(c);
#endif
}
// ----------------------------------------------------------------------------------
// Shared functions for uber & fast path (on-tile)
// These should only process an input color, don't sample in neighbor pixels!
half3 ApplyVignette(half3 input, float2 uv, float2 center, float intensity, float roundness, float smoothness, half3 color)
{
center = UnityStereoTransformScreenSpaceTex(center);
float2 dist = abs(uv - center) * intensity;
#if defined(UNITY_SINGLE_PASS_STEREO)
dist.x /= unity_StereoScaleOffset[unity_StereoEyeIndex].x;
#endif
dist.x *= roundness;
float vfactor = pow(saturate(1.0 - dot(dist, dist)), smoothness);
return input * lerp(color, (1.0).xxx, vfactor);
}
half3 ApplyTonemap(half3 input)
{
#if _TONEMAP_ACES
float3 aces = unity_to_ACES(input);
input = AcesTonemap(aces);
#elif _TONEMAP_NEUTRAL
input = NeutralTonemap(input);
#endif
return saturate(input);
}
half3 ApplyColorGrading(half3 input, float postExposure, TEXTURE2D_PARAM(lutTex, lutSampler), float3 lutParams, TEXTURE2D_PARAM(userLutTex, userLutSampler), float3 userLutParams, float userLutContrib)
{
// Artist request to fine tune exposure in post without affecting bloom, dof etc
input *= postExposure;
// HDR Grading:
// - Apply internal LogC LUT
// - (optional) Clamp result & apply user LUT
#if _HDR_GRADING
{
float3 inputLutSpace = saturate(LinearToLogC(input)); // LUT space is in LogC
input = ApplyLut2D(TEXTURE2D_ARGS(lutTex, lutSampler), inputLutSpace, lutParams);
UNITY_BRANCH
if (userLutContrib > 0.0)
{
input = saturate(input);
input.rgb = GetLinearToSRGB(input.rgb); // In LDR do the lookup in sRGB for the user LUT
half3 outLut = ApplyLut2D(TEXTURE2D_ARGS(userLutTex, userLutSampler), input, userLutParams);
input = lerp(input, outLut, userLutContrib);
input.rgb = GetSRGBToLinear(input.rgb);
}
}
// LDR Grading:
// - Apply tonemapping (result is clamped)
// - (optional) Apply user LUT
// - Apply internal linear LUT
#else
{
input = ApplyTonemap(input);
UNITY_BRANCH
if (userLutContrib > 0.0)
{
input.rgb = GetLinearToSRGB(input.rgb); // In LDR do the lookup in sRGB for the user LUT
half3 outLut = ApplyLut2D(TEXTURE2D_ARGS(userLutTex, userLutSampler), input, userLutParams);
input = lerp(input, outLut, userLutContrib);
input.rgb = GetSRGBToLinear(input.rgb);
}
input = ApplyLut2D(TEXTURE2D_ARGS(lutTex, lutSampler), input, lutParams);
}
#endif
return input;
}
half3 ApplyGrain(half3 input, float2 uv, TEXTURE2D_PARAM(GrainTexture, GrainSampler), float intensity, float response, float2 scale, float2 offset)
{
// Grain in range [0;1] with neutral at 0.5
half grain = SAMPLE_TEXTURE2D(GrainTexture, GrainSampler, uv * scale + offset).w;
// Remap [-1;1]
grain = (grain - 0.5) * 2.0;
// Noisiness response curve based on scene luminance
float lum = 1.0 - sqrt(Luminance(input));
lum = lerp(1.0, lum, response);
return input + input * grain * intensity * lum;
}
half3 ApplyDithering(half3 input, float2 uv, TEXTURE2D_PARAM(BlueNoiseTexture, BlueNoiseSampler), float2 scale, float2 offset)
{
// Symmetric triangular distribution on [-1,1] with maximal density at 0
float noise = SAMPLE_TEXTURE2D(BlueNoiseTexture, BlueNoiseSampler, uv * scale + offset).a * 2.0 - 1.0;
noise = FastSign(noise) * (1.0 - sqrt(1.0 - abs(noise)));
#if UNITY_COLORSPACE_GAMMA
input += noise / 255.0;
#else
input = GetSRGBToLinear(GetLinearToSRGB(input) + noise / 255.0);
#endif
return input;
}
#endif // UNIVERSAL_POSTPROCESSING_COMMON_INCLUDED

View File

@@ -0,0 +1,155 @@
Shader "Hidden/Universal Render Pipeline/FinalPost"
{
HLSLINCLUDE
#pragma exclude_renderers gles
#pragma multi_compile_local_fragment _ _FXAA
#pragma multi_compile_local_fragment _ _FILM_GRAIN
#pragma multi_compile_local_fragment _ _DITHERING
#pragma multi_compile_local_fragment _ _LINEAR_TO_SRGB_CONVERSION
#pragma multi_compile _ _USE_DRAW_PROCEDURAL
#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.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/PostProcessing/Common.hlsl"
TEXTURE2D_X(_SourceTex);
TEXTURE2D(_Grain_Texture);
TEXTURE2D(_BlueNoise_Texture);
float4 _SourceSize;
float2 _Grain_Params;
float4 _Grain_TilingParams;
float4 _Dithering_Params;
#define GrainIntensity _Grain_Params.x
#define GrainResponse _Grain_Params.y
#define GrainScale _Grain_TilingParams.xy
#define GrainOffset _Grain_TilingParams.zw
#define DitheringScale _Dithering_Params.xy
#define DitheringOffset _Dithering_Params.zw
#define FXAA_SPAN_MAX (8.0)
#define FXAA_REDUCE_MUL (1.0 / 8.0)
#define FXAA_REDUCE_MIN (1.0 / 128.0)
half3 Fetch(float2 coords, float2 offset)
{
float2 uv = coords + offset;
return SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv).xyz;
}
half3 Load(int2 icoords, int idx, int idy)
{
#if SHADER_API_GLES
float2 uv = (icoords + int2(idx, idy)) * _SourceSize.zw;
return SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv).xyz;
#else
return LOAD_TEXTURE2D_X(_SourceTex, clamp(icoords + int2(idx, idy), 0, _SourceSize.xy - 1.0)).xyz;
#endif
}
half4 Frag(Varyings input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
float2 uv = UnityStereoTransformScreenSpaceTex(input.uv);
float2 positionNDC = uv;
int2 positionSS = uv * _SourceSize.xy;
half3 color = Load(positionSS, 0, 0).xyz;
#if _FXAA
{
// Edge detection
half3 rgbNW = Load(positionSS, -1, -1);
half3 rgbNE = Load(positionSS, 1, -1);
half3 rgbSW = Load(positionSS, -1, 1);
half3 rgbSE = Load(positionSS, 1, 1);
rgbNW = saturate(rgbNW);
rgbNE = saturate(rgbNE);
rgbSW = saturate(rgbSW);
rgbSE = saturate(rgbSE);
color = saturate(color);
half lumaNW = Luminance(rgbNW);
half lumaNE = Luminance(rgbNE);
half lumaSW = Luminance(rgbSW);
half lumaSE = Luminance(rgbSE);
half lumaM = Luminance(color);
float2 dir;
dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));
dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));
half lumaSum = lumaNW + lumaNE + lumaSW + lumaSE;
float dirReduce = max(lumaSum * (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN);
float rcpDirMin = rcp(min(abs(dir.x), abs(dir.y)) + dirReduce);
dir = min((FXAA_SPAN_MAX).xx, max((-FXAA_SPAN_MAX).xx, dir * rcpDirMin)) * _SourceSize.zw;
// Blur
half3 rgb03 = Fetch(positionNDC, dir * (0.0 / 3.0 - 0.5));
half3 rgb13 = Fetch(positionNDC, dir * (1.0 / 3.0 - 0.5));
half3 rgb23 = Fetch(positionNDC, dir * (2.0 / 3.0 - 0.5));
half3 rgb33 = Fetch(positionNDC, dir * (3.0 / 3.0 - 0.5));
rgb03 = saturate(rgb03);
rgb13 = saturate(rgb13);
rgb23 = saturate(rgb23);
rgb33 = saturate(rgb33);
half3 rgbA = 0.5 * (rgb13 + rgb23);
half3 rgbB = rgbA * 0.5 + 0.25 * (rgb03 + rgb33);
half lumaB = Luminance(rgbB);
half lumaMin = Min3(lumaM, lumaNW, Min3(lumaNE, lumaSW, lumaSE));
half lumaMax = Max3(lumaM, lumaNW, Max3(lumaNE, lumaSW, lumaSE));
color = ((lumaB < lumaMin) || (lumaB > lumaMax)) ? rgbA : rgbB;
}
#endif
#if _FILM_GRAIN
{
color = ApplyGrain(color, positionNDC, TEXTURE2D_ARGS(_Grain_Texture, sampler_LinearRepeat), GrainIntensity, GrainResponse, GrainScale, GrainOffset);
}
#endif
#if _LINEAR_TO_SRGB_CONVERSION
{
color = LinearToSRGB(color);
}
#endif
#if _DITHERING
{
color = ApplyDithering(color, positionNDC, TEXTURE2D_ARGS(_BlueNoise_Texture, sampler_PointRepeat), DitheringScale, DitheringOffset);
}
#endif
return half4(color, 1.0);
}
ENDHLSL
SubShader
{
Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline"}
LOD 100
ZTest Always ZWrite Off Cull Off
Pass
{
Name "FinalPost"
HLSLPROGRAM
#pragma vertex FullscreenVert
#pragma fragment Frag
ENDHLSL
}
}
}

View File

@@ -0,0 +1,267 @@
Shader "Hidden/Universal Render Pipeline/GaussianDepthOfField"
{
HLSLINCLUDE
#pragma target 3.5
#pragma exclude_renderers gles
#pragma multi_compile _ _USE_DRAW_PROCEDURAL
#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.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/PostProcessing/Common.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl"
TEXTURE2D_X(_SourceTex);
TEXTURE2D_X(_ColorTexture);
TEXTURE2D_X(_FullCoCTexture);
TEXTURE2D_X(_HalfCoCTexture);
float4 _SourceSize;
float4 _DownSampleScaleFactor;
float3 _CoCParams;
#define FarStart _CoCParams.x
#define FarEnd _CoCParams.y
#define MaxRadius _CoCParams.z
#define BLUR_KERNEL 0
#if BLUR_KERNEL == 0
// Offsets & coeffs for optimized separable bilinear 3-tap gaussian (5-tap equivalent)
const static int kTapCount = 3;
const static float kOffsets[] = {
-1.33333333,
0.00000000,
1.33333333
};
const static half kCoeffs[] = {
0.35294118,
0.29411765,
0.35294118
};
#elif BLUR_KERNEL == 1
// Offsets & coeffs for optimized separable bilinear 5-tap gaussian (9-tap equivalent)
const static int kTapCount = 5;
const static float kOffsets[] = {
-3.23076923,
-1.38461538,
0.00000000,
1.38461538,
3.23076923
};
const static half kCoeffs[] = {
0.07027027,
0.31621622,
0.22702703,
0.31621622,
0.07027027
};
#endif
half FragCoC(Varyings input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
float2 uv = UnityStereoTransformScreenSpaceTex(input.uv);
float depth = LOAD_TEXTURE2D_X(_CameraDepthTexture, _SourceSize.xy * uv).x;
depth = LinearEyeDepth(depth, _ZBufferParams);
half coc = (depth - FarStart) / (FarEnd - FarStart);
return saturate(coc);
}
struct PrefilterOutput
{
half coc : SV_Target0;
half3 color : SV_Target1;
};
PrefilterOutput FragPrefilter(Varyings input)
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
float2 uv = UnityStereoTransformScreenSpaceTex(input.uv);
#if _HIGH_QUALITY_SAMPLING
// Use a rotated grid to minimize artifacts coming from horizontal and vertical boundaries
// "High Quality Antialiasing" [Lorach07]
const int kCount = 5;
const float2 kTaps[] = {
float2( 0.0, 0.0),
float2( 0.9, -0.4),
float2(-0.9, 0.4),
float2( 0.4, 0.9),
float2(-0.4, -0.9)
};
half3 colorAcc = 0.0;
half farCoCAcc = 0.0;
UNITY_UNROLL
for (int i = 0; i < kCount; i++)
{
float2 tapCoord = _SourceSize.zw * kTaps[i] + uv;
half3 tapColor = SAMPLE_TEXTURE2D_X(_ColorTexture, sampler_LinearClamp, tapCoord).xyz;
half coc = SAMPLE_TEXTURE2D_X(_FullCoCTexture, sampler_LinearClamp, tapCoord).x;
// Pre-multiply CoC to reduce bleeding of background blur on focused areas
colorAcc += tapColor * coc;
farCoCAcc += coc;
}
half3 color = colorAcc * rcp(kCount);
half farCoC = farCoCAcc * rcp(kCount);
#else
// Bilinear sampling the coc is technically incorrect but we're aiming for speed here
half farCoC = SAMPLE_TEXTURE2D_X(_FullCoCTexture, sampler_LinearClamp, uv).x;
// Fast bilinear downscale of the source target and pre-multiply the CoC to reduce
// bleeding of background blur on focused areas
half3 color = SAMPLE_TEXTURE2D_X(_ColorTexture, sampler_LinearClamp, uv).xyz;
color *= farCoC;
#endif
PrefilterOutput o;
o.coc = farCoC;
o.color = color;
return o;
}
half4 Blur(Varyings input, float2 dir, float premultiply)
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
float2 uv = UnityStereoTransformScreenSpaceTex(input.uv);
// Use the center CoC as radius
int2 positionSS = int2(_SourceSize.xy * _DownSampleScaleFactor.xy * uv);
half samp0CoC = LOAD_TEXTURE2D_X(_HalfCoCTexture, positionSS).x;
float2 offset = _SourceSize.zw * _DownSampleScaleFactor.zw * dir * samp0CoC * MaxRadius;
half4 acc = 0.0;
UNITY_UNROLL
for (int i = 0; i < kTapCount; i++)
{
float2 sampCoord = uv + kOffsets[i] * offset;
half sampCoC = SAMPLE_TEXTURE2D_X(_HalfCoCTexture, sampler_LinearClamp, sampCoord).x;
half3 sampColor = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, sampCoord).xyz;
// Weight & pre-multiply to limit bleeding on the focused area
half weight = saturate(1.0 - (samp0CoC - sampCoC));
acc += half4(sampColor, premultiply ? sampCoC : 1.0) * kCoeffs[i] * weight;
}
acc.xyz /= acc.w + 1e-4; // Zero-div guard
return half4(acc.xyz, 1.0);
}
half4 FragBlurH(Varyings input) : SV_Target
{
return Blur(input, float2(1.0, 0.0), 1.0);
}
half4 FragBlurV(Varyings input) : SV_Target
{
return Blur(input, float2(0.0, 1.0), 0.0);
}
half4 FragComposite(Varyings input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
float2 uv = UnityStereoTransformScreenSpaceTex(input.uv);
half3 baseColor = LOAD_TEXTURE2D_X(_SourceTex, _SourceSize.xy * uv).xyz;
half coc = LOAD_TEXTURE2D_X(_FullCoCTexture, _SourceSize.xy * uv).x;
#if _HIGH_QUALITY_SAMPLING && !defined(SHADER_API_GLES)
half3 farColor = SampleTexture2DBicubic(TEXTURE2D_X_ARGS(_ColorTexture, sampler_LinearClamp), uv, _SourceSize * _DownSampleScaleFactor, 1.0, unity_StereoEyeIndex).xyz;
#else
half3 farColor = SAMPLE_TEXTURE2D_X(_ColorTexture, sampler_LinearClamp, uv).xyz;
#endif
half3 dstColor = 0.0;
half dstAlpha = 1.0;
UNITY_BRANCH
if (coc > 0.0)
{
// Non-linear blend
// "CryEngine 3 Graphics Gems" [Sousa13]
half blend = sqrt(coc * TWO_PI);
dstColor = farColor * saturate(blend);
dstAlpha = saturate(1.0 - blend);
}
return half4(baseColor * dstAlpha + dstColor, 1.0);
}
ENDHLSL
SubShader
{
Tags { "RenderPipeline" = "UniversalPipeline" }
LOD 100
ZTest Always ZWrite Off Cull Off
Pass
{
Name "Gaussian Depth Of Field CoC"
HLSLPROGRAM
#pragma vertex FullscreenVert
#pragma fragment FragCoC
ENDHLSL
}
Pass
{
Name "Gaussian Depth Of Field Prefilter"
HLSLPROGRAM
#pragma vertex VertFullscreenMesh
#pragma fragment FragPrefilter
#pragma multi_compile_local _ _HIGH_QUALITY_SAMPLING
ENDHLSL
}
Pass
{
Name "Gaussian Depth Of Field Blur Horizontal"
HLSLPROGRAM
#pragma vertex FullscreenVert
#pragma fragment FragBlurH
ENDHLSL
}
Pass
{
Name "Gaussian Depth Of Field Blur Vertical"
HLSLPROGRAM
#pragma vertex FullscreenVert
#pragma fragment FragBlurV
ENDHLSL
}
Pass
{
Name "Gaussian Depth Of Field Composite"
HLSLPROGRAM
#pragma vertex FullscreenVert
#pragma fragment FragComposite
#pragma multi_compile_local _ _HIGH_QUALITY_SAMPLING
ENDHLSL
}
}
}

View File

@@ -0,0 +1,215 @@
Shader "Hidden/Universal Render Pipeline/LutBuilderHdr"
{
HLSLINCLUDE
#pragma exclude_renderers gles
#pragma multi_compile_local _ _TONEMAP_ACES _TONEMAP_NEUTRAL
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/PostProcessing/Common.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/ACES.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
float4 _Lut_Params; // x: lut_height, y: 0.5 / lut_width, z: 0.5 / lut_height, w: lut_height / lut_height - 1
float4 _ColorBalance; // xyz: LMS coeffs, w: unused
float4 _ColorFilter; // xyz: color, w: unused
float4 _ChannelMixerRed; // xyz: rgb coeffs, w: unused
float4 _ChannelMixerGreen; // xyz: rgb coeffs, w: unused
float4 _ChannelMixerBlue; // xyz: rgb coeffs, w: unused
float4 _HueSatCon; // x: hue shift, y: saturation, z: contrast, w: unused
float4 _Lift; // xyz: color, w: unused
float4 _Gamma; // xyz: color, w: unused
float4 _Gain; // xyz: color, w: unused
float4 _Shadows; // xyz: color, w: unused
float4 _Midtones; // xyz: color, w: unused
float4 _Highlights; // xyz: color, w: unused
float4 _ShaHiLimits; // xy: shadows min/max, zw: highlight min/max
float4 _SplitShadows; // xyz: color, w: balance
float4 _SplitHighlights; // xyz: color, w: unused
TEXTURE2D(_CurveMaster);
TEXTURE2D(_CurveRed);
TEXTURE2D(_CurveGreen);
TEXTURE2D(_CurveBlue);
TEXTURE2D(_CurveHueVsHue);
TEXTURE2D(_CurveHueVsSat);
TEXTURE2D(_CurveSatVsSat);
TEXTURE2D(_CurveLumVsSat);
float EvaluateCurve(TEXTURE2D(curve), float t)
{
float x = SAMPLE_TEXTURE2D(curve, sampler_LinearClamp, float2(t, 0.0)).x;
return saturate(x);
}
// Note: when the ACES tonemapper is selected the grading steps will be done using ACES spaces
float3 ColorGrade(float3 colorLutSpace)
{
// Switch back to linear
float3 colorLinear = LogCToLinear(colorLutSpace);
// White balance in LMS space
float3 colorLMS = LinearToLMS(colorLinear);
colorLMS *= _ColorBalance.xyz;
colorLinear = LMSToLinear(colorLMS);
// Do contrast in log after white balance
#if _TONEMAP_ACES
float3 colorLog = ACES_to_ACEScc(unity_to_ACES(colorLinear));
#else
float3 colorLog = LinearToLogC(colorLinear);
#endif
colorLog = (colorLog - ACEScc_MIDGRAY) * _HueSatCon.z + ACEScc_MIDGRAY;
#if _TONEMAP_ACES
colorLinear = ACES_to_ACEScg(ACEScc_to_ACES(colorLog));
#else
colorLinear = LogCToLinear(colorLog);
#endif
// Color filter is just an unclipped multiplier
colorLinear *= _ColorFilter.xyz;
// Do NOT feed negative values to the following color ops
colorLinear = max(0.0, colorLinear);
// Split toning
// As counter-intuitive as it is, to make split-toning work the same way it does in Adobe
// products we have to do all the maths in gamma-space...
float balance = _SplitShadows.w;
float3 colorGamma = PositivePow(colorLinear, 1.0 / 2.2);
float luma = saturate(GetLuminance(saturate(colorGamma)) + balance);
float3 splitShadows = lerp((0.5).xxx, _SplitShadows.xyz, 1.0 - luma);
float3 splitHighlights = lerp((0.5).xxx, _SplitHighlights.xyz, luma);
colorGamma = SoftLight(colorGamma, splitShadows);
colorGamma = SoftLight(colorGamma, splitHighlights);
colorLinear = PositivePow(colorGamma, 2.2);
// Channel mixing (Adobe style)
colorLinear = float3(
dot(colorLinear, _ChannelMixerRed.xyz),
dot(colorLinear, _ChannelMixerGreen.xyz),
dot(colorLinear, _ChannelMixerBlue.xyz)
);
// Shadows, midtones, highlights
luma = GetLuminance(colorLinear);
float shadowsFactor = 1.0 - smoothstep(_ShaHiLimits.x, _ShaHiLimits.y, luma);
float highlightsFactor = smoothstep(_ShaHiLimits.z, _ShaHiLimits.w, luma);
float midtonesFactor = 1.0 - shadowsFactor - highlightsFactor;
colorLinear = colorLinear * _Shadows.xyz * shadowsFactor
+ colorLinear * _Midtones.xyz * midtonesFactor
+ colorLinear * _Highlights.xyz * highlightsFactor;
// Lift, gamma, gain
colorLinear = colorLinear * _Gain.xyz + _Lift.xyz;
colorLinear = sign(colorLinear) * pow(abs(colorLinear), _Gamma.xyz);
// HSV operations
float satMult;
float3 hsv = RgbToHsv(colorLinear);
{
// Hue Vs Sat
satMult = EvaluateCurve(_CurveHueVsSat, hsv.x) * 2.0;
// Sat Vs Sat
satMult *= EvaluateCurve(_CurveSatVsSat, hsv.y) * 2.0;
// Lum Vs Sat
satMult *= EvaluateCurve(_CurveLumVsSat, Luminance(colorLinear)) * 2.0;
// Hue Shift & Hue Vs Hue
float hue = hsv.x + _HueSatCon.x;
float offset = EvaluateCurve(_CurveHueVsHue, hue) - 0.5;
hue += offset;
hsv.x = RotateHue(hue, 0.0, 1.0);
}
colorLinear = HsvToRgb(hsv);
// Global saturation
luma = GetLuminance(colorLinear);
colorLinear = luma.xxx + (_HueSatCon.yyy * satMult) * (colorLinear - luma.xxx);
// YRGB curves
// Conceptually these need to be in range [0;1] and from an artist-workflow perspective
// it's easier to deal with
colorLinear = FastTonemap(colorLinear);
{
const float kHalfPixel = (1.0 / 128.0) / 2.0;
float3 c = colorLinear;
// Y (master)
c += kHalfPixel.xxx;
float mr = EvaluateCurve(_CurveMaster, c.r);
float mg = EvaluateCurve(_CurveMaster, c.g);
float mb = EvaluateCurve(_CurveMaster, c.b);
c = float3(mr, mg, mb);
// RGB
c += kHalfPixel.xxx;
float r = EvaluateCurve(_CurveRed, c.r);
float g = EvaluateCurve(_CurveGreen, c.g);
float b = EvaluateCurve(_CurveBlue, c.b);
colorLinear = float3(r, g, b);
}
colorLinear = FastTonemapInvert(colorLinear);
colorLinear = max(0.0, colorLinear);
return colorLinear;
}
float3 Tonemap(float3 colorLinear)
{
#if _TONEMAP_NEUTRAL
{
colorLinear = NeutralTonemap(colorLinear);
}
#elif _TONEMAP_ACES
{
// Note: input is actually ACEScg (AP1 w/ linear encoding)
float3 aces = ACEScg_to_ACES(colorLinear);
colorLinear = AcesTonemap(aces);
}
#endif
return colorLinear;
}
float4 Frag(Varyings input) : SV_Target
{
// Lut space
// We use Alexa LogC (El 1000) to store the LUT as it provides a good enough range
// (~58.85666) and is good enough to be stored in fp16 without losing precision in the
// darks
float3 colorLutSpace = GetLutStripValue(input.uv, _Lut_Params);
// Color grade & tonemap
float3 gradedColor = ColorGrade(colorLutSpace);
gradedColor = Tonemap(gradedColor);
return float4(gradedColor, 1.0);
}
ENDHLSL
SubShader
{
Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline"}
LOD 100
ZTest Always ZWrite Off Cull Off
Pass
{
Name "LutBuilderHdr"
HLSLPROGRAM
#pragma vertex FullscreenVert
#pragma fragment Frag
ENDHLSL
}
}
}

View File

@@ -0,0 +1,164 @@
Shader "Hidden/Universal Render Pipeline/LutBuilderLdr"
{
HLSLINCLUDE
#pragma exclude_renderers gles
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/PostProcessing/Common.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
float4 _Lut_Params; // x: lut_height, y: 0.5 / lut_width, z: 0.5 / lut_height, w: lut_height / lut_height - 1
float4 _ColorBalance; // xyz: LMS coeffs, w: unused
half4 _ColorFilter; // xyz: color, w: unused
half4 _ChannelMixerRed; // xyz: rgb coeffs, w: unused
half4 _ChannelMixerGreen; // xyz: rgb coeffs, w: unused
half4 _ChannelMixerBlue; // xyz: rgb coeffs, w: unused
float4 _HueSatCon; // x: hue shift, y: saturation, z: contrast, w: unused
float4 _Lift; // xyz: color, w: unused
float4 _Gamma; // xyz: color, w: unused
float4 _Gain; // xyz: color, w: unused
float4 _Shadows; // xyz: color, w: unused
float4 _Midtones; // xyz: color, w: unused
float4 _Highlights; // xyz: color, w: unused
float4 _ShaHiLimits; // xy: shadows min/max, zw: highlight min/max
half4 _SplitShadows; // xyz: color, w: balance
half4 _SplitHighlights; // xyz: color, w: unused
TEXTURE2D(_CurveMaster);
TEXTURE2D(_CurveRed);
TEXTURE2D(_CurveGreen);
TEXTURE2D(_CurveBlue);
TEXTURE2D(_CurveHueVsHue);
TEXTURE2D(_CurveHueVsSat);
TEXTURE2D(_CurveSatVsSat);
TEXTURE2D(_CurveLumVsSat);
half EvaluateCurve(TEXTURE2D(curve), float t)
{
half x = SAMPLE_TEXTURE2D(curve, sampler_LinearClamp, float2(t, 0.0)).x;
return saturate(x);
}
half4 Frag(Varyings input) : SV_Target
{
float3 colorLinear = GetLutStripValue(input.uv, _Lut_Params);
// White balance in LMS space
float3 colorLMS = LinearToLMS(colorLinear);
colorLMS *= _ColorBalance.xyz;
colorLinear = LMSToLinear(colorLMS);
// Do contrast in log after white balance
float3 colorLog = LinearToLogC(colorLinear);
colorLog = (colorLog - ACEScc_MIDGRAY) * _HueSatCon.z + ACEScc_MIDGRAY;
colorLinear = LogCToLinear(colorLog);
// Color filter is just an unclipped multiplier
colorLinear *= _ColorFilter.xyz;
// Do NOT feed negative values to the following color ops
colorLinear = max(0.0, colorLinear);
// Split toning
// As counter-intuitive as it is, to make split-toning work the same way it does in Adobe
// products we have to do all the maths in gamma-space...
float balance = _SplitShadows.w;
float3 colorGamma = PositivePow(colorLinear, 1.0 / 2.2);
float luma = saturate(GetLuminance(saturate(colorGamma)) + balance);
float3 splitShadows = lerp((0.5).xxx, _SplitShadows.xyz, 1.0 - luma);
float3 splitHighlights = lerp((0.5).xxx, _SplitHighlights.xyz, luma);
colorGamma = SoftLight(colorGamma, splitShadows);
colorGamma = SoftLight(colorGamma, splitHighlights);
colorLinear = PositivePow(colorGamma, 2.2);
// Channel mixing (Adobe style)
colorLinear = float3(
dot(colorLinear, _ChannelMixerRed.xyz),
dot(colorLinear, _ChannelMixerGreen.xyz),
dot(colorLinear, _ChannelMixerBlue.xyz)
);
// Shadows, midtones, highlights
luma = GetLuminance(colorLinear);
float shadowsFactor = 1.0 - smoothstep(_ShaHiLimits.x, _ShaHiLimits.y, luma);
float highlightsFactor = smoothstep(_ShaHiLimits.z, _ShaHiLimits.w, luma);
float midtonesFactor = 1.0 - shadowsFactor - highlightsFactor;
colorLinear = colorLinear * _Shadows.xyz * shadowsFactor
+ colorLinear * _Midtones.xyz * midtonesFactor
+ colorLinear * _Highlights.xyz * highlightsFactor;
// Lift, gamma, gain
colorLinear = colorLinear * _Gain.xyz + _Lift.xyz;
colorLinear = sign(colorLinear) * pow(abs(colorLinear), _Gamma.xyz);
// HSV operations
float satMult;
float3 hsv = RgbToHsv(colorLinear);
{
// Hue Vs Sat
satMult = EvaluateCurve(_CurveHueVsSat, hsv.x) * 2.0;
// Sat Vs Sat
satMult *= EvaluateCurve(_CurveSatVsSat, hsv.y) * 2.0;
// Lum Vs Sat
satMult *= EvaluateCurve(_CurveLumVsSat, Luminance(colorLinear)) * 2.0;
// Hue Shift & Hue Vs Hue
float hue = hsv.x + _HueSatCon.x;
float offset = EvaluateCurve(_CurveHueVsHue, hue) - 0.5;
hue += offset;
hsv.x = RotateHue(hue, 0.0, 1.0);
}
colorLinear = HsvToRgb(hsv);
// Global saturation
luma = GetLuminance(colorLinear);
colorLinear = luma.xxx + (_HueSatCon.yyy * satMult) * (colorLinear - luma.xxx);
// YRGB curves
{
const float kHalfPixel = (1.0 / 128.0) / 2.0;
float3 c = colorLinear;
// Y (master)
c += kHalfPixel.xxx;
float mr = EvaluateCurve(_CurveMaster, c.r);
float mg = EvaluateCurve(_CurveMaster, c.g);
float mb = EvaluateCurve(_CurveMaster, c.b);
c = float3(mr, mg, mb);
// RGB
c += kHalfPixel.xxx;
float r = EvaluateCurve(_CurveRed, c.r);
float g = EvaluateCurve(_CurveGreen, c.g);
float b = EvaluateCurve(_CurveBlue, c.b);
colorLinear = float3(r, g, b);
}
return half4(saturate(colorLinear), 1.0);
}
ENDHLSL
SubShader
{
Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline"}
LOD 100
ZTest Always ZWrite Off Cull Off
Pass
{
Name "LutBuilderLdr"
HLSLPROGRAM
#pragma vertex FullscreenVert
#pragma fragment Frag
ENDHLSL
}
}
}

View File

@@ -0,0 +1,134 @@
Shader "Hidden/Universal Render Pipeline/PaniniProjection"
{
HLSLINCLUDE
#pragma exclude_renderers gles
#pragma multi_compile_local _GENERIC _UNIT_DISTANCE
#pragma multi_compile _ _USE_DRAW_PROCEDURAL
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/PostProcessing/Common.hlsl"
TEXTURE2D_X(_SourceTex);
float4 _Params;
// Back-ported & adapted from the work of the Stockholm demo team - thanks Lasse
float2 Panini_UnitDistance(float2 view_pos)
{
// Given
// S----------- E--X-------
// | ` . /,´
// |-- --- Q
// 1 | ,´/ `
// | ,´ / ´
// | ,´ / `
// | ,´ / .
// O` / .
// | / `
// | / ´
// 1 | / ´
// | / ´
// |/_ . ´
// P
//
// Have E
// Want to find X
//
// First apply tangent-secant theorem to find Q
// PE*QE = SE*SE
// QE = PE-PQ
// PQ = PE-(SE*SE)/PE
// Q = E*(PQ/PE)
// Then project Q to find X
const float d = 1.0;
const float view_dist = 2.0;
const float view_dist_sq = 4.0;
float view_hyp = sqrt(view_pos.x * view_pos.x + view_dist_sq);
float cyl_hyp = view_hyp - (view_pos.x * view_pos.x) / view_hyp;
float cyl_hyp_frac = cyl_hyp / view_hyp;
float cyl_dist = view_dist * cyl_hyp_frac;
float2 cyl_pos = view_pos * cyl_hyp_frac;
return cyl_pos / (cyl_dist - d);
}
float2 Panini_Generic(float2 view_pos, float d)
{
// Given
// S----------- E--X-------
// | ` ~. /,´
// |-- --- Q
// | ,/ `
// 1 | ,´/ `
// | ,´ / ´
// | ,´ / ´
// |,` / ,
// O /
// | / ,
// d | /
// | / ,
// |/ .
// P
// | ´
// | , ´
// +- ´
//
// Have E
// Want to find X
//
// First compute line-circle intersection to find Q
// Then project Q to find X
float view_dist = 1.0 + d;
float view_hyp_sq = view_pos.x * view_pos.x + view_dist * view_dist;
float isect_D = view_pos.x * d;
float isect_discrim = view_hyp_sq - isect_D * isect_D;
float cyl_dist_minus_d = (-isect_D * view_pos.x + view_dist * sqrt(isect_discrim)) / view_hyp_sq;
float cyl_dist = cyl_dist_minus_d + d;
float2 cyl_pos = view_pos * (cyl_dist / view_dist);
return cyl_pos / (cyl_dist - d);
}
half4 Frag(Varyings input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
#if _GENERIC
float2 proj_pos = Panini_Generic((2.0 * input.uv - 1.0) * _Params.xy * _Params.w, _Params.z);
#else // _UNIT_DISTANCE
float2 proj_pos = Panini_UnitDistance((2.0 * input.uv - 1.0) * _Params.xy * _Params.w);
#endif
float2 proj_ndc = proj_pos / _Params.xy;
float2 coords = proj_ndc * 0.5 + 0.5;
return SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, coords);
}
ENDHLSL
SubShader
{
Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline"}
LOD 100
ZTest Always ZWrite Off Cull Off
Pass
{
Name "Panini Projection"
HLSLPROGRAM
#pragma vertex FullscreenVert
#pragma fragment Frag
ENDHLSL
}
}
}

View File

@@ -0,0 +1,45 @@
Shader "Hidden/Universal Render Pipeline/Stop NaN"
{
HLSLINCLUDE
#pragma exclude_renderers gles
#pragma multi_compile _ _USE_DRAW_PROCEDURAL
#pragma exclude_renderers gles
#pragma target 3.5
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/PostProcessing/Common.hlsl"
#define NAN_COLOR half3(0.0, 0.0, 0.0)
TEXTURE2D_X(_SourceTex);
half4 Frag(Varyings input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
half3 color = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_PointClamp, UnityStereoTransformScreenSpaceTex(input.uv)).xyz;
if (AnyIsNaN(color) || AnyIsInf(color))
color = NAN_COLOR;
return half4(color, 1.0);
}
ENDHLSL
SubShader
{
Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline"}
LOD 100
ZTest Always ZWrite Off Cull Off
Pass
{
Name "Stop NaN"
HLSLPROGRAM
#pragma vertex FullscreenVert
#pragma fragment Frag
ENDHLSL
}
}
}

View File

@@ -0,0 +1,74 @@
Shader "Hidden/Universal Render Pipeline/SubpixelMorphologicalAntialiasing"
{
Properties
{
[HideInInspector] _StencilRef ("_StencilRef", Int) = 64
[HideInInspector] _StencilMask ("_StencilMask", Int) = 64
}
HLSLINCLUDE
#pragma multi_compile_local _SMAA_PRESET_LOW _SMAA_PRESET_MEDIUM _SMAA_PRESET_HIGH
#pragma multi_compile _ _USE_DRAW_PROCEDURAL
#pragma exclude_renderers gles
ENDHLSL
SubShader
{
Cull Off ZWrite Off ZTest Always
// Edge detection
Pass
{
Stencil
{
WriteMask [_StencilMask]
Ref [_StencilRef]
Comp Always
Pass Replace
}
HLSLPROGRAM
#pragma vertex VertEdge
#pragma fragment FragEdge
#include "SubpixelMorphologicalAntialiasingBridge.hlsl"
ENDHLSL
}
// Blend Weights Calculation
Pass
{
Stencil
{
WriteMask [_StencilMask]
ReadMask [_StencilMask]
Ref [_StencilRef]
Comp Equal
Pass Replace
}
HLSLPROGRAM
#pragma vertex VertBlend
#pragma fragment FragBlend
#include "SubpixelMorphologicalAntialiasingBridge.hlsl"
ENDHLSL
}
// Neighborhood Blending
Pass
{
HLSLPROGRAM
#pragma vertex VertNeighbor
#pragma fragment FragNeighbor
#include "SubpixelMorphologicalAntialiasingBridge.hlsl"
ENDHLSL
}
}
}

View File

@@ -0,0 +1,136 @@
#ifndef UNIVERSAL_POSTPROCESSING_SMAA_BRIDGE
#define UNIVERSAL_POSTPROCESSING_SMAA_BRIDGE
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/PostProcessing/Common.hlsl"
#define SMAA_HLSL_4_1
#if _SMAA_PRESET_LOW
#define SMAA_PRESET_LOW
#elif _SMAA_PRESET_MEDIUM
#define SMAA_PRESET_MEDIUM
#else
#define SMAA_PRESET_HIGH
#endif
TEXTURE2D_X(_ColorTexture);
TEXTURE2D_X(_BlendTexture);
TEXTURE2D(_AreaTexture);
TEXTURE2D(_SearchTexture);
float4 _Metrics;
#define SMAA_RT_METRICS _Metrics
#define SMAA_AREATEX_SELECT(s) s.rg
#define SMAA_SEARCHTEX_SELECT(s) s.a
#define LinearSampler sampler_LinearClamp
#define PointSampler sampler_PointClamp
#if UNITY_COLORSPACE_GAMMA
#define GAMMA_FOR_EDGE_DETECTION (1)
#else
#define GAMMA_FOR_EDGE_DETECTION (1/2.2)
#endif
#include "Packages/com.unity.render-pipelines.universal/Shaders/PostProcessing/SubpixelMorphologicalAntialiasing.hlsl"
// ----------------------------------------------------------------------------------------
// Edge Detection
struct VaryingsEdge
{
float4 positionCS : SV_POSITION;
float2 uv : TEXCOORD0;
float4 offsets[3] : TEXCOORD1;
UNITY_VERTEX_OUTPUT_STEREO
};
VaryingsEdge VertEdge(Attributes input)
{
VaryingsEdge output;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
#if _USE_DRAW_PROCEDURAL
GetProceduralQuad(input.vertexID, output.positionCS, output.uv);
#else
output.positionCS = TransformFullscreenMesh(input.positionOS.xyz);
output.uv = UnityStereoTransformScreenSpaceTex(input.uv);
#endif
SMAAEdgeDetectionVS(output.uv, output.offsets);
return output;
}
float4 FragEdge(VaryingsEdge input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
return float4(SMAAColorEdgeDetectionPS(input.uv, input.offsets, _ColorTexture), 0.0, 0.0);
}
// ----------------------------------------------------------------------------------------
// Blend Weights Calculation
struct VaryingsBlend
{
float4 positionCS : SV_POSITION;
float2 uv : TEXCOORD0;
float2 pixcoord : TEXCOORD1;
float4 offsets[3] : TEXCOORD2;
UNITY_VERTEX_OUTPUT_STEREO
};
VaryingsBlend VertBlend(Attributes input)
{
VaryingsBlend output;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
#if _USE_DRAW_PROCEDURAL
GetProceduralQuad(input.vertexID, output.positionCS, output.uv);
#else
output.positionCS = TransformFullscreenMesh(input.positionOS.xyz);
output.uv = UnityStereoTransformScreenSpaceTex(input.uv);
#endif
SMAABlendingWeightCalculationVS(output.uv, output.pixcoord, output.offsets);
return output;
}
float4 FragBlend(VaryingsBlend input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
return SMAABlendingWeightCalculationPS(input.uv, input.pixcoord, input.offsets, _ColorTexture, _AreaTexture, _SearchTexture, 0);
}
// ----------------------------------------------------------------------------------------
// Neighborhood Blending
struct VaryingsNeighbor
{
float4 positionCS : SV_POSITION;
float2 uv : TEXCOORD0;
float4 offset : TEXCOORD1;
UNITY_VERTEX_OUTPUT_STEREO
};
VaryingsNeighbor VertNeighbor(Attributes input)
{
VaryingsNeighbor output;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
#if _USE_DRAW_PROCEDURAL
GetProceduralQuad(input.vertexID, output.positionCS, output.uv);
#else
output.positionCS = TransformFullscreenMesh(input.positionOS.xyz);
output.uv = UnityStereoTransformScreenSpaceTex(input.uv);
#endif
SMAANeighborhoodBlendingVS(output.uv, output.offset);
return output;
}
float4 FragNeighbor(VaryingsNeighbor input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
return SMAANeighborhoodBlendingPS(input.uv, input.offset, _ColorTexture, _BlendTexture);
}
#endif // UNIVERSAL_POSTPROCESSING_SMAA_BRIDGE

View File

@@ -0,0 +1,240 @@
Shader "Hidden/Universal Render Pipeline/UberPost"
{
HLSLINCLUDE
#pragma exclude_renderers gles
#pragma multi_compile_local_fragment _ _DISTORTION
#pragma multi_compile_local_fragment _ _CHROMATIC_ABERRATION
#pragma multi_compile_local_fragment _ _BLOOM_LQ _BLOOM_HQ _BLOOM_LQ_DIRT _BLOOM_HQ_DIRT
#pragma multi_compile_local_fragment _ _HDR_GRADING _TONEMAP_ACES _TONEMAP_NEUTRAL
#pragma multi_compile_local_fragment _ _FILM_GRAIN
#pragma multi_compile_local_fragment _ _DITHERING
#pragma multi_compile_local_fragment _ _LINEAR_TO_SRGB_CONVERSION
#pragma multi_compile_local_fragment _ _USE_FAST_SRGB_LINEAR_CONVERSION
#pragma multi_compile _ _USE_DRAW_PROCEDURAL
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Filtering.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/PostProcessing/Common.hlsl"
// Hardcoded dependencies to reduce the number of variants
#if _BLOOM_LQ || _BLOOM_HQ || _BLOOM_LQ_DIRT || _BLOOM_HQ_DIRT
#define BLOOM
#if _BLOOM_LQ_DIRT || _BLOOM_HQ_DIRT
#define BLOOM_DIRT
#endif
#endif
TEXTURE2D_X(_SourceTex);
TEXTURE2D_X(_Bloom_Texture);
TEXTURE2D(_LensDirt_Texture);
TEXTURE2D(_Grain_Texture);
TEXTURE2D(_InternalLut);
TEXTURE2D(_UserLut);
TEXTURE2D(_BlueNoise_Texture);
float4 _Lut_Params;
float4 _UserLut_Params;
float4 _Bloom_Params;
float _Bloom_RGBM;
float4 _LensDirt_Params;
float _LensDirt_Intensity;
float4 _Distortion_Params1;
float4 _Distortion_Params2;
float _Chroma_Params;
half4 _Vignette_Params1;
float4 _Vignette_Params2;
float2 _Grain_Params;
float4 _Grain_TilingParams;
float4 _Bloom_Texture_TexelSize;
float4 _Dithering_Params;
#define DistCenter _Distortion_Params1.xy
#define DistAxis _Distortion_Params1.zw
#define DistTheta _Distortion_Params2.x
#define DistSigma _Distortion_Params2.y
#define DistScale _Distortion_Params2.z
#define DistIntensity _Distortion_Params2.w
#define ChromaAmount _Chroma_Params.x
#define BloomIntensity _Bloom_Params.x
#define BloomTint _Bloom_Params.yzw
#define BloomRGBM _Bloom_RGBM.x
#define LensDirtScale _LensDirt_Params.xy
#define LensDirtOffset _LensDirt_Params.zw
#define LensDirtIntensity _LensDirt_Intensity.x
#define VignetteColor _Vignette_Params1.xyz
#define VignetteCenter _Vignette_Params2.xy
#define VignetteIntensity _Vignette_Params2.z
#define VignetteSmoothness _Vignette_Params2.w
#define VignetteRoundness _Vignette_Params1.w
#define LutParams _Lut_Params.xyz
#define PostExposure _Lut_Params.w
#define UserLutParams _UserLut_Params.xyz
#define UserLutContribution _UserLut_Params.w
#define GrainIntensity _Grain_Params.x
#define GrainResponse _Grain_Params.y
#define GrainScale _Grain_TilingParams.xy
#define GrainOffset _Grain_TilingParams.zw
#define DitheringScale _Dithering_Params.xy
#define DitheringOffset _Dithering_Params.zw
float2 DistortUV(float2 uv)
{
// Note: this variant should never be set with XR
#if _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;
}
half4 Frag(Varyings input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
float2 uv = UnityStereoTransformScreenSpaceTex(input.uv);
float2 uvDistorted = DistortUV(uv);
half3 color = (0.0).xxx;
#if _CHROMATIC_ABERRATION
{
// Very fast version of chromatic aberration from HDRP using 3 samples and hardcoded
// spectral lut. Performs significantly better on lower end GPUs.
float2 coords = 2.0 * uv - 1.0;
float2 end = uv - coords * dot(coords, coords) * ChromaAmount;
float2 delta = (end - uv) / 3.0;
half r = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uvDistorted ).x;
half g = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, DistortUV(delta + uv) ).y;
half b = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, DistortUV(delta * 2.0 + uv)).z;
color = half3(r, g, b);
}
#else
{
color = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uvDistorted).xyz;
}
#endif
// Gamma space... Just do the rest of Uber in linear and convert back to sRGB at the end
#if UNITY_COLORSPACE_GAMMA
{
color = GetSRGBToLinear(color);
}
#endif
#if defined(BLOOM)
{
#if _BLOOM_HQ && !defined(SHADER_API_GLES)
half4 bloom = SampleTexture2DBicubic(TEXTURE2D_X_ARGS(_Bloom_Texture, sampler_LinearClamp), uvDistorted, _Bloom_Texture_TexelSize.zwxy, (1.0).xx, unity_StereoEyeIndex);
#else
half4 bloom = SAMPLE_TEXTURE2D_X(_Bloom_Texture, sampler_LinearClamp, uvDistorted);
#endif
#if UNITY_COLORSPACE_GAMMA
bloom.xyz *= bloom.xyz; // γ to linear
#endif
UNITY_BRANCH
if (BloomRGBM > 0)
{
bloom.xyz = DecodeRGBM(bloom);
}
bloom.xyz *= BloomIntensity;
color += bloom.xyz * BloomTint;
#if defined(BLOOM_DIRT)
{
// 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.
half3 dirt = SAMPLE_TEXTURE2D(_LensDirt_Texture, sampler_LinearClamp, uvDistorted * LensDirtScale + LensDirtOffset).xyz;
dirt *= LensDirtIntensity;
color += dirt * bloom.xyz;
}
#endif
}
#endif
// To save on variants we'll use an uniform branch for vignette. Lower end platforms
// don't like these but if we're running Uber it means we're running more expensive
// effects anyway. Lower-end devices would limit themselves to on-tile compatible effect
// and thus this shouldn't too much of a problem (famous last words).
UNITY_BRANCH
if (VignetteIntensity > 0)
{
color = ApplyVignette(color, uvDistorted, VignetteCenter, VignetteIntensity, VignetteRoundness, VignetteSmoothness, VignetteColor);
}
// Color grading is always enabled when post-processing/uber is active
{
color = ApplyColorGrading(color, PostExposure, TEXTURE2D_ARGS(_InternalLut, sampler_LinearClamp), LutParams, TEXTURE2D_ARGS(_UserLut, sampler_LinearClamp), UserLutParams, UserLutContribution);
}
#if _FILM_GRAIN
{
color = ApplyGrain(color, uv, TEXTURE2D_ARGS(_Grain_Texture, sampler_LinearRepeat), GrainIntensity, GrainResponse, GrainScale, GrainOffset);
}
#endif
// Back to sRGB
#if UNITY_COLORSPACE_GAMMA || _LINEAR_TO_SRGB_CONVERSION
{
color = GetLinearToSRGB(color);
}
#endif
#if _DITHERING
{
color = ApplyDithering(color, uv, TEXTURE2D_ARGS(_BlueNoise_Texture, sampler_PointRepeat), DitheringScale, DitheringOffset);
}
#endif
return half4(color, 1.0);
}
ENDHLSL
SubShader
{
Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline"}
LOD 100
ZTest Always ZWrite Off Cull Off
Pass
{
Name "UberPost"
HLSLPROGRAM
#pragma vertex FullscreenVert
#pragma fragment Frag
ENDHLSL
}
}
}