1 Shader "Hidden/PostProcessing/Uber"
7 #pragma multi_compile __ DISTORT
8 #pragma multi_compile __ CHROMATIC_ABERRATION CHROMATIC_ABERRATION_LOW
9 #pragma multi_compile __ BLOOM BLOOM_LOW
10 #pragma multi_compile __ VIGNETTE
11 #pragma multi_compile __ GRAIN
12 #pragma multi_compile __ FINALPASS
13 // the following keywords are handled in API specific SubShaders below
14 // #pragma multi_compile __ COLOR_GRADING_LDR_2D COLOR_GRADING_HDR_2D COLOR_GRADING_HDR_3D
15 // #pragma multi_compile __ STEREO_INSTANCING_ENABLED STEREO_DOUBLEWIDE_TARGET
17 #pragma vertex VertUVTransform
18 #pragma fragment FragUber
20 #include "../StdLib.hlsl"
21 #include "../Colors.hlsl"
22 #include "../Sampling.hlsl"
23 #include "Distortion.hlsl"
24 #include "Dithering.hlsl"
26 #define MAX_CHROMATIC_SAMPLES 16
28 TEXTURE2D_SAMPLER2D(_MainTex, sampler_MainTex);
29 float4 _MainTex_TexelSize;
31 // Auto exposure / eye adaptation
32 TEXTURE2D_SAMPLER2D(_AutoExposureTex, sampler_AutoExposureTex);
35 TEXTURE2D_SAMPLER2D(_BloomTex, sampler_BloomTex);
36 TEXTURE2D_SAMPLER2D(_Bloom_DirtTex, sampler_Bloom_DirtTex);
37 float4 _BloomTex_TexelSize;
38 float4 _Bloom_DirtTileOffset; // xy: tiling, zw: offset
39 half3 _Bloom_Settings; // x: sampleScale, y: intensity, z: dirt intensity
42 // Chromatic aberration
43 TEXTURE2D_SAMPLER2D(_ChromaticAberration_SpectralLut, sampler_ChromaticAberration_SpectralLut);
44 half _ChromaticAberration_Amount;
47 #if COLOR_GRADING_HDR_3D
49 TEXTURE3D_SAMPLER3D(_Lut3D, sampler_Lut3D);
54 TEXTURE2D_SAMPLER2D(_Lut2D, sampler_Lut2D);
59 half _PostExposure; // EV (exp2)
62 half3 _Vignette_Color;
63 half2 _Vignette_Center; // UV space
64 half4 _Vignette_Settings; // x: intensity, y: smoothness, z: roundness, w: rounded
65 half _Vignette_Opacity;
66 half _Vignette_Mode; // <0.5: procedural, >=0.5: masked
67 TEXTURE2D_SAMPLER2D(_Vignette_Mask, sampler_Vignette_Mask);
70 TEXTURE2D_SAMPLER2D(_GrainTex, sampler_GrainTex);
71 half2 _Grain_Params1; // x: lum_contrib, y: intensity
72 float4 _Grain_Params2; // x: xscale, h: yscale, z: xoffset, w: yoffset
77 half4 FragUber(VaryingsDefault i) : SV_Target
79 float2 uv = i.texcoord;
81 //>>> Automatically skipped by the shader optimizer when not used
82 float2 uvDistorted = Distort(i.texcoord);
83 float2 uvStereoDistorted = Distort(i.texcoordStereo);
86 half autoExposure = SAMPLE_TEXTURE2D(_AutoExposureTex, sampler_AutoExposureTex, uv).r;
87 half4 color = (0.0).xxxx;
89 // Inspired by the method described in "Rendering Inside" [Playdead 2016]
90 // https://twitter.com/pixelmager/status/717019757766123520
91 #if CHROMATIC_ABERRATION
93 float2 coords = 2.0 * uv - 1.0;
94 float2 end = uv - coords * dot(coords, coords) * _ChromaticAberration_Amount;
96 float2 diff = end - uv;
97 int samples = clamp(int(length(_MainTex_TexelSize.zw * diff / 2.0)), 3, MAX_CHROMATIC_SAMPLES);
98 float2 delta = diff / samples;
100 half4 sum = (0.0).xxxx, filterSum = (0.0).xxxx;
102 for (int i = 0; i < samples; i++)
104 half t = (i + 0.5) / samples;
105 half4 s = SAMPLE_TEXTURE2D_LOD(_MainTex, sampler_MainTex, UnityStereoTransformScreenSpaceTex(Distort(pos)), 0);
106 half4 filter = half4(SAMPLE_TEXTURE2D_LOD(_ChromaticAberration_SpectralLut, sampler_ChromaticAberration_SpectralLut, float2(t, 0.0), 0).rgb, 1.0);
113 color = sum / filterSum;
115 #elif CHROMATIC_ABERRATION_LOW
117 float2 coords = 2.0 * uv - 1.0;
118 float2 end = uv - coords * dot(coords, coords) * _ChromaticAberration_Amount;
119 float2 delta = (end - uv) / 3;
121 half4 filterA = half4(SAMPLE_TEXTURE2D_LOD(_ChromaticAberration_SpectralLut, sampler_ChromaticAberration_SpectralLut, float2(0.5 / 3, 0.0), 0).rgb, 1.0);
122 half4 filterB = half4(SAMPLE_TEXTURE2D_LOD(_ChromaticAberration_SpectralLut, sampler_ChromaticAberration_SpectralLut, float2(1.5 / 3, 0.0), 0).rgb, 1.0);
123 half4 filterC = half4(SAMPLE_TEXTURE2D_LOD(_ChromaticAberration_SpectralLut, sampler_ChromaticAberration_SpectralLut, float2(2.5 / 3, 0.0), 0).rgb, 1.0);
125 half4 texelA = SAMPLE_TEXTURE2D_LOD(_MainTex, sampler_MainTex, UnityStereoTransformScreenSpaceTex(Distort(uv)), 0);
126 half4 texelB = SAMPLE_TEXTURE2D_LOD(_MainTex, sampler_MainTex, UnityStereoTransformScreenSpaceTex(Distort(delta + uv)), 0);
127 half4 texelC = SAMPLE_TEXTURE2D_LOD(_MainTex, sampler_MainTex, UnityStereoTransformScreenSpaceTex(Distort(delta * 2.0 + uv)), 0);
129 half4 sum = texelA * filterA + texelB * filterB + texelC * filterC;
130 half4 filterSum = filterA + filterB + filterC;
131 color = sum / filterSum;
135 color = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uvStereoDistorted);
139 // Gamma space... Gah.
140 #if UNITY_COLORSPACE_GAMMA
142 color = SRGBToLinear(color);
146 color.rgb *= autoExposure;
148 #if BLOOM || BLOOM_LOW
151 half4 bloom = UpsampleTent(TEXTURE2D_PARAM(_BloomTex, sampler_BloomTex), uvDistorted, _BloomTex_TexelSize.xy, _Bloom_Settings.x);
153 half4 bloom = UpsampleBox(TEXTURE2D_PARAM(_BloomTex, sampler_BloomTex), uvDistorted, _BloomTex_TexelSize.xy, _Bloom_Settings.x);
156 // UVs should be Distort(uv * _Bloom_DirtTileOffset.xy + _Bloom_DirtTileOffset.zw)
157 // but considering we use a cover-style scale on the dirt texture the difference
158 // isn't massive so we chose to save a few ALUs here instead in case lens distortion
160 half4 dirt = half4(SAMPLE_TEXTURE2D(_Bloom_DirtTex, sampler_Bloom_DirtTex, uvDistorted * _Bloom_DirtTileOffset.xy + _Bloom_DirtTileOffset.zw).rgb, 0.0);
162 // Additive bloom (artist friendly)
163 bloom *= _Bloom_Settings.y;
164 dirt *= _Bloom_Settings.z;
165 color += bloom * half4(_Bloom_Color, 1.0);
166 color += dirt * bloom;
173 if (_Vignette_Mode < 0.5)
175 half2 d = abs(uvDistorted - _Vignette_Center) * _Vignette_Settings.x;
176 d.x *= lerp(1.0, _ScreenParams.x / _ScreenParams.y, _Vignette_Settings.w);
177 d = pow(saturate(d), _Vignette_Settings.z); // Roundness
178 half vfactor = pow(saturate(1.0 - dot(d, d)), _Vignette_Settings.y);
179 color.rgb *= lerp(_Vignette_Color, (1.0).xxx, vfactor);
180 color.a = lerp(1.0, color.a, vfactor);
184 half vfactor = SAMPLE_TEXTURE2D(_Vignette_Mask, sampler_Vignette_Mask, uvDistorted).a;
186 #if !UNITY_COLORSPACE_GAMMA
188 vfactor = SRGBToLinear(vfactor);
192 half3 new_color = color.rgb * lerp(_Vignette_Color, (1.0).xxx, vfactor);
193 color.rgb = lerp(color.rgb, new_color, _Vignette_Opacity);
194 color.a = lerp(1.0, color.a, vfactor);
201 half3 grain = SAMPLE_TEXTURE2D(_GrainTex, sampler_GrainTex, i.texcoordStereo * _Grain_Params2.xy + _Grain_Params2.zw).rgb;
203 // Noisiness response curve based on scene luminance
204 float lum = 1.0 - sqrt(Luminance(saturate(color)));
205 lum = lerp(1.0, lum, _Grain_Params1.x);
207 color.rgb += color.rgb * grain * _Grain_Params1.y * lum;
211 #if COLOR_GRADING_HDR_3D
213 color *= _PostExposure;
214 float3 colorLutSpace = saturate(LUT_SPACE_ENCODE(color.rgb));
215 color.rgb = ApplyLut3D(TEXTURE3D_PARAM(_Lut3D, sampler_Lut3D), colorLutSpace, _Lut3D_Params);
217 #elif COLOR_GRADING_HDR_2D
219 color *= _PostExposure;
220 float3 colorLutSpace = saturate(LUT_SPACE_ENCODE(color.rgb));
221 color.rgb = ApplyLut2D(TEXTURE2D_PARAM(_Lut2D, sampler_Lut2D), colorLutSpace, _Lut2D_Params);
223 #elif COLOR_GRADING_LDR_2D
225 color = saturate(color);
227 // LDR Lut lookup needs to be in sRGB - for HDR stick to linear
228 color.rgb = LinearToSRGB(color.rgb);
229 color.rgb = ApplyLut2D(TEXTURE2D_PARAM(_Lut2D, sampler_Lut2D), color.rgb, _Lut2D_Params);
230 color.rgb = SRGBToLinear(color.rgb);
234 half4 output = color;
238 #if UNITY_COLORSPACE_GAMMA
240 output = LinearToSRGB(output);
244 output.rgb = Dither(output.rgb, i.texcoord);
249 if (_LumaInAlpha > 0.5)
251 // Put saturated luma in alpha for FXAA - higher quality than "green as luma" and
252 // necessary as RGB values will potentially still be HDR for the FXAA pass
253 half luma = Luminance(saturate(output));
257 #if UNITY_COLORSPACE_GAMMA
259 output = LinearToSRGB(output);
265 // Output RGB is still HDR at that point (unless range was crunched by a tonemapper)
273 Cull Off ZWrite Off ZTest Always
278 #pragma exclude_renderers gles vulkan
280 #pragma multi_compile __ COLOR_GRADING_LDR_2D COLOR_GRADING_HDR_2D COLOR_GRADING_HDR_3D
281 #pragma multi_compile __ STEREO_INSTANCING_ENABLED STEREO_DOUBLEWIDE_TARGET
288 Cull Off ZWrite Off ZTest Always
293 #pragma only_renderers vulkan
295 #pragma multi_compile __ COLOR_GRADING_LDR_2D COLOR_GRADING_HDR_2D COLOR_GRADING_HDR_3D
296 #pragma multi_compile __ STEREO_DOUBLEWIDE_TARGET // disabled for Vulkan because of shader compiler issues in older Unity versions: STEREO_INSTANCING_ENABLED
303 Cull Off ZWrite Off ZTest Always
308 #pragma only_renderers gles
310 #pragma multi_compile __ COLOR_GRADING_LDR_2D COLOR_GRADING_HDR_2D // not supported by OpenGL ES 2.0: COLOR_GRADING_HDR_3D
311 #pragma multi_compile __ STEREO_DOUBLEWIDE_TARGET // not supported by OpenGL ES 2.0: STEREO_INSTANCING_ENABLED