BokehShader.js 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. /**
  2. * @module BokehShader
  3. * @three_import import { BokehShader } from 'three/addons/shaders/BokehShader.js';
  4. */
  5. /**
  6. * Depth-of-field shader with bokeh ported from
  7. * [GLSL shader by Martins Upitis]{@link http://artmartinsh.blogspot.com/2010/02/glsl-lens-blur-filter-with-bokeh.html}.
  8. *
  9. * @constant
  10. * @type {ShaderMaterial~Shader}
  11. */
  12. const BokehShader = {
  13. name: 'BokehShader',
  14. defines: {
  15. 'DEPTH_PACKING': 1,
  16. 'PERSPECTIVE_CAMERA': 1,
  17. },
  18. uniforms: {
  19. 'tColor': { value: null },
  20. 'tDepth': { value: null },
  21. 'focus': { value: 1.0 },
  22. 'aspect': { value: 1.0 },
  23. 'aperture': { value: 0.025 },
  24. 'maxblur': { value: 0.01 },
  25. 'nearClip': { value: 1.0 },
  26. 'farClip': { value: 1000.0 },
  27. },
  28. vertexShader: /* glsl */`
  29. varying vec2 vUv;
  30. void main() {
  31. vUv = uv;
  32. gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
  33. }`,
  34. fragmentShader: /* glsl */`
  35. #include <common>
  36. varying vec2 vUv;
  37. uniform sampler2D tColor;
  38. uniform sampler2D tDepth;
  39. uniform float maxblur; // max blur amount
  40. uniform float aperture; // aperture - bigger values for shallower depth of field
  41. uniform float nearClip;
  42. uniform float farClip;
  43. uniform float focus;
  44. uniform float aspect;
  45. #include <packing>
  46. float getDepth( const in vec2 screenPosition ) {
  47. #if DEPTH_PACKING == 1
  48. return unpackRGBAToDepth( texture2D( tDepth, screenPosition ) );
  49. #else
  50. return texture2D( tDepth, screenPosition ).x;
  51. #endif
  52. }
  53. float getViewZ( const in float depth ) {
  54. #if PERSPECTIVE_CAMERA == 1
  55. return perspectiveDepthToViewZ( depth, nearClip, farClip );
  56. #else
  57. return orthographicDepthToViewZ( depth, nearClip, farClip );
  58. #endif
  59. }
  60. void main() {
  61. vec2 aspectcorrect = vec2( 1.0, aspect );
  62. float viewZ = getViewZ( getDepth( vUv ) );
  63. float factor = ( focus + viewZ ); // viewZ is <= 0, so this is a difference equation
  64. vec2 dofblur = vec2 ( clamp( factor * aperture, -maxblur, maxblur ) );
  65. vec2 dofblur9 = dofblur * 0.9;
  66. vec2 dofblur7 = dofblur * 0.7;
  67. vec2 dofblur4 = dofblur * 0.4;
  68. vec4 col = vec4( 0.0 );
  69. col += texture2D( tColor, vUv.xy );
  70. col += texture2D( tColor, vUv.xy + ( vec2( 0.0, 0.4 ) * aspectcorrect ) * dofblur );
  71. col += texture2D( tColor, vUv.xy + ( vec2( 0.15, 0.37 ) * aspectcorrect ) * dofblur );
  72. col += texture2D( tColor, vUv.xy + ( vec2( 0.29, 0.29 ) * aspectcorrect ) * dofblur );
  73. col += texture2D( tColor, vUv.xy + ( vec2( -0.37, 0.15 ) * aspectcorrect ) * dofblur );
  74. col += texture2D( tColor, vUv.xy + ( vec2( 0.40, 0.0 ) * aspectcorrect ) * dofblur );
  75. col += texture2D( tColor, vUv.xy + ( vec2( 0.37, -0.15 ) * aspectcorrect ) * dofblur );
  76. col += texture2D( tColor, vUv.xy + ( vec2( 0.29, -0.29 ) * aspectcorrect ) * dofblur );
  77. col += texture2D( tColor, vUv.xy + ( vec2( -0.15, -0.37 ) * aspectcorrect ) * dofblur );
  78. col += texture2D( tColor, vUv.xy + ( vec2( 0.0, -0.4 ) * aspectcorrect ) * dofblur );
  79. col += texture2D( tColor, vUv.xy + ( vec2( -0.15, 0.37 ) * aspectcorrect ) * dofblur );
  80. col += texture2D( tColor, vUv.xy + ( vec2( -0.29, 0.29 ) * aspectcorrect ) * dofblur );
  81. col += texture2D( tColor, vUv.xy + ( vec2( 0.37, 0.15 ) * aspectcorrect ) * dofblur );
  82. col += texture2D( tColor, vUv.xy + ( vec2( -0.4, 0.0 ) * aspectcorrect ) * dofblur );
  83. col += texture2D( tColor, vUv.xy + ( vec2( -0.37, -0.15 ) * aspectcorrect ) * dofblur );
  84. col += texture2D( tColor, vUv.xy + ( vec2( -0.29, -0.29 ) * aspectcorrect ) * dofblur );
  85. col += texture2D( tColor, vUv.xy + ( vec2( 0.15, -0.37 ) * aspectcorrect ) * dofblur );
  86. col += texture2D( tColor, vUv.xy + ( vec2( 0.15, 0.37 ) * aspectcorrect ) * dofblur9 );
  87. col += texture2D( tColor, vUv.xy + ( vec2( -0.37, 0.15 ) * aspectcorrect ) * dofblur9 );
  88. col += texture2D( tColor, vUv.xy + ( vec2( 0.37, -0.15 ) * aspectcorrect ) * dofblur9 );
  89. col += texture2D( tColor, vUv.xy + ( vec2( -0.15, -0.37 ) * aspectcorrect ) * dofblur9 );
  90. col += texture2D( tColor, vUv.xy + ( vec2( -0.15, 0.37 ) * aspectcorrect ) * dofblur9 );
  91. col += texture2D( tColor, vUv.xy + ( vec2( 0.37, 0.15 ) * aspectcorrect ) * dofblur9 );
  92. col += texture2D( tColor, vUv.xy + ( vec2( -0.37, -0.15 ) * aspectcorrect ) * dofblur9 );
  93. col += texture2D( tColor, vUv.xy + ( vec2( 0.15, -0.37 ) * aspectcorrect ) * dofblur9 );
  94. col += texture2D( tColor, vUv.xy + ( vec2( 0.29, 0.29 ) * aspectcorrect ) * dofblur7 );
  95. col += texture2D( tColor, vUv.xy + ( vec2( 0.40, 0.0 ) * aspectcorrect ) * dofblur7 );
  96. col += texture2D( tColor, vUv.xy + ( vec2( 0.29, -0.29 ) * aspectcorrect ) * dofblur7 );
  97. col += texture2D( tColor, vUv.xy + ( vec2( 0.0, -0.4 ) * aspectcorrect ) * dofblur7 );
  98. col += texture2D( tColor, vUv.xy + ( vec2( -0.29, 0.29 ) * aspectcorrect ) * dofblur7 );
  99. col += texture2D( tColor, vUv.xy + ( vec2( -0.4, 0.0 ) * aspectcorrect ) * dofblur7 );
  100. col += texture2D( tColor, vUv.xy + ( vec2( -0.29, -0.29 ) * aspectcorrect ) * dofblur7 );
  101. col += texture2D( tColor, vUv.xy + ( vec2( 0.0, 0.4 ) * aspectcorrect ) * dofblur7 );
  102. col += texture2D( tColor, vUv.xy + ( vec2( 0.29, 0.29 ) * aspectcorrect ) * dofblur4 );
  103. col += texture2D( tColor, vUv.xy + ( vec2( 0.4, 0.0 ) * aspectcorrect ) * dofblur4 );
  104. col += texture2D( tColor, vUv.xy + ( vec2( 0.29, -0.29 ) * aspectcorrect ) * dofblur4 );
  105. col += texture2D( tColor, vUv.xy + ( vec2( 0.0, -0.4 ) * aspectcorrect ) * dofblur4 );
  106. col += texture2D( tColor, vUv.xy + ( vec2( -0.29, 0.29 ) * aspectcorrect ) * dofblur4 );
  107. col += texture2D( tColor, vUv.xy + ( vec2( -0.4, 0.0 ) * aspectcorrect ) * dofblur4 );
  108. col += texture2D( tColor, vUv.xy + ( vec2( -0.29, -0.29 ) * aspectcorrect ) * dofblur4 );
  109. col += texture2D( tColor, vUv.xy + ( vec2( 0.0, 0.4 ) * aspectcorrect ) * dofblur4 );
  110. gl_FragColor = col / 41.0;
  111. gl_FragColor.a = 1.0;
  112. }`
  113. };
  114. export { BokehShader };