taa.effect 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. // Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd.
  2. CCEffect %{
  3. techniques:
  4. - passes:
  5. - vert: vs
  6. frag: fs
  7. pass: DeferredTAA0
  8. rasterizerState: &rasterizerState
  9. cullMode: none
  10. blendState: &blendState
  11. targets:
  12. - blend: true
  13. blendSrc: one
  14. blendDst: zero
  15. depthStencilState: &depthStencilState
  16. depthTest: false
  17. depthWrite: false
  18. - vert: vs
  19. frag: fs
  20. pass: DeferredTAA1
  21. rasterizerState: *rasterizerState
  22. depthStencilState: *depthStencilState
  23. blendState: *blendState
  24. - vert: vs
  25. frag: fs
  26. pass: DeferredTAA-1
  27. rasterizerState: *rasterizerState
  28. depthStencilState: *depthStencilState
  29. blendState: *blendState
  30. }%
  31. CCProgram vs %{
  32. #include <./chunks/vs>
  33. }%
  34. CCProgram fs %{
  35. precision highp float;
  36. #include <builtin/uniforms/cc-global>
  37. #include <legacy/output-standard>
  38. #include <unpack>
  39. in vec2 v_uv;
  40. uniform TaaUBO {
  41. vec4 inputViewPort;
  42. vec4 taaTextureSize;
  43. vec4 taaParams1; // xy: offset, z: feedback
  44. mat4 taaPrevViewProj;
  45. };
  46. #pragma rate motionMaskTex
  47. uniform highp sampler2D motionMaskTex;
  48. #pragma rate inputTexture pass
  49. uniform sampler2D inputTexture;
  50. #pragma rate depthTex pass
  51. uniform highp sampler2D depthTex;
  52. #pragma rate taaPrevTexture pass
  53. uniform sampler2D taaPrevTexture;
  54. // screen position (0-1)
  55. vec3 screen2WS(vec3 screenPos) {
  56. vec4 ndc = vec4(screenPos.xyz * 2. - 1.0, 1.0);
  57. vec4 world = cc_matViewProjInv * ndc;
  58. world = world / world.w;
  59. return world.xyz;
  60. }
  61. vec2 taaInputTexSize();
  62. vec2 taaPrevTexSize();
  63. vec3 Reinhard(in vec3 hdr) {
  64. return hdr / (hdr + 1.0);
  65. }
  66. vec3 ReinhardInverse(in vec3 sdr) {
  67. return sdr / max(1.0 - sdr, 1e-5);
  68. }
  69. // metal NDC y up while texture coord y down,
  70. // keep ndc and texture coord same y direction.
  71. vec2 NDCScToUV(vec4 ndc) {
  72. ndc /= ndc.w;
  73. vec2 uv = ndc.xy * 0.5 + 0.5;
  74. float epsilon = cc_cameraPos.w - 1.0;
  75. if ((epsilon > -0.1) && (epsilon < 0.1)) { // == 1.0
  76. uv.y = -uv.y;
  77. }
  78. return uv;
  79. }
  80. vec2 getVelocity(vec2 unjittedUV, vec2 uv, out float depth) {
  81. // vec3 worldPos = texture(posTex, uv).xyz;
  82. // use unjitted depth for unjitter matrix
  83. depth = texture(depthTex, unjittedUV).r;
  84. vec3 worldPos = screen2WS(vec3(uv, depth));
  85. if (abs(worldPos.x) < 0.0001 && abs(worldPos.y) < 0.0001) {
  86. return vec2(0.);
  87. }
  88. vec4 historyNDC = taaPrevViewProj * vec4(worldPos, 1.);
  89. vec2 screenPos = NDCScToUV(historyNDC);
  90. return screenPos - uv;
  91. }
  92. vec4 clip_aabb(vec3 aabb_min, vec3 aabb_max, vec4 avg, vec4 input_texel) {
  93. vec3 p_clip = 0.5 * (aabb_max + aabb_min);
  94. vec3 e_clip = 0.5 * (aabb_max - aabb_min) + 5.960464478e-8;
  95. vec4 v_clip = input_texel - vec4(p_clip, avg.w);
  96. vec3 v_unit = v_clip.xyz / e_clip;
  97. vec3 a_unit = abs(v_unit);
  98. float ma_unit = max(a_unit.x, max(a_unit.y, a_unit.z));
  99. if (ma_unit > 1.0)
  100. return vec4(p_clip, avg.w) + v_clip / ma_unit;
  101. else
  102. return input_texel;
  103. }
  104. vec3 RGBToYCoCg( vec3 RGB ) {
  105. float Y = dot( RGB, vec3( 1, 2, 1 ) );
  106. float Co = dot( RGB, vec3( 2, 0, -2 ) );
  107. float Cg = dot( RGB, vec3( -1, 2, -1 ) );
  108. return vec3( Y, Co, Cg );
  109. }
  110. vec3 YCoCgToRGB( vec3 YCoCg ) {
  111. float Y = YCoCg.x * 0.25;
  112. float Co = YCoCg.y * 0.25;
  113. float Cg = YCoCg.z * 0.25;
  114. float R = Y + Co - Cg;
  115. float G = Y + Cg;
  116. float B = Y - Co - Cg;
  117. return vec3( R, G, B );
  118. }
  119. vec4 taaSampleTex(sampler2D tex, vec2 uv) {
  120. vec4 color = texture(tex, uv);
  121. color.rgb = RGBToYCoCg(color.rgb);
  122. // color.rgb = Reinhard(color.rgb);
  123. return color;
  124. }
  125. void minmax(sampler2D mainTex, in vec2 uv, out vec4 colorMin, out vec4 colorMax) {
  126. vec2 texSize = taaInputTexSize();
  127. vec2 du = vec2(texSize.x, 0.0);
  128. vec2 dv = vec2(0.0, texSize.y);
  129. vec4 t = taaSampleTex(mainTex, uv - dv);
  130. vec4 l = taaSampleTex(mainTex, uv - du);
  131. vec4 c = taaSampleTex(mainTex, uv);
  132. vec4 r = taaSampleTex(mainTex, uv + du);
  133. vec4 b = taaSampleTex(mainTex, uv + dv);
  134. colorMin = min(t, min(l, min(c, min(r, b))));
  135. colorMax = max(t, max(l, max(c, max(r, b))));
  136. // colorAvg = (t + l + c + r + b) / 5.0;
  137. }
  138. float HdrWeightY(float Color, float Exposure) {
  139. return 1. / (Color * Exposure + 4.0);
  140. // return Color;
  141. }
  142. vec2 WeightedLerpFactors(float WeightA, float WeightB, float Blend) {
  143. float BlendA = (1.0 - Blend) * WeightA;
  144. float BlendB = Blend * WeightB;
  145. float RcpBlend = 1. / (BlendA + BlendB);
  146. BlendA *= RcpBlend;
  147. BlendB *= RcpBlend;
  148. return vec2(BlendA, BlendB);
  149. }
  150. vec4 temporalAAPS (sampler2D taaPrevTexture, sampler2D inputTexture, vec2 uv) {
  151. vec2 unjittedUV = uv - taaParams1.xy / 2.;
  152. vec2 scaledUnjittedUV = unjittedUV;
  153. // vec2 scaledUnjittedUV = (uv - taaParams1.xy / 2.) * cc_view_pr_parameters.x;
  154. // scaledUnjittedUV = min(vec2(cc_view_pr_parameters.x - taaInputTexSize()*2.), scaledUnjittedUV);
  155. float depth = 0.;
  156. vec2 velocity = getVelocity(scaledUnjittedUV, uv, depth);
  157. vec4 prevColor = taaSampleTex(taaPrevTexture, uv + velocity);
  158. vec4 color = taaSampleTex(inputTexture, scaledUnjittedUV);
  159. vec4 colorMin, colorMax;
  160. minmax(inputTexture, scaledUnjittedUV, colorMin, colorMax);
  161. vec3 resultColor;
  162. // clamp
  163. {
  164. // if (cc_view_taa_params2.y == 0. && cc_view_taa_params2.z == 1.) {
  165. prevColor.rgb = clamp(prevColor.rgb, colorMin.rgb, colorMax.rgb);
  166. // }
  167. float blendFinal = 1. - taaParams1.z;
  168. float currentWeight = HdrWeightY(color.x, 1.);
  169. float historyWeight = HdrWeightY(prevColor.x, 1.);
  170. vec2 weights = WeightedLerpFactors(historyWeight, currentWeight, blendFinal);
  171. resultColor = prevColor.rgb * weights.x + color.rgb * weights.y;
  172. // resultColor = mix(color.rgb, prevColor.rgb, blendFinal);
  173. }
  174. // clip
  175. // {
  176. // prevColor = clip_aabb(colorMin.xyz, colorMax.xyz, colorAvg, prevColor);
  177. // resultColor = lerp(color.rgb, prevColor.rgb, cc_view_taa_params2.y);
  178. // }
  179. // if (cc_view_taa_params2.y != 0.) {
  180. // resultColor = prevColor.rgb;
  181. // }
  182. // resultColor = ReinhardInverse(resultColor);
  183. resultColor = YCoCgToRGB(resultColor.rgb);
  184. return vec4(resultColor, color.a);
  185. }
  186. layout(location = 0) out vec4 fragColor;
  187. vec2 taaInputTexSize() {
  188. return taaTextureSize.xy;
  189. }
  190. vec2 taaPrevTexSize () {
  191. return taaTextureSize.zw;
  192. }
  193. void main () {
  194. vec4 mask = vec4(0.);
  195. #if USE_TAA_MASK
  196. mask = texture(motionMaskTex, v_uv);
  197. #endif
  198. if (mask.r > 0.) {
  199. fragColor = texture(inputTexture, v_uv);
  200. }
  201. else {
  202. fragColor = temporalAAPS(taaPrevTexture, inputTexture, v_uv);
  203. }
  204. }
  205. }%