dof.effect 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. // Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd.
  2. CCEffect %{
  3. techniques:
  4. - passes:
  5. - vert: dof-vs
  6. frag: dof-coc-fs
  7. pass: dof-coc
  8. depthStencilState:
  9. depthTest: false
  10. depthWrite: false
  11. - vert: dof-vs
  12. frag: dof-prefilter-fs
  13. pass: dof-prefilter
  14. depthStencilState:
  15. depthTest: false
  16. depthWrite: false
  17. - vert: dof-vs
  18. frag: dof-bokeh-fs
  19. pass: dof-bokeh
  20. depthStencilState:
  21. depthTest: false
  22. depthWrite: false
  23. - vert: dof-vs
  24. frag: dof-filter-fs
  25. pass: dof-filter
  26. depthStencilState:
  27. depthTest: false
  28. depthWrite: false
  29. - vert: dof-vs
  30. frag: dof-combine-fs
  31. pass: dof-combine
  32. depthStencilState:
  33. depthTest: false
  34. depthWrite: false
  35. blendState:
  36. targets:
  37. - blend: true
  38. blendSrc: zero
  39. blendDst: src_alpha
  40. blendSrcAlpha: zero
  41. blendDstAlpha: one
  42. }%
  43. CCProgram ubo %{
  44. #include <common/common-define>
  45. uniform ColorGradingUBO {
  46. vec4 cocParams;
  47. vec4 mainTexTexelSize;
  48. };
  49. #pragma rate colorTex pass
  50. uniform sampler2D colorTex;
  51. #pragma rate cocTex pass
  52. uniform sampler2D cocTex;
  53. #pragma rate prefilterTex pass
  54. uniform sampler2D prefilterTex;
  55. #pragma rate bokehTex pass
  56. uniform sampler2D bokehTex;
  57. #pragma rate filterTex pass
  58. uniform sampler2D filterTex;
  59. #define focusDistance cocParams.x
  60. #define focusRange cocParams.y
  61. #define bokehRadius cocParams.z
  62. float FloatToUint8(float v) {
  63. return (v * 127.0 + 128.0 + 0.5) / 255.0;
  64. }
  65. float Uint8ToFloat(float v) {
  66. v *= 255.0;
  67. return ((v - 128.0) / 127.0);
  68. }
  69. }%
  70. CCProgram dof-vs %{
  71. precision highp float;
  72. #include <legacy/decode-standard>
  73. #include <builtin/uniforms/cc-global>
  74. out vec2 v_uv;
  75. void main() {
  76. StandardVertInput In;
  77. CCDecode(In);
  78. CC_HANDLE_GET_CLIP_FLIP(In.position.xy);
  79. gl_Position = In.position;
  80. v_uv = a_texCoord;
  81. }
  82. }%
  83. CCProgram dof-coc-fs %{
  84. precision highp float;
  85. #include <ubo>
  86. #include <common/common-define>
  87. #include <chunks/hbao>
  88. in vec2 v_uv;
  89. layout(location = 0)out vec4 fragColor;
  90. void main() {
  91. float depth = GetLinearDepth(v_uv);
  92. //get circle of confusion
  93. float coc = (depth - focusDistance) / focusRange;
  94. coc = clamp(coc, - 1.0, 1.0);
  95. fragColor = vec4(FloatToUint8(coc), 0.0, 0.0, 1.0);
  96. }
  97. }%
  98. CCProgram dof-prefilter-fs %{
  99. precision highp float;
  100. #include <ubo>
  101. #include <common/common-define>
  102. in vec2 v_uv;
  103. layout(location = 0)out vec4 fragColor;
  104. float Weigh(vec3 c) {
  105. return 1.0 / (1.0 + max(max(c.r, c.g), c.b));
  106. }
  107. void main() {
  108. //use lower resolution in order to cover more area
  109. //downsampling
  110. vec4 o = mainTexTexelSize.xyxy * vec2(-0.5, 0.5).xxyy;
  111. vec2 uv0 = v_uv + o.xy;
  112. vec2 uv1 = v_uv + o.zy;
  113. vec2 uv2 = v_uv + o.xw;
  114. vec2 uv3 = v_uv + o.zw;
  115. vec3 s0 = texture(colorTex, uv0).rgb;
  116. vec3 s1 = texture(colorTex, uv1).rgb;
  117. vec3 s2 = texture(colorTex, uv2).rgb;
  118. vec3 s3 = texture(colorTex, uv3).rgb;
  119. float w0 = Weigh(s0);
  120. float w1 = Weigh(s1);
  121. float w2 = Weigh(s2);
  122. float w3 = Weigh(s3);
  123. // get the weighted average
  124. vec3 avg = s0 * w0 + s1 * w1 + s2 * w2 + s3 * w3;
  125. avg /= max(w0 + w1 + w2 + s3, 0.00001);
  126. float coc0 = Uint8ToFloat(texture(cocTex, uv0).r);
  127. float coc1 = Uint8ToFloat(texture(cocTex, uv1).r);
  128. float coc2 = Uint8ToFloat(texture(cocTex, uv2).r);
  129. float coc3 = Uint8ToFloat(texture(cocTex, uv3).r);
  130. //get the largest CoC value of the four texture pixels
  131. float cocMin = min(min(min(coc0, coc1), coc2), coc3);
  132. float cocMax = max(max(max(coc0, coc1), coc2), coc3);
  133. float coc = cocMax >= -cocMin ? cocMax : cocMin;
  134. fragColor = vec4(avg, FloatToUint8(coc));
  135. }
  136. }%
  137. CCProgram dof-bokeh-fs %{
  138. precision highp float;
  139. #include <ubo>
  140. #include <common/common-define>
  141. in vec2 v_uv;
  142. layout(location = 0)out vec4 fragColor;
  143. const int SAMPLE_COUNT = 16;
  144. vec2 bokehKernel[SAMPLE_COUNT];
  145. void initKernel()
  146. {
  147. bokehKernel[0] = vec2(0.0, 0.0);
  148. bokehKernel[1] = vec2(0.54545456, 0.0);
  149. bokehKernel[2] = vec2(0.16855472, 0.5187581);
  150. bokehKernel[3] = vec2(-0.44128203, 0.3206101);
  151. bokehKernel[4] = vec2(-0.44128197, - 0.3206102);
  152. bokehKernel[5] = vec2(0.1685548, - 0.5187581);
  153. bokehKernel[6] = vec2(1.0, 0.0);
  154. bokehKernel[7] = vec2(0.809017, 0.58778524);
  155. bokehKernel[8] = vec2(0.30901697, 0.95105654);
  156. bokehKernel[9] = vec2(-0.30901703, 0.9510565);
  157. bokehKernel[10] = vec2(-0.80901706, 0.5877852);
  158. bokehKernel[11] = vec2(-1.0, 0.0);
  159. bokehKernel[12] = vec2(-0.80901694, - 0.58778536);
  160. bokehKernel[13] = vec2(-0.30901664, - 0.9510566);
  161. bokehKernel[14] = vec2(0.30901712, - 0.9510565);
  162. bokehKernel[15] = vec2(0.80901694, - 0.5877853);
  163. }
  164. //smooth transition between focal areas and boken areas
  165. float Weigh(float coc, float dist) {
  166. return saturate((abs(coc) - dist + 2.0) / 2.0);
  167. }
  168. void Accumulate(float coc, vec2 displacement, inout vec4 farAcc, inout vec4 nearAcc) {
  169. float dist = length(displacement);
  170. vec2 offset = displacement * mainTexTexelSize.xy * 2.0;
  171. vec4 prefilterColor = texture(prefilterTex, v_uv + offset);
  172. prefilterColor.a = Uint8ToFloat(prefilterColor.a) * bokehRadius;
  173. float fw = Weigh(max(0.0, min(prefilterColor.a, coc)), dist);
  174. farAcc.rgb += prefilterColor.rgb * fw;
  175. farAcc.a += fw;
  176. float nw = Weigh(-prefilterColor.a, dist);
  177. nearAcc.rgb += prefilterColor.rgb * nw;
  178. nearAcc.a += nw;
  179. }
  180. void main() {
  181. initKernel();
  182. float coc = Uint8ToFloat(texture(prefilterTex, v_uv).a) * bokehRadius;
  183. vec4 farAcc = vec4(0.0); // background
  184. vec4 nearAcc = vec4(0.0); // foreground
  185. for(int k = 0; k < SAMPLE_COUNT; k ++ ) {
  186. vec2 displacement = bokehKernel[k] * bokehRadius;
  187. Accumulate(coc, displacement, farAcc, nearAcc);
  188. }
  189. farAcc.rgb *= 1.0 / (farAcc.a + (farAcc.a == 0.0 ? 1.0 : 0.0));
  190. nearAcc.rgb *= 1.0 / (nearAcc.a + (nearAcc.a == 0.0 ? 1.0 : 0.0));
  191. //enhance foreground effects with a factor
  192. float alpha = min(1.0, nearAcc.a * PI / float(SAMPLE_COUNT));
  193. vec3 rgb = lerp(farAcc.rgb, nearAcc.rgb, alpha);
  194. fragColor = vec4(rgb, alpha);
  195. }
  196. }%
  197. CCProgram dof-filter-fs %{
  198. precision highp float;
  199. #include <ubo>
  200. in vec2 v_uv;
  201. layout(location = 0)out vec4 fragColor;
  202. void main() {
  203. //use tent filter,reduce the gap between sampling points
  204. vec4 o = mainTexTexelSize.xyxy * 2.0 * vec2(-0.5, 0.5).xxyy;
  205. vec4 s =
  206. texture(bokehTex, v_uv + o.xy) +
  207. texture(bokehTex, v_uv + o.zy) +
  208. texture(bokehTex, v_uv + o.xw) +
  209. texture(bokehTex, v_uv + o.zw);
  210. fragColor = s * 0.25;
  211. }
  212. }%
  213. CCProgram dof-combine-fs %{
  214. precision highp float;
  215. #include <ubo>
  216. #include <common/common-define>
  217. in vec2 v_uv;
  218. layout(location = 0)out vec4 fragColor;
  219. void main() {
  220. vec4 source = texture(colorTex, v_uv);
  221. float coc = Uint8ToFloat(texture(cocTex, v_uv).r) * bokehRadius;
  222. vec4 dof = texture(filterTex, v_uv);
  223. float dofStrength = smoothstep(0.1, 1.0, abs(coc));
  224. vec3 color = lerp(source.rgb, dof.rgb, dofStrength + dof.a - dofStrength * dof.a);
  225. fragColor = vec4(color.rgb, source.a);
  226. }
  227. }%