You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

330 lines
11 KiB

  1. Shader "Hidden/Post FX/Uber Shader"
  2. {
  3. Properties
  4. {
  5. _MainTex ("Texture", 2D) = "white" {}
  6. _AutoExposure ("", 2D) = "" {}
  7. _BloomTex ("", 2D) = "" {}
  8. _Bloom_DirtTex ("", 2D) = "" {}
  9. _GrainTex ("", 2D) = "" {}
  10. _LogLut ("", 2D) = "" {}
  11. _UserLut ("", 2D) = "" {}
  12. _Vignette_Mask ("", 2D) = "" {}
  13. _ChromaticAberration_Spectrum ("", 2D) = "" {}
  14. _DitheringTex ("", 2D) = "" {}
  15. }
  16. CGINCLUDE
  17. #pragma target 3.0
  18. #pragma multi_compile __ UNITY_COLORSPACE_GAMMA
  19. #pragma multi_compile __ CHROMATIC_ABERRATION
  20. #pragma multi_compile __ DEPTH_OF_FIELD DEPTH_OF_FIELD_COC_VIEW
  21. #pragma multi_compile __ BLOOM BLOOM_LENS_DIRT
  22. #pragma multi_compile __ COLOR_GRADING COLOR_GRADING_LOG_VIEW
  23. #pragma multi_compile __ USER_LUT
  24. #pragma multi_compile __ GRAIN
  25. #pragma multi_compile __ VIGNETTE_CLASSIC VIGNETTE_MASKED
  26. #pragma multi_compile __ DITHERING
  27. #include "UnityCG.cginc"
  28. #include "Bloom.cginc"
  29. #include "ColorGrading.cginc"
  30. #include "UberSecondPass.cginc"
  31. // Auto exposure / eye adaptation
  32. sampler2D _AutoExposure;
  33. // Chromatic aberration
  34. half _ChromaticAberration_Amount;
  35. sampler2D _ChromaticAberration_Spectrum;
  36. // Depth of field
  37. sampler2D_float _CameraDepthTexture;
  38. sampler2D _DepthOfFieldTex;
  39. sampler2D _DepthOfFieldCoCTex;
  40. float4 _DepthOfFieldTex_TexelSize;
  41. float3 _DepthOfFieldParams; // x: distance, y: f^2 / (N * (S1 - f) * film_width * 2), z: max coc
  42. // Bloom
  43. sampler2D _BloomTex;
  44. float4 _BloomTex_TexelSize;
  45. half2 _Bloom_Settings; // x: sampleScale, y: bloom.intensity
  46. sampler2D _Bloom_DirtTex;
  47. half _Bloom_DirtIntensity;
  48. // Color grading & tonemapping
  49. sampler2D _LogLut;
  50. half3 _LogLut_Params; // x: 1 / lut_width, y: 1 / lut_height, z: lut_height - 1
  51. half _ExposureEV; // EV (exp2)
  52. // User lut
  53. sampler2D _UserLut;
  54. half4 _UserLut_Params; // @see _LogLut_Params
  55. // Vignette
  56. half3 _Vignette_Color;
  57. half2 _Vignette_Center; // UV space
  58. half4 _Vignette_Settings; // x: intensity, y: smoothness, z: roundness, w: rounded
  59. sampler2D _Vignette_Mask;
  60. half _Vignette_Opacity; // [0;1]
  61. struct VaryingsFlipped
  62. {
  63. float4 pos : SV_POSITION;
  64. float2 uv : TEXCOORD0;
  65. float2 uvSPR : TEXCOORD1; // Single Pass Stereo UVs
  66. float2 uvFlipped : TEXCOORD2; // Flipped UVs (DX/MSAA/Forward)
  67. float2 uvFlippedSPR : TEXCOORD3; // Single Pass Stereo flipped UVs
  68. };
  69. VaryingsFlipped VertUber(AttributesDefault v)
  70. {
  71. VaryingsFlipped o;
  72. o.pos = UnityObjectToClipPos(v.vertex);
  73. o.uv = v.texcoord.xy;
  74. o.uvSPR = UnityStereoScreenSpaceUVAdjust(v.texcoord.xy, _MainTex_ST);
  75. o.uvFlipped = v.texcoord.xy;
  76. #if UNITY_UV_STARTS_AT_TOP
  77. if (_MainTex_TexelSize.y < 0.0)
  78. o.uvFlipped.y = 1.0 - o.uvFlipped.y;
  79. #endif
  80. o.uvFlippedSPR = UnityStereoScreenSpaceUVAdjust(o.uvFlipped, _MainTex_ST);
  81. return o;
  82. }
  83. half4 FragUber(VaryingsFlipped i) : SV_Target
  84. {
  85. float2 uv = i.uv;
  86. half autoExposure = tex2D(_AutoExposure, uv).r;
  87. half3 color = (0.0).xxx;
  88. #if DEPTH_OF_FIELD && CHROMATIC_ABERRATION
  89. half4 dof = (0.0).xxxx;
  90. half ffa = 0.0; // far field alpha
  91. #endif
  92. //
  93. // HDR effects
  94. // ---------------------------------------------------------
  95. // Chromatic Aberration
  96. // Inspired by the method described in "Rendering Inside" [Playdead 2016]
  97. // https://twitter.com/pixelmager/status/717019757766123520
  98. #if CHROMATIC_ABERRATION
  99. {
  100. float2 coords = 2.0 * uv - 1.0;
  101. float2 end = uv - coords * dot(coords, coords) * _ChromaticAberration_Amount;
  102. float2 diff = end - uv;
  103. int samples = clamp(int(length(_MainTex_TexelSize.zw * diff / 2.0)), 3, 16);
  104. float2 delta = diff / samples;
  105. float2 pos = uv;
  106. half3 sum = (0.0).xxx, filterSum = (0.0).xxx;
  107. #if DEPTH_OF_FIELD
  108. float2 dofDelta = delta;
  109. float2 dofPos = pos;
  110. if (_MainTex_TexelSize.y < 0.0)
  111. {
  112. dofDelta.y = -dofDelta.y;
  113. dofPos.y = 1.0 - dofPos.y;
  114. }
  115. half4 dofSum = (0.0).xxxx;
  116. half ffaSum = 0.0;
  117. #endif
  118. for (int i = 0; i < samples; i++)
  119. {
  120. half t = (i + 0.5) / samples;
  121. half3 s = tex2Dlod(_MainTex, float4(UnityStereoScreenSpaceUVAdjust(pos, _MainTex_ST), 0, 0)).rgb;
  122. half3 filter = tex2Dlod(_ChromaticAberration_Spectrum, float4(t, 0, 0, 0)).rgb;
  123. sum += s * filter;
  124. filterSum += filter;
  125. pos += delta;
  126. #if DEPTH_OF_FIELD
  127. float4 uvDof = float4(UnityStereoScreenSpaceUVAdjust(dofPos, _MainTex_ST), 0, 0);
  128. half4 sdof = tex2Dlod(_DepthOfFieldTex, uvDof).rgba;
  129. half scoc = tex2Dlod(_DepthOfFieldCoCTex, uvDof).r;
  130. scoc = (scoc - 0.5) * 2 * _DepthOfFieldParams.z;
  131. dofSum += sdof * half4(filter, 1);
  132. ffaSum += smoothstep(_MainTex_TexelSize.y * 2, _MainTex_TexelSize.y * 4, scoc);
  133. dofPos += dofDelta;
  134. #endif
  135. }
  136. color = sum / filterSum;
  137. #if DEPTH_OF_FIELD
  138. dof = dofSum / half4(filterSum, samples);
  139. ffa = ffaSum / samples;
  140. #endif
  141. }
  142. #else
  143. {
  144. color = tex2D(_MainTex, i.uvSPR).rgb;
  145. }
  146. #endif
  147. // Apply auto exposure if any
  148. color *= autoExposure;
  149. // Gamma space... Gah.
  150. #if UNITY_COLORSPACE_GAMMA
  151. {
  152. color = GammaToLinearSpace(color);
  153. }
  154. #endif
  155. // Depth of field
  156. #if DEPTH_OF_FIELD_COC_VIEW
  157. {
  158. // Calculate the radiuses of CoC.
  159. half4 src = tex2D(_DepthOfFieldTex, uv);
  160. float depth = LinearEyeDepth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uvFlippedSPR));
  161. float coc = (depth - _DepthOfFieldParams.x) * _DepthOfFieldParams.y / depth;
  162. coc *= 80;
  163. // Visualize CoC (white -> red -> gray)
  164. half3 rgb = lerp(half3(1, 0, 0), half3(1.0, 1.0, 1.0), saturate(-coc));
  165. rgb = lerp(rgb, half3(0.4, 0.4, 0.4), saturate(coc));
  166. // Black and white image overlay
  167. rgb *= AcesLuminance(color) + 0.5;
  168. // Gamma correction
  169. #if !UNITY_COLORSPACE_GAMMA
  170. {
  171. rgb = GammaToLinearSpace(rgb);
  172. }
  173. #endif
  174. color = rgb;
  175. }
  176. #elif DEPTH_OF_FIELD
  177. {
  178. #if !CHROMATIC_ABERRATION
  179. half4 dof = tex2D(_DepthOfFieldTex, i.uvFlippedSPR);
  180. half coc = tex2D(_DepthOfFieldCoCTex, i.uvFlippedSPR);
  181. coc = (coc - 0.5) * 2 * _DepthOfFieldParams.z;
  182. // Convert CoC to far field alpha value.
  183. float ffa = smoothstep(_MainTex_TexelSize.y * 2, _MainTex_TexelSize.y * 4, coc);
  184. #endif
  185. // lerp(lerp(color, dof, ffa), dof, dof.a)
  186. color = lerp(color, dof.rgb * autoExposure, ffa + dof.a - ffa * dof.a);
  187. }
  188. #endif
  189. // HDR Bloom
  190. #if BLOOM || BLOOM_LENS_DIRT
  191. {
  192. half3 bloom = UpsampleFilter(_BloomTex, i.uvFlippedSPR, _BloomTex_TexelSize.xy, _Bloom_Settings.x) * _Bloom_Settings.y;
  193. color += bloom;
  194. #if BLOOM_LENS_DIRT
  195. {
  196. half3 dirt = tex2D(_Bloom_DirtTex, i.uvFlipped).rgb * _Bloom_DirtIntensity;
  197. color += bloom * dirt;
  198. }
  199. #endif
  200. }
  201. #endif
  202. // Procedural vignette
  203. #if VIGNETTE_CLASSIC
  204. {
  205. half2 d = abs(uv - _Vignette_Center) * _Vignette_Settings.x;
  206. d.x *= lerp(1.0, _ScreenParams.x / _ScreenParams.y, _Vignette_Settings.w);
  207. d = pow(d, _Vignette_Settings.z); // Roundness
  208. half vfactor = pow(saturate(1.0 - dot(d, d)), _Vignette_Settings.y);
  209. color *= lerp(_Vignette_Color, (1.0).xxx, vfactor);
  210. }
  211. // Masked vignette
  212. #elif VIGNETTE_MASKED
  213. {
  214. half vfactor = tex2D(_Vignette_Mask, uv).a;
  215. half3 new_color = color * lerp(_Vignette_Color, (1.0).xxx, vfactor);
  216. color = lerp(color, new_color, _Vignette_Opacity);
  217. }
  218. #endif
  219. // HDR color grading & tonemapping
  220. #if COLOR_GRADING_LOG_VIEW
  221. {
  222. color *= _ExposureEV;
  223. color = saturate(LinearToLogC(color));
  224. }
  225. #elif COLOR_GRADING
  226. {
  227. color *= _ExposureEV; // Exposure is in ev units (or 'stops')
  228. half3 colorLogC = saturate(LinearToLogC(color));
  229. color = ApplyLut2d(_LogLut, colorLogC, _LogLut_Params);
  230. }
  231. #endif
  232. //
  233. // All the following effects happen in LDR
  234. // ---------------------------------------------------------
  235. color = saturate(color);
  236. // Back to gamma space if needed
  237. #if UNITY_COLORSPACE_GAMMA
  238. {
  239. color = LinearToGammaSpace(color);
  240. }
  241. #endif
  242. // LDR user lut
  243. #if USER_LUT
  244. {
  245. color = saturate(color);
  246. half3 colorGraded;
  247. #if !UNITY_COLORSPACE_GAMMA
  248. {
  249. colorGraded = ApplyLut2d(_UserLut, LinearToGammaSpace(color), _UserLut_Params.xyz);
  250. colorGraded = GammaToLinearSpace(colorGraded);
  251. }
  252. #else
  253. {
  254. colorGraded = ApplyLut2d(_UserLut, color, _UserLut_Params.xyz);
  255. }
  256. #endif
  257. color = lerp(color, colorGraded, _UserLut_Params.w);
  258. }
  259. #endif
  260. color = UberSecondPass(color, uv);
  261. // Done !
  262. return half4(color, 1.0);
  263. }
  264. ENDCG
  265. SubShader
  266. {
  267. Cull Off ZWrite Off ZTest Always
  268. // (0)
  269. Pass
  270. {
  271. CGPROGRAM
  272. #pragma vertex VertUber
  273. #pragma fragment FragUber
  274. ENDCG
  275. }
  276. }
  277. }