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.

86 lines
2.4 KiB

  1. #ifndef __BLOOM__
  2. #define __BLOOM__
  3. #include "Common.cginc"
  4. // Brightness function
  5. half Brightness(half3 c)
  6. {
  7. return Max3(c);
  8. }
  9. // 3-tap median filter
  10. half3 Median(half3 a, half3 b, half3 c)
  11. {
  12. return a + b + c - min(min(a, b), c) - max(max(a, b), c);
  13. }
  14. // Downsample with a 4x4 box filter
  15. half3 DownsampleFilter(sampler2D tex, float2 uv, float2 texelSize)
  16. {
  17. float4 d = texelSize.xyxy * float4(-1.0, -1.0, 1.0, 1.0);
  18. half3 s;
  19. s = DecodeHDR(tex2D(tex, uv + d.xy));
  20. s += DecodeHDR(tex2D(tex, uv + d.zy));
  21. s += DecodeHDR(tex2D(tex, uv + d.xw));
  22. s += DecodeHDR(tex2D(tex, uv + d.zw));
  23. return s * (1.0 / 4.0);
  24. }
  25. // Downsample with a 4x4 box filter + anti-flicker filter
  26. half3 DownsampleAntiFlickerFilter(sampler2D tex, float2 uv, float2 texelSize)
  27. {
  28. float4 d = texelSize.xyxy * float4(-1.0, -1.0, 1.0, 1.0);
  29. half3 s1 = DecodeHDR(tex2D(tex, uv + d.xy));
  30. half3 s2 = DecodeHDR(tex2D(tex, uv + d.zy));
  31. half3 s3 = DecodeHDR(tex2D(tex, uv + d.xw));
  32. half3 s4 = DecodeHDR(tex2D(tex, uv + d.zw));
  33. // Karis's luma weighted average (using brightness instead of luma)
  34. half s1w = 1.0 / (Brightness(s1) + 1.0);
  35. half s2w = 1.0 / (Brightness(s2) + 1.0);
  36. half s3w = 1.0 / (Brightness(s3) + 1.0);
  37. half s4w = 1.0 / (Brightness(s4) + 1.0);
  38. half one_div_wsum = 1.0 / (s1w + s2w + s3w + s4w);
  39. return (s1 * s1w + s2 * s2w + s3 * s3w + s4 * s4w) * one_div_wsum;
  40. }
  41. half3 UpsampleFilter(sampler2D tex, float2 uv, float2 texelSize, float sampleScale)
  42. {
  43. #if MOBILE_OR_CONSOLE
  44. // 4-tap bilinear upsampler
  45. float4 d = texelSize.xyxy * float4(-1.0, -1.0, 1.0, 1.0) * (sampleScale * 0.5);
  46. half3 s;
  47. s = DecodeHDR(tex2D(tex, uv + d.xy));
  48. s += DecodeHDR(tex2D(tex, uv + d.zy));
  49. s += DecodeHDR(tex2D(tex, uv + d.xw));
  50. s += DecodeHDR(tex2D(tex, uv + d.zw));
  51. return s * (1.0 / 4.0);
  52. #else
  53. // 9-tap bilinear upsampler (tent filter)
  54. float4 d = texelSize.xyxy * float4(1.0, 1.0, -1.0, 0.0) * sampleScale;
  55. half3 s;
  56. s = DecodeHDR(tex2D(tex, uv - d.xy));
  57. s += DecodeHDR(tex2D(tex, uv - d.wy)) * 2.0;
  58. s += DecodeHDR(tex2D(tex, uv - d.zy));
  59. s += DecodeHDR(tex2D(tex, uv + d.zw)) * 2.0;
  60. s += DecodeHDR(tex2D(tex, uv)) * 4.0;
  61. s += DecodeHDR(tex2D(tex, uv + d.xw)) * 2.0;
  62. s += DecodeHDR(tex2D(tex, uv + d.zy));
  63. s += DecodeHDR(tex2D(tex, uv + d.wy)) * 2.0;
  64. s += DecodeHDR(tex2D(tex, uv + d.xy));
  65. return s * (1.0 / 16.0);
  66. #endif
  67. }
  68. #endif // __BLOOM__