testss
This commit is contained in:
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
@@ -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
|
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
@@ -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
|
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user