316 lines
12 KiB
Plaintext
316 lines
12 KiB
Plaintext
Shader "Hidden/PostProcessing/Uber"
|
|
{
|
|
HLSLINCLUDE
|
|
|
|
#pragma target 3.0
|
|
|
|
#pragma multi_compile __ DISTORT
|
|
#pragma multi_compile __ CHROMATIC_ABERRATION CHROMATIC_ABERRATION_LOW
|
|
#pragma multi_compile __ BLOOM BLOOM_LOW
|
|
#pragma multi_compile __ VIGNETTE
|
|
#pragma multi_compile __ GRAIN
|
|
#pragma multi_compile __ FINALPASS
|
|
// the following keywords are handled in API specific SubShaders below
|
|
// #pragma multi_compile __ COLOR_GRADING_LDR_2D COLOR_GRADING_HDR_2D COLOR_GRADING_HDR_3D
|
|
// #pragma multi_compile __ STEREO_INSTANCING_ENABLED STEREO_DOUBLEWIDE_TARGET
|
|
|
|
#pragma vertex VertUVTransform
|
|
#pragma fragment FragUber
|
|
|
|
#include "Packages/com.unity.postprocessing/PostProcessing/Shaders/StdLib.hlsl"
|
|
#include "Packages/com.unity.postprocessing/PostProcessing/Shaders/Colors.hlsl"
|
|
#include "Packages/com.unity.postprocessing/PostProcessing/Shaders/Sampling.hlsl"
|
|
#include "Packages/com.unity.postprocessing/PostProcessing/Shaders/Builtins/Distortion.hlsl"
|
|
#include "Packages/com.unity.postprocessing/PostProcessing/Shaders/Builtins/Dithering.hlsl"
|
|
|
|
#define MAX_CHROMATIC_SAMPLES 16
|
|
|
|
TEXTURE2D_SAMPLER2D(_MainTex, sampler_MainTex);
|
|
float4 _MainTex_TexelSize;
|
|
|
|
// Auto exposure / eye adaptation
|
|
TEXTURE2D_SAMPLER2D(_AutoExposureTex, sampler_AutoExposureTex);
|
|
|
|
// Bloom
|
|
TEXTURE2D_SAMPLER2D(_BloomTex, sampler_BloomTex);
|
|
TEXTURE2D_SAMPLER2D(_Bloom_DirtTex, sampler_Bloom_DirtTex);
|
|
float4 _BloomTex_TexelSize;
|
|
float4 _Bloom_DirtTileOffset; // xy: tiling, zw: offset
|
|
half3 _Bloom_Settings; // x: sampleScale, y: intensity, z: dirt intensity
|
|
half3 _Bloom_Color;
|
|
|
|
// Chromatic aberration
|
|
TEXTURE2D_SAMPLER2D(_ChromaticAberration_SpectralLut, sampler_ChromaticAberration_SpectralLut);
|
|
half _ChromaticAberration_Amount;
|
|
|
|
// Color grading
|
|
#if COLOR_GRADING_HDR_3D
|
|
|
|
TEXTURE3D_SAMPLER3D(_Lut3D, sampler_Lut3D);
|
|
float2 _Lut3D_Params;
|
|
|
|
#else
|
|
|
|
TEXTURE2D_SAMPLER2D(_Lut2D, sampler_Lut2D);
|
|
float3 _Lut2D_Params;
|
|
|
|
#endif
|
|
|
|
half _PostExposure; // EV (exp2)
|
|
|
|
// Vignette
|
|
half3 _Vignette_Color;
|
|
half2 _Vignette_Center; // UV space
|
|
half4 _Vignette_Settings; // x: intensity, y: smoothness, z: roundness, w: rounded
|
|
half _Vignette_Opacity;
|
|
half _Vignette_Mode; // <0.5: procedural, >=0.5: masked
|
|
TEXTURE2D_SAMPLER2D(_Vignette_Mask, sampler_Vignette_Mask);
|
|
|
|
// Grain
|
|
TEXTURE2D_SAMPLER2D(_GrainTex, sampler_GrainTex);
|
|
half2 _Grain_Params1; // x: lum_contrib, y: intensity
|
|
float4 _Grain_Params2; // x: xscale, h: yscale, z: xoffset, w: yoffset
|
|
|
|
// Misc
|
|
half _LumaInAlpha;
|
|
|
|
half4 FragUber(VaryingsDefault i) : SV_Target
|
|
{
|
|
float2 uv = i.texcoord;
|
|
|
|
//>>> Automatically skipped by the shader optimizer when not used
|
|
float2 uvDistorted = Distort(i.texcoord);
|
|
float2 uvStereoDistorted = Distort(i.texcoordStereo);
|
|
//<<<
|
|
|
|
half autoExposure = SAMPLE_TEXTURE2D(_AutoExposureTex, sampler_AutoExposureTex, uv).r;
|
|
half4 color = (0.0).xxxx;
|
|
|
|
// Inspired by the method described in "Rendering Inside" [Playdead 2016]
|
|
// https://twitter.com/pixelmager/status/717019757766123520
|
|
#if CHROMATIC_ABERRATION
|
|
{
|
|
float2 coords = 2.0 * uv - 1.0;
|
|
float2 end = uv - coords * dot(coords, coords) * _ChromaticAberration_Amount;
|
|
|
|
float2 diff = end - uv;
|
|
int samples = clamp(int(length(_MainTex_TexelSize.zw * diff / 2.0)), 3, MAX_CHROMATIC_SAMPLES);
|
|
float2 delta = diff / samples;
|
|
float2 pos = uv;
|
|
half4 sum = (0.0).xxxx, filterSum = (0.0).xxxx;
|
|
|
|
for (int i = 0; i < samples; i++)
|
|
{
|
|
half t = (i + 0.5) / samples;
|
|
half4 s = SAMPLE_TEXTURE2D_LOD(_MainTex, sampler_MainTex, UnityStereoTransformScreenSpaceTex(Distort(pos)), 0);
|
|
half4 filter = half4(SAMPLE_TEXTURE2D_LOD(_ChromaticAberration_SpectralLut, sampler_ChromaticAberration_SpectralLut, float2(t, 0.0), 0).rgb, 1.0);
|
|
|
|
sum += s * filter;
|
|
filterSum += filter;
|
|
pos += delta;
|
|
}
|
|
|
|
color = sum / filterSum;
|
|
}
|
|
#elif CHROMATIC_ABERRATION_LOW
|
|
{
|
|
float2 coords = 2.0 * uv - 1.0;
|
|
float2 end = uv - coords * dot(coords, coords) * _ChromaticAberration_Amount;
|
|
float2 delta = (end - uv) / 3;
|
|
|
|
half4 filterA = half4(SAMPLE_TEXTURE2D_LOD(_ChromaticAberration_SpectralLut, sampler_ChromaticAberration_SpectralLut, float2(0.5 / 3, 0.0), 0).rgb, 1.0);
|
|
half4 filterB = half4(SAMPLE_TEXTURE2D_LOD(_ChromaticAberration_SpectralLut, sampler_ChromaticAberration_SpectralLut, float2(1.5 / 3, 0.0), 0).rgb, 1.0);
|
|
half4 filterC = half4(SAMPLE_TEXTURE2D_LOD(_ChromaticAberration_SpectralLut, sampler_ChromaticAberration_SpectralLut, float2(2.5 / 3, 0.0), 0).rgb, 1.0);
|
|
|
|
half4 texelA = SAMPLE_TEXTURE2D_LOD(_MainTex, sampler_MainTex, UnityStereoTransformScreenSpaceTex(Distort(uv)), 0);
|
|
half4 texelB = SAMPLE_TEXTURE2D_LOD(_MainTex, sampler_MainTex, UnityStereoTransformScreenSpaceTex(Distort(delta + uv)), 0);
|
|
half4 texelC = SAMPLE_TEXTURE2D_LOD(_MainTex, sampler_MainTex, UnityStereoTransformScreenSpaceTex(Distort(delta * 2.0 + uv)), 0);
|
|
|
|
half4 sum = texelA * filterA + texelB * filterB + texelC * filterC;
|
|
half4 filterSum = filterA + filterB + filterC;
|
|
color = sum / filterSum;
|
|
}
|
|
#else
|
|
{
|
|
color = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uvStereoDistorted);
|
|
}
|
|
#endif
|
|
|
|
// Gamma space... Gah.
|
|
#if UNITY_COLORSPACE_GAMMA
|
|
{
|
|
color = SRGBToLinear(color);
|
|
}
|
|
#endif
|
|
|
|
color.rgb *= autoExposure;
|
|
|
|
#if BLOOM || BLOOM_LOW
|
|
{
|
|
#if BLOOM
|
|
half4 bloom = UpsampleTent(TEXTURE2D_PARAM(_BloomTex, sampler_BloomTex), uvDistorted, _BloomTex_TexelSize.xy, _Bloom_Settings.x);
|
|
#else
|
|
half4 bloom = UpsampleBox(TEXTURE2D_PARAM(_BloomTex, sampler_BloomTex), uvDistorted, _BloomTex_TexelSize.xy, _Bloom_Settings.x);
|
|
#endif
|
|
|
|
// UVs should be Distort(uv * _Bloom_DirtTileOffset.xy + _Bloom_DirtTileOffset.zw)
|
|
// 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
|
|
half4 dirt = half4(SAMPLE_TEXTURE2D(_Bloom_DirtTex, sampler_Bloom_DirtTex, uvDistorted * _Bloom_DirtTileOffset.xy + _Bloom_DirtTileOffset.zw).rgb, 0.0);
|
|
|
|
// Additive bloom (artist friendly)
|
|
bloom *= _Bloom_Settings.y;
|
|
dirt *= _Bloom_Settings.z;
|
|
color += bloom * half4(_Bloom_Color, 1.0);
|
|
color += dirt * bloom;
|
|
}
|
|
#endif
|
|
|
|
#if VIGNETTE
|
|
{
|
|
UNITY_BRANCH
|
|
if (_Vignette_Mode < 0.5)
|
|
{
|
|
half2 d = abs(uvDistorted - _Vignette_Center) * _Vignette_Settings.x;
|
|
d.x *= lerp(1.0, _ScreenParams.x / _ScreenParams.y, _Vignette_Settings.w);
|
|
d = pow(saturate(d), _Vignette_Settings.z); // Roundness
|
|
half vfactor = pow(saturate(1.0 - dot(d, d)), _Vignette_Settings.y);
|
|
color.rgb *= lerp(_Vignette_Color, (1.0).xxx, vfactor);
|
|
color.a = lerp(1.0, color.a, vfactor);
|
|
}
|
|
else
|
|
{
|
|
half vfactor = SAMPLE_TEXTURE2D(_Vignette_Mask, sampler_Vignette_Mask, uvDistorted).a;
|
|
|
|
#if !UNITY_COLORSPACE_GAMMA
|
|
{
|
|
vfactor = SRGBToLinear(vfactor);
|
|
}
|
|
#endif
|
|
|
|
half3 new_color = color.rgb * lerp(_Vignette_Color, (1.0).xxx, vfactor);
|
|
color.rgb = lerp(color.rgb, new_color, _Vignette_Opacity);
|
|
color.a = lerp(1.0, color.a, vfactor);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#if GRAIN
|
|
{
|
|
half3 grain = SAMPLE_TEXTURE2D(_GrainTex, sampler_GrainTex, i.texcoordStereo * _Grain_Params2.xy + _Grain_Params2.zw).rgb;
|
|
|
|
// Noisiness response curve based on scene luminance
|
|
float lum = 1.0 - sqrt(Luminance(saturate(color)));
|
|
lum = lerp(1.0, lum, _Grain_Params1.x);
|
|
|
|
color.rgb += color.rgb * grain * _Grain_Params1.y * lum;
|
|
}
|
|
#endif
|
|
|
|
#if COLOR_GRADING_HDR_3D
|
|
{
|
|
color *= _PostExposure;
|
|
float3 colorLutSpace = saturate(LUT_SPACE_ENCODE(color.rgb));
|
|
color.rgb = ApplyLut3D(TEXTURE3D_PARAM(_Lut3D, sampler_Lut3D), colorLutSpace, _Lut3D_Params);
|
|
}
|
|
#elif COLOR_GRADING_HDR_2D
|
|
{
|
|
color *= _PostExposure;
|
|
float3 colorLutSpace = saturate(LUT_SPACE_ENCODE(color.rgb));
|
|
color.rgb = ApplyLut2D(TEXTURE2D_PARAM(_Lut2D, sampler_Lut2D), colorLutSpace, _Lut2D_Params);
|
|
}
|
|
#elif COLOR_GRADING_LDR_2D
|
|
{
|
|
color = saturate(color);
|
|
|
|
// LDR Lut lookup needs to be in sRGB - for HDR stick to linear
|
|
color.rgb = LinearToSRGB(color.rgb);
|
|
color.rgb = ApplyLut2D(TEXTURE2D_PARAM(_Lut2D, sampler_Lut2D), color.rgb, _Lut2D_Params);
|
|
color.rgb = SRGBToLinear(color.rgb);
|
|
}
|
|
#endif
|
|
|
|
half4 output = color;
|
|
|
|
#if FINALPASS
|
|
{
|
|
#if UNITY_COLORSPACE_GAMMA
|
|
{
|
|
output = LinearToSRGB(output);
|
|
}
|
|
#endif
|
|
|
|
output.rgb = Dither(output.rgb, i.texcoord);
|
|
}
|
|
#else
|
|
{
|
|
UNITY_BRANCH
|
|
if (_LumaInAlpha > 0.5)
|
|
{
|
|
// Put saturated luma in alpha for FXAA - higher quality than "green as luma" and
|
|
// necessary as RGB values will potentially still be HDR for the FXAA pass
|
|
half luma = Luminance(saturate(output));
|
|
output.a = luma;
|
|
}
|
|
|
|
#if UNITY_COLORSPACE_GAMMA
|
|
{
|
|
output = LinearToSRGB(output);
|
|
}
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
// Output RGB is still HDR at that point (unless range was crunched by a tonemapper)
|
|
return output;
|
|
}
|
|
|
|
ENDHLSL
|
|
|
|
SubShader
|
|
{
|
|
Cull Off ZWrite Off ZTest Always
|
|
|
|
Pass
|
|
{
|
|
HLSLPROGRAM
|
|
#pragma exclude_renderers gles vulkan webgpu switch
|
|
|
|
#pragma multi_compile __ COLOR_GRADING_LDR_2D COLOR_GRADING_HDR_2D COLOR_GRADING_HDR_3D
|
|
#pragma multi_compile __ STEREO_INSTANCING_ENABLED STEREO_DOUBLEWIDE_TARGET
|
|
ENDHLSL
|
|
}
|
|
}
|
|
|
|
SubShader
|
|
{
|
|
Cull Off ZWrite Off ZTest Always
|
|
|
|
Pass
|
|
{
|
|
HLSLPROGRAM
|
|
#pragma only_renderers vulkan webgpu switch
|
|
|
|
#pragma multi_compile __ COLOR_GRADING_LDR_2D COLOR_GRADING_HDR_2D COLOR_GRADING_HDR_3D
|
|
#pragma multi_compile __ STEREO_DOUBLEWIDE_TARGET // disabled for Vulkan because of shader compiler issues in older Unity versions: STEREO_INSTANCING_ENABLED
|
|
ENDHLSL
|
|
}
|
|
}
|
|
|
|
SubShader
|
|
{
|
|
Cull Off ZWrite Off ZTest Always
|
|
|
|
Pass
|
|
{
|
|
HLSLPROGRAM
|
|
#pragma only_renderers gles
|
|
|
|
#pragma multi_compile __ COLOR_GRADING_LDR_2D COLOR_GRADING_HDR_2D // not supported by OpenGL ES 2.0: COLOR_GRADING_HDR_3D
|
|
#pragma multi_compile __ STEREO_DOUBLEWIDE_TARGET // not supported by OpenGL ES 2.0: STEREO_INSTANCING_ENABLED
|
|
ENDHLSL
|
|
}
|
|
}
|
|
}
|