motion_blur.frag 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. // SuperTuxKart - a fun racing game with go-kart
  2. // Copyright (C) 2013 the SuperTuxKart team
  3. //
  4. // This program is free software; you can redistribute it and/or
  5. // modify it under the terms of the GNU General Public License
  6. // as published by the Free Software Foundation; either version 3
  7. // of the License, or (at your option) any later version.
  8. //
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License
  15. // along with this program; if not, write to the Free Software
  16. // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  17. // motion_blur.frag
  18. // The actual boost amount (which linearly scales the blur to be shown).
  19. // should be in the range [0.0, 1.0], though a larger value might make
  20. // the blurring too string. Atm we are using [0, 0.5].
  21. uniform float boost_amount;
  22. // The color buffer to use.
  23. uniform sampler2D color_buffer;
  24. uniform sampler2D dtex;
  25. // Center (in texture coordinates) at which the kart is. A small circle
  26. // around this center is not blurred (see mask_radius below)
  27. uniform vec2 center;
  28. // Radius of mask around the character in which no blurring happens
  29. // so that the kart doesn't get blurred.
  30. uniform float mask_radius;
  31. uniform mat4 previous_viewproj;
  32. out vec4 FragColor;
  33. // Number of samples used for blurring
  34. #define NB_SAMPLES 8
  35. vec4 getPosFromUVDepth(vec3 uvDepth, mat4 InverseProjectionMatrix);
  36. void main()
  37. {
  38. vec2 texcoords = gl_FragCoord.xy / screen;
  39. // Sample the color buffer
  40. vec3 color = texture(color_buffer, texcoords).rgb;
  41. float z = texture(dtex, texcoords).x;
  42. vec4 ViewPos = getPosFromUVDepth(vec3(texcoords, z), InverseProjectionMatrix);
  43. vec4 OldScreenPos = previous_viewproj * InverseViewMatrix * ViewPos;
  44. OldScreenPos /= OldScreenPos.w;
  45. OldScreenPos = .5 * OldScreenPos + .5;
  46. // Compute the blur direction.
  47. // IMPORTANT: we don't normalize it so that it avoids a glitch around 'center',
  48. // plus it naturally scales the motion blur in a cool way :)
  49. vec2 blur_dir = texcoords - OldScreenPos.xy;
  50. // Compute the blurring factor:
  51. // - apply the mask, i.e. no blurring in a small circle around the kart
  52. float blur_factor = max(0.0, length(texcoords - center) - mask_radius);
  53. // - apply the boost amount
  54. blur_factor *= boost_amount;
  55. // Scale the blur direction
  56. blur_dir *= blur_factor;
  57. // Compute the blur
  58. vec2 inc_vec = blur_dir / vec2(NB_SAMPLES);
  59. vec2 blur_texcoords = texcoords - inc_vec * NB_SAMPLES / 2;
  60. for(int i=1 ; i < NB_SAMPLES ; i++)
  61. {
  62. color += texture(color_buffer, blur_texcoords).rgb;
  63. blur_texcoords += inc_vec;
  64. }
  65. color /= vec3(NB_SAMPLES);
  66. FragColor = vec4(color, 1.0);
  67. }