Uber.shader 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. Shader "Hidden/PostProcessing/Uber"
  2. {
  3. HLSLINCLUDE
  4. #pragma target 3.0
  5. #pragma multi_compile __ DISTORT
  6. #pragma multi_compile __ CHROMATIC_ABERRATION CHROMATIC_ABERRATION_LOW
  7. #pragma multi_compile __ BLOOM BLOOM_LOW
  8. #pragma multi_compile __ VIGNETTE
  9. #pragma multi_compile __ GRAIN
  10. #pragma multi_compile __ FINALPASS
  11. // the following keywords are handled in API specific SubShaders below
  12. // #pragma multi_compile __ COLOR_GRADING_LDR_2D COLOR_GRADING_HDR_2D COLOR_GRADING_HDR_3D
  13. // #pragma multi_compile __ STEREO_INSTANCING_ENABLED STEREO_DOUBLEWIDE_TARGET
  14. #pragma vertex VertUVTransform
  15. #pragma fragment FragUber
  16. #include "../StdLib.hlsl"
  17. #include "../Colors.hlsl"
  18. #include "../Sampling.hlsl"
  19. #include "Distortion.hlsl"
  20. #include "Dithering.hlsl"
  21. #define MAX_CHROMATIC_SAMPLES 16
  22. TEXTURE2D_SAMPLER2D(_MainTex, sampler_MainTex);
  23. float4 _MainTex_TexelSize;
  24. // Auto exposure / eye adaptation
  25. TEXTURE2D_SAMPLER2D(_AutoExposureTex, sampler_AutoExposureTex);
  26. // Bloom
  27. TEXTURE2D_SAMPLER2D(_BloomTex, sampler_BloomTex);
  28. TEXTURE2D_SAMPLER2D(_Bloom_DirtTex, sampler_Bloom_DirtTex);
  29. float4 _BloomTex_TexelSize;
  30. float4 _Bloom_DirtTileOffset; // xy: tiling, zw: offset
  31. half3 _Bloom_Settings; // x: sampleScale, y: intensity, z: dirt intensity
  32. half3 _Bloom_Color;
  33. // Chromatic aberration
  34. TEXTURE2D_SAMPLER2D(_ChromaticAberration_SpectralLut, sampler_ChromaticAberration_SpectralLut);
  35. half _ChromaticAberration_Amount;
  36. // Color grading
  37. #if COLOR_GRADING_HDR_3D
  38. TEXTURE3D_SAMPLER3D(_Lut3D, sampler_Lut3D);
  39. float2 _Lut3D_Params;
  40. #else
  41. TEXTURE2D_SAMPLER2D(_Lut2D, sampler_Lut2D);
  42. float3 _Lut2D_Params;
  43. #endif
  44. half _PostExposure; // EV (exp2)
  45. // Vignette
  46. half3 _Vignette_Color;
  47. half2 _Vignette_Center; // UV space
  48. half4 _Vignette_Settings; // x: intensity, y: smoothness, z: roundness, w: rounded
  49. half _Vignette_Opacity;
  50. half _Vignette_Mode; // <0.5: procedural, >=0.5: masked
  51. TEXTURE2D_SAMPLER2D(_Vignette_Mask, sampler_Vignette_Mask);
  52. // Grain
  53. TEXTURE2D_SAMPLER2D(_GrainTex, sampler_GrainTex);
  54. half2 _Grain_Params1; // x: lum_contrib, y: intensity
  55. float4 _Grain_Params2; // x: xscale, h: yscale, z: xoffset, w: yoffset
  56. // Misc
  57. half _LumaInAlpha;
  58. half4 FragUber(VaryingsDefault i) : SV_Target
  59. {
  60. float2 uv = i.texcoord;
  61. //>>> Automatically skipped by the shader optimizer when not used
  62. float2 uvDistorted = Distort(i.texcoord);
  63. float2 uvStereoDistorted = Distort(i.texcoordStereo);
  64. //<<<
  65. half autoExposure = SAMPLE_TEXTURE2D(_AutoExposureTex, sampler_AutoExposureTex, uv).r;
  66. half4 color = (0.0).xxxx;
  67. // Inspired by the method described in "Rendering Inside" [Playdead 2016]
  68. // https://twitter.com/pixelmager/status/717019757766123520
  69. #if CHROMATIC_ABERRATION
  70. {
  71. float2 coords = 2.0 * uv - 1.0;
  72. float2 end = uv - coords * dot(coords, coords) * _ChromaticAberration_Amount;
  73. float2 diff = end - uv;
  74. int samples = clamp(int(length(_MainTex_TexelSize.zw * diff / 2.0)), 3, MAX_CHROMATIC_SAMPLES);
  75. float2 delta = diff / samples;
  76. float2 pos = uv;
  77. half4 sum = (0.0).xxxx, filterSum = (0.0).xxxx;
  78. for (int i = 0; i < samples; i++)
  79. {
  80. half t = (i + 0.5) / samples;
  81. half4 s = SAMPLE_TEXTURE2D_LOD(_MainTex, sampler_MainTex, UnityStereoTransformScreenSpaceTex(Distort(pos)), 0);
  82. half4 filter = half4(SAMPLE_TEXTURE2D_LOD(_ChromaticAberration_SpectralLut, sampler_ChromaticAberration_SpectralLut, float2(t, 0.0), 0).rgb, 1.0);
  83. sum += s * filter;
  84. filterSum += filter;
  85. pos += delta;
  86. }
  87. color = sum / filterSum;
  88. }
  89. #elif CHROMATIC_ABERRATION_LOW
  90. {
  91. float2 coords = 2.0 * uv - 1.0;
  92. float2 end = uv - coords * dot(coords, coords) * _ChromaticAberration_Amount;
  93. float2 delta = (end - uv) / 3;
  94. half4 filterA = half4(SAMPLE_TEXTURE2D_LOD(_ChromaticAberration_SpectralLut, sampler_ChromaticAberration_SpectralLut, float2(0.5 / 3, 0.0), 0).rgb, 1.0);
  95. half4 filterB = half4(SAMPLE_TEXTURE2D_LOD(_ChromaticAberration_SpectralLut, sampler_ChromaticAberration_SpectralLut, float2(1.5 / 3, 0.0), 0).rgb, 1.0);
  96. half4 filterC = half4(SAMPLE_TEXTURE2D_LOD(_ChromaticAberration_SpectralLut, sampler_ChromaticAberration_SpectralLut, float2(2.5 / 3, 0.0), 0).rgb, 1.0);
  97. half4 texelA = SAMPLE_TEXTURE2D_LOD(_MainTex, sampler_MainTex, UnityStereoTransformScreenSpaceTex(Distort(uv)), 0);
  98. half4 texelB = SAMPLE_TEXTURE2D_LOD(_MainTex, sampler_MainTex, UnityStereoTransformScreenSpaceTex(Distort(delta + uv)), 0);
  99. half4 texelC = SAMPLE_TEXTURE2D_LOD(_MainTex, sampler_MainTex, UnityStereoTransformScreenSpaceTex(Distort(delta * 2.0 + uv)), 0);
  100. half4 sum = texelA * filterA + texelB * filterB + texelC * filterC;
  101. half4 filterSum = filterA + filterB + filterC;
  102. color = sum / filterSum;
  103. }
  104. #else
  105. {
  106. color = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uvStereoDistorted);
  107. }
  108. #endif
  109. // Gamma space... Gah.
  110. #if UNITY_COLORSPACE_GAMMA
  111. {
  112. color = SRGBToLinear(color);
  113. }
  114. #endif
  115. color.rgb *= autoExposure;
  116. #if BLOOM || BLOOM_LOW
  117. {
  118. #if BLOOM
  119. half4 bloom = UpsampleTent(TEXTURE2D_PARAM(_BloomTex, sampler_BloomTex), uvDistorted, _BloomTex_TexelSize.xy, _Bloom_Settings.x);
  120. #else
  121. half4 bloom = UpsampleBox(TEXTURE2D_PARAM(_BloomTex, sampler_BloomTex), uvDistorted, _BloomTex_TexelSize.xy, _Bloom_Settings.x);
  122. #endif
  123. // UVs should be Distort(uv * _Bloom_DirtTileOffset.xy + _Bloom_DirtTileOffset.zw)
  124. // but considering we use a cover-style scale on the dirt texture the difference
  125. // isn't massive so we chose to save a few ALUs here instead in case lens distortion
  126. // is active
  127. half4 dirt = half4(SAMPLE_TEXTURE2D(_Bloom_DirtTex, sampler_Bloom_DirtTex, uvDistorted * _Bloom_DirtTileOffset.xy + _Bloom_DirtTileOffset.zw).rgb, 0.0);
  128. // Additive bloom (artist friendly)
  129. bloom *= _Bloom_Settings.y;
  130. dirt *= _Bloom_Settings.z;
  131. color += bloom * half4(_Bloom_Color, 1.0);
  132. color += dirt * bloom;
  133. }
  134. #endif
  135. #if VIGNETTE
  136. {
  137. UNITY_BRANCH
  138. if (_Vignette_Mode < 0.5)
  139. {
  140. half2 d = abs(uvDistorted - _Vignette_Center) * _Vignette_Settings.x;
  141. d.x *= lerp(1.0, _ScreenParams.x / _ScreenParams.y, _Vignette_Settings.w);
  142. d = pow(saturate(d), _Vignette_Settings.z); // Roundness
  143. half vfactor = pow(saturate(1.0 - dot(d, d)), _Vignette_Settings.y);
  144. color.rgb *= lerp(_Vignette_Color, (1.0).xxx, vfactor);
  145. color.a = lerp(1.0, color.a, vfactor);
  146. }
  147. else
  148. {
  149. half vfactor = SAMPLE_TEXTURE2D(_Vignette_Mask, sampler_Vignette_Mask, uvDistorted).a;
  150. #if !UNITY_COLORSPACE_GAMMA
  151. {
  152. vfactor = SRGBToLinear(vfactor);
  153. }
  154. #endif
  155. half3 new_color = color.rgb * lerp(_Vignette_Color, (1.0).xxx, vfactor);
  156. color.rgb = lerp(color.rgb, new_color, _Vignette_Opacity);
  157. color.a = lerp(1.0, color.a, vfactor);
  158. }
  159. }
  160. #endif
  161. #if GRAIN
  162. {
  163. half3 grain = SAMPLE_TEXTURE2D(_GrainTex, sampler_GrainTex, i.texcoordStereo * _Grain_Params2.xy + _Grain_Params2.zw).rgb;
  164. // Noisiness response curve based on scene luminance
  165. float lum = 1.0 - sqrt(Luminance(saturate(color)));
  166. lum = lerp(1.0, lum, _Grain_Params1.x);
  167. color.rgb += color.rgb * grain * _Grain_Params1.y * lum;
  168. }
  169. #endif
  170. #if COLOR_GRADING_HDR_3D
  171. {
  172. color *= _PostExposure;
  173. float3 colorLutSpace = saturate(LUT_SPACE_ENCODE(color.rgb));
  174. color.rgb = ApplyLut3D(TEXTURE3D_PARAM(_Lut3D, sampler_Lut3D), colorLutSpace, _Lut3D_Params);
  175. }
  176. #elif COLOR_GRADING_HDR_2D
  177. {
  178. color *= _PostExposure;
  179. float3 colorLutSpace = saturate(LUT_SPACE_ENCODE(color.rgb));
  180. color.rgb = ApplyLut2D(TEXTURE2D_PARAM(_Lut2D, sampler_Lut2D), colorLutSpace, _Lut2D_Params);
  181. }
  182. #elif COLOR_GRADING_LDR_2D
  183. {
  184. color = saturate(color);
  185. // LDR Lut lookup needs to be in sRGB - for HDR stick to linear
  186. color.rgb = LinearToSRGB(color.rgb);
  187. color.rgb = ApplyLut2D(TEXTURE2D_PARAM(_Lut2D, sampler_Lut2D), color.rgb, _Lut2D_Params);
  188. color.rgb = SRGBToLinear(color.rgb);
  189. }
  190. #endif
  191. half4 output = color;
  192. #if FINALPASS
  193. {
  194. #if UNITY_COLORSPACE_GAMMA
  195. {
  196. output = LinearToSRGB(output);
  197. }
  198. #endif
  199. output.rgb = Dither(output.rgb, i.texcoord);
  200. }
  201. #else
  202. {
  203. UNITY_BRANCH
  204. if (_LumaInAlpha > 0.5)
  205. {
  206. // Put saturated luma in alpha for FXAA - higher quality than "green as luma" and
  207. // necessary as RGB values will potentially still be HDR for the FXAA pass
  208. half luma = Luminance(saturate(output));
  209. output.a = luma;
  210. }
  211. #if UNITY_COLORSPACE_GAMMA
  212. {
  213. output = LinearToSRGB(output);
  214. }
  215. #endif
  216. }
  217. #endif
  218. // Output RGB is still HDR at that point (unless range was crunched by a tonemapper)
  219. return output;
  220. }
  221. ENDHLSL
  222. SubShader
  223. {
  224. Cull Off ZWrite Off ZTest Always
  225. Pass
  226. {
  227. HLSLPROGRAM
  228. #pragma exclude_renderers gles vulkan
  229. #pragma multi_compile __ COLOR_GRADING_LDR_2D COLOR_GRADING_HDR_2D COLOR_GRADING_HDR_3D
  230. #pragma multi_compile __ STEREO_INSTANCING_ENABLED STEREO_DOUBLEWIDE_TARGET
  231. ENDHLSL
  232. }
  233. }
  234. SubShader
  235. {
  236. Cull Off ZWrite Off ZTest Always
  237. Pass
  238. {
  239. HLSLPROGRAM
  240. #pragma only_renderers vulkan
  241. #pragma multi_compile __ COLOR_GRADING_LDR_2D COLOR_GRADING_HDR_2D COLOR_GRADING_HDR_3D
  242. #pragma multi_compile __ STEREO_DOUBLEWIDE_TARGET // disabled for Vulkan because of shader compiler issues in older Unity versions: STEREO_INSTANCING_ENABLED
  243. ENDHLSL
  244. }
  245. }
  246. SubShader
  247. {
  248. Cull Off ZWrite Off ZTest Always
  249. Pass
  250. {
  251. HLSLPROGRAM
  252. #pragma only_renderers gles
  253. #pragma multi_compile __ COLOR_GRADING_LDR_2D COLOR_GRADING_HDR_2D // not supported by OpenGL ES 2.0: COLOR_GRADING_HDR_3D
  254. #pragma multi_compile __ STEREO_DOUBLEWIDE_TARGET // not supported by OpenGL ES 2.0: STEREO_INSTANCING_ENABLED
  255. ENDHLSL
  256. }
  257. }
  258. }