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.

182 lines
5.6 KiB

  1. //
  2. // Kino/Bloom v2 - Bloom filter for Unity
  3. //
  4. // Copyright (C) 2015, 2016 Keijiro Takahashi
  5. //
  6. // Permission is hereby granted, free of charge, to any person obtaining a copy
  7. // of this software and associated documentation files (the "Software"), to deal
  8. // in the Software without restriction, including without limitation the rights
  9. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. // copies of the Software, and to permit persons to whom the Software is
  11. // furnished to do so, subject to the following conditions:
  12. //
  13. // The above copyright notice and this permission notice shall be included in
  14. // all copies or substantial portions of the Software.
  15. //
  16. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22. // THE SOFTWARE.
  23. //
  24. Shader "Hidden/Post FX/Bloom"
  25. {
  26. Properties
  27. {
  28. _MainTex ("", 2D) = "" {}
  29. _BaseTex ("", 2D) = "" {}
  30. _AutoExposure ("", 2D) = "" {}
  31. }
  32. CGINCLUDE
  33. #pragma target 3.0
  34. #include "UnityCG.cginc"
  35. #include "Bloom.cginc"
  36. #include "Common.cginc"
  37. sampler2D _BaseTex;
  38. float2 _BaseTex_TexelSize;
  39. sampler2D _AutoExposure;
  40. float _PrefilterOffs;
  41. float _Threshold;
  42. float3 _Curve;
  43. float _SampleScale;
  44. // -----------------------------------------------------------------------------
  45. // Vertex shaders
  46. struct VaryingsMultitex
  47. {
  48. float4 pos : SV_POSITION;
  49. float2 uvMain : TEXCOORD0;
  50. float2 uvBase : TEXCOORD1;
  51. };
  52. VaryingsMultitex VertMultitex(AttributesDefault v)
  53. {
  54. VaryingsMultitex o;
  55. o.pos = UnityObjectToClipPos(v.vertex);
  56. o.uvMain = UnityStereoScreenSpaceUVAdjust(v.texcoord.xy, _MainTex_ST);
  57. o.uvBase = o.uvMain;
  58. #if UNITY_UV_STARTS_AT_TOP
  59. if (_BaseTex_TexelSize.y < 0.0)
  60. o.uvBase.y = 1.0 - o.uvBase.y;
  61. #endif
  62. return o;
  63. }
  64. // -----------------------------------------------------------------------------
  65. // Fragment shaders
  66. half4 FetchAutoExposed(sampler2D tex, float2 uv)
  67. {
  68. float autoExposure = 1.0;
  69. uv = UnityStereoScreenSpaceUVAdjust(uv, _MainTex_ST);
  70. autoExposure = tex2D(_AutoExposure, uv).r;
  71. return tex2D(tex, uv) * autoExposure;
  72. }
  73. half4 FragPrefilter(VaryingsDefault i) : SV_Target
  74. {
  75. float2 uv = i.uv + _MainTex_TexelSize.xy * _PrefilterOffs;
  76. #if ANTI_FLICKER
  77. float3 d = _MainTex_TexelSize.xyx * float3(1.0, 1.0, 0.0);
  78. half4 s0 = SafeHDR(FetchAutoExposed(_MainTex, uv));
  79. half3 s1 = SafeHDR(FetchAutoExposed(_MainTex, uv - d.xz).rgb);
  80. half3 s2 = SafeHDR(FetchAutoExposed(_MainTex, uv + d.xz).rgb);
  81. half3 s3 = SafeHDR(FetchAutoExposed(_MainTex, uv - d.zy).rgb);
  82. half3 s4 = SafeHDR(FetchAutoExposed(_MainTex, uv + d.zy).rgb);
  83. half3 m = Median(Median(s0.rgb, s1, s2), s3, s4);
  84. #else
  85. half4 s0 = SafeHDR(FetchAutoExposed(_MainTex, uv));
  86. half3 m = s0.rgb;
  87. #endif
  88. #if UNITY_COLORSPACE_GAMMA
  89. m = GammaToLinearSpace(m);
  90. #endif
  91. // Pixel brightness
  92. half br = Brightness(m);
  93. // Under-threshold part: quadratic curve
  94. half rq = clamp(br - _Curve.x, 0.0, _Curve.y);
  95. rq = _Curve.z * rq * rq;
  96. // Combine and apply the brightness response curve.
  97. m *= max(rq, br - _Threshold) / max(br, 1e-5);
  98. return EncodeHDR(m);
  99. }
  100. half4 FragDownsample1(VaryingsDefault i) : SV_Target
  101. {
  102. #if ANTI_FLICKER
  103. return EncodeHDR(DownsampleAntiFlickerFilter(_MainTex, i.uvSPR, _MainTex_TexelSize.xy));
  104. #else
  105. return EncodeHDR(DownsampleFilter(_MainTex, i.uvSPR, _MainTex_TexelSize.xy));
  106. #endif
  107. }
  108. half4 FragDownsample2(VaryingsDefault i) : SV_Target
  109. {
  110. return EncodeHDR(DownsampleFilter(_MainTex, i.uvSPR, _MainTex_TexelSize.xy));
  111. }
  112. half4 FragUpsample(VaryingsMultitex i) : SV_Target
  113. {
  114. half3 base = DecodeHDR(tex2D(_BaseTex, i.uvBase));
  115. half3 blur = UpsampleFilter(_MainTex, i.uvMain, _MainTex_TexelSize.xy, _SampleScale);
  116. return EncodeHDR(base + blur);
  117. }
  118. ENDCG
  119. SubShader
  120. {
  121. ZTest Always Cull Off ZWrite Off
  122. Pass
  123. {
  124. CGPROGRAM
  125. #pragma multi_compile __ ANTI_FLICKER
  126. #pragma multi_compile __ UNITY_COLORSPACE_GAMMA
  127. #pragma vertex VertDefault
  128. #pragma fragment FragPrefilter
  129. ENDCG
  130. }
  131. Pass
  132. {
  133. CGPROGRAM
  134. #pragma multi_compile __ ANTI_FLICKER
  135. #pragma vertex VertDefault
  136. #pragma fragment FragDownsample1
  137. ENDCG
  138. }
  139. Pass
  140. {
  141. CGPROGRAM
  142. #pragma vertex VertDefault
  143. #pragma fragment FragDownsample2
  144. ENDCG
  145. }
  146. Pass
  147. {
  148. CGPROGRAM
  149. #pragma vertex VertMultitex
  150. #pragma fragment FragUpsample
  151. ENDCG
  152. }
  153. }
  154. }