|
5 | 5 | * ported from GLSL shader by Martins Upitis |
6 | 6 | * http://artmartinsh.blogspot.com/2010/02/glsl-lens-blur-filter-with-bokeh.html |
7 | 7 | */ |
8 | | - var BokehShader = { |
| 8 | + const BokehShader = { |
9 | 9 | defines: { |
10 | 10 | 'DEPTH_PACKING': 1, |
11 | 11 | 'PERSPECTIVE_CAMERA': 1 |
|
36 | 36 | value: 1000.0 |
37 | 37 | } |
38 | 38 | }, |
39 | | - vertexShader: [ 'varying vec2 vUv;', 'void main() {', ' vUv = uv;', ' gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}' ].join( '\n' ), |
40 | | - fragmentShader: [ '#include <common>', 'varying vec2 vUv;', 'uniform sampler2D tColor;', 'uniform sampler2D tDepth;', 'uniform float maxblur;', // max blur amount |
41 | | - 'uniform float aperture;', // aperture - bigger values for shallower depth of field |
42 | | - 'uniform float nearClip;', 'uniform float farClip;', 'uniform float focus;', 'uniform float aspect;', '#include <packing>', 'float getDepth( const in vec2 screenPosition ) {', ' #if DEPTH_PACKING == 1', ' return unpackRGBAToDepth( texture2D( tDepth, screenPosition ) );', ' #else', ' return texture2D( tDepth, screenPosition ).x;', ' #endif', '}', 'float getViewZ( const in float depth ) {', ' #if PERSPECTIVE_CAMERA == 1', ' return perspectiveDepthToViewZ( depth, nearClip, farClip );', ' #else', ' return orthographicDepthToViewZ( depth, nearClip, farClip );', ' #endif', '}', 'void main() {', ' vec2 aspectcorrect = vec2( 1.0, aspect );', ' float viewZ = getViewZ( getDepth( vUv ) );', ' float factor = ( focus + viewZ );', // viewZ is <= 0, so this is a difference equation |
43 | | - ' vec2 dofblur = vec2 ( clamp( factor * aperture, -maxblur, maxblur ) );', ' vec2 dofblur9 = dofblur * 0.9;', ' vec2 dofblur7 = dofblur * 0.7;', ' vec2 dofblur4 = dofblur * 0.4;', ' vec4 col = vec4( 0.0 );', ' col += texture2D( tColor, vUv.xy );', ' col += texture2D( tColor, vUv.xy + ( vec2( 0.0, 0.4 ) * aspectcorrect ) * dofblur );', ' col += texture2D( tColor, vUv.xy + ( vec2( 0.15, 0.37 ) * aspectcorrect ) * dofblur );', ' col += texture2D( tColor, vUv.xy + ( vec2( 0.29, 0.29 ) * aspectcorrect ) * dofblur );', ' col += texture2D( tColor, vUv.xy + ( vec2( -0.37, 0.15 ) * aspectcorrect ) * dofblur );', ' col += texture2D( tColor, vUv.xy + ( vec2( 0.40, 0.0 ) * aspectcorrect ) * dofblur );', ' col += texture2D( tColor, vUv.xy + ( vec2( 0.37, -0.15 ) * aspectcorrect ) * dofblur );', ' col += texture2D( tColor, vUv.xy + ( vec2( 0.29, -0.29 ) * aspectcorrect ) * dofblur );', ' col += texture2D( tColor, vUv.xy + ( vec2( -0.15, -0.37 ) * aspectcorrect ) * dofblur );', ' col += texture2D( tColor, vUv.xy + ( vec2( 0.0, -0.4 ) * aspectcorrect ) * dofblur );', ' col += texture2D( tColor, vUv.xy + ( vec2( -0.15, 0.37 ) * aspectcorrect ) * dofblur );', ' col += texture2D( tColor, vUv.xy + ( vec2( -0.29, 0.29 ) * aspectcorrect ) * dofblur );', ' col += texture2D( tColor, vUv.xy + ( vec2( 0.37, 0.15 ) * aspectcorrect ) * dofblur );', ' col += texture2D( tColor, vUv.xy + ( vec2( -0.4, 0.0 ) * aspectcorrect ) * dofblur );', ' col += texture2D( tColor, vUv.xy + ( vec2( -0.37, -0.15 ) * aspectcorrect ) * dofblur );', ' col += texture2D( tColor, vUv.xy + ( vec2( -0.29, -0.29 ) * aspectcorrect ) * dofblur );', ' col += texture2D( tColor, vUv.xy + ( vec2( 0.15, -0.37 ) * aspectcorrect ) * dofblur );', ' col += texture2D( tColor, vUv.xy + ( vec2( 0.15, 0.37 ) * aspectcorrect ) * dofblur9 );', ' col += texture2D( tColor, vUv.xy + ( vec2( -0.37, 0.15 ) * aspectcorrect ) * dofblur9 );', ' col += texture2D( tColor, vUv.xy + ( vec2( 0.37, -0.15 ) * aspectcorrect ) * dofblur9 );', ' col += texture2D( tColor, vUv.xy + ( vec2( -0.15, -0.37 ) * aspectcorrect ) * dofblur9 );', ' col += texture2D( tColor, vUv.xy + ( vec2( -0.15, 0.37 ) * aspectcorrect ) * dofblur9 );', ' col += texture2D( tColor, vUv.xy + ( vec2( 0.37, 0.15 ) * aspectcorrect ) * dofblur9 );', ' col += texture2D( tColor, vUv.xy + ( vec2( -0.37, -0.15 ) * aspectcorrect ) * dofblur9 );', ' col += texture2D( tColor, vUv.xy + ( vec2( 0.15, -0.37 ) * aspectcorrect ) * dofblur9 );', ' col += texture2D( tColor, vUv.xy + ( vec2( 0.29, 0.29 ) * aspectcorrect ) * dofblur7 );', ' col += texture2D( tColor, vUv.xy + ( vec2( 0.40, 0.0 ) * aspectcorrect ) * dofblur7 );', ' col += texture2D( tColor, vUv.xy + ( vec2( 0.29, -0.29 ) * aspectcorrect ) * dofblur7 );', ' col += texture2D( tColor, vUv.xy + ( vec2( 0.0, -0.4 ) * aspectcorrect ) * dofblur7 );', ' col += texture2D( tColor, vUv.xy + ( vec2( -0.29, 0.29 ) * aspectcorrect ) * dofblur7 );', ' col += texture2D( tColor, vUv.xy + ( vec2( -0.4, 0.0 ) * aspectcorrect ) * dofblur7 );', ' col += texture2D( tColor, vUv.xy + ( vec2( -0.29, -0.29 ) * aspectcorrect ) * dofblur7 );', ' col += texture2D( tColor, vUv.xy + ( vec2( 0.0, 0.4 ) * aspectcorrect ) * dofblur7 );', ' col += texture2D( tColor, vUv.xy + ( vec2( 0.29, 0.29 ) * aspectcorrect ) * dofblur4 );', ' col += texture2D( tColor, vUv.xy + ( vec2( 0.4, 0.0 ) * aspectcorrect ) * dofblur4 );', ' col += texture2D( tColor, vUv.xy + ( vec2( 0.29, -0.29 ) * aspectcorrect ) * dofblur4 );', ' col += texture2D( tColor, vUv.xy + ( vec2( 0.0, -0.4 ) * aspectcorrect ) * dofblur4 );', ' col += texture2D( tColor, vUv.xy + ( vec2( -0.29, 0.29 ) * aspectcorrect ) * dofblur4 );', ' col += texture2D( tColor, vUv.xy + ( vec2( -0.4, 0.0 ) * aspectcorrect ) * dofblur4 );', ' col += texture2D( tColor, vUv.xy + ( vec2( -0.29, -0.29 ) * aspectcorrect ) * dofblur4 );', ' col += texture2D( tColor, vUv.xy + ( vec2( 0.0, 0.4 ) * aspectcorrect ) * dofblur4 );', ' gl_FragColor = col / 41.0;', ' gl_FragColor.a = 1.0;', '}' ].join( '\n' ) |
| 39 | + vertexShader: `varying vec2 vUv; |
| 40 | +
|
| 41 | + void main() { |
| 42 | +
|
| 43 | + vUv = uv; |
| 44 | + gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); |
| 45 | +
|
| 46 | + }`, |
| 47 | + fragmentShader: `#include <common> |
| 48 | +
|
| 49 | + varying vec2 vUv; |
| 50 | +
|
| 51 | + uniform sampler2D tColor; |
| 52 | + uniform sampler2D tDepth; |
| 53 | +
|
| 54 | + uniform float maxblur; // max blur amount |
| 55 | + uniform float aperture; // aperture - bigger values for shallower depth of field |
| 56 | +
|
| 57 | + uniform float nearClip; |
| 58 | + uniform float farClip; |
| 59 | +
|
| 60 | + uniform float focus; |
| 61 | + uniform float aspect; |
| 62 | +
|
| 63 | + #include <packing> |
| 64 | +
|
| 65 | + float getDepth( const in vec2 screenPosition ) { |
| 66 | + #if DEPTH_PACKING == 1 |
| 67 | + return unpackRGBAToDepth( texture2D( tDepth, screenPosition ) ); |
| 68 | + #else |
| 69 | + return texture2D( tDepth, screenPosition ).x; |
| 70 | + #endif |
| 71 | + } |
| 72 | +
|
| 73 | + float getViewZ( const in float depth ) { |
| 74 | + #if PERSPECTIVE_CAMERA == 1 |
| 75 | + return perspectiveDepthToViewZ( depth, nearClip, farClip ); |
| 76 | + #else |
| 77 | + return orthographicDepthToViewZ( depth, nearClip, farClip ); |
| 78 | + #endif |
| 79 | + } |
| 80 | +
|
| 81 | +
|
| 82 | + void main() { |
| 83 | +
|
| 84 | + vec2 aspectcorrect = vec2( 1.0, aspect ); |
| 85 | +
|
| 86 | + float viewZ = getViewZ( getDepth( vUv ) ); |
| 87 | +
|
| 88 | + float factor = ( focus + viewZ ); // viewZ is <= 0, so this is a difference equation |
| 89 | +
|
| 90 | + vec2 dofblur = vec2 ( clamp( factor * aperture, -maxblur, maxblur ) ); |
| 91 | +
|
| 92 | + vec2 dofblur9 = dofblur * 0.9; |
| 93 | + vec2 dofblur7 = dofblur * 0.7; |
| 94 | + vec2 dofblur4 = dofblur * 0.4; |
| 95 | +
|
| 96 | + vec4 col = vec4( 0.0 ); |
| 97 | +
|
| 98 | + col += texture2D( tColor, vUv.xy ); |
| 99 | + col += texture2D( tColor, vUv.xy + ( vec2( 0.0, 0.4 ) * aspectcorrect ) * dofblur ); |
| 100 | + col += texture2D( tColor, vUv.xy + ( vec2( 0.15, 0.37 ) * aspectcorrect ) * dofblur ); |
| 101 | + col += texture2D( tColor, vUv.xy + ( vec2( 0.29, 0.29 ) * aspectcorrect ) * dofblur ); |
| 102 | + col += texture2D( tColor, vUv.xy + ( vec2( -0.37, 0.15 ) * aspectcorrect ) * dofblur ); |
| 103 | + col += texture2D( tColor, vUv.xy + ( vec2( 0.40, 0.0 ) * aspectcorrect ) * dofblur ); |
| 104 | + col += texture2D( tColor, vUv.xy + ( vec2( 0.37, -0.15 ) * aspectcorrect ) * dofblur ); |
| 105 | + col += texture2D( tColor, vUv.xy + ( vec2( 0.29, -0.29 ) * aspectcorrect ) * dofblur ); |
| 106 | + col += texture2D( tColor, vUv.xy + ( vec2( -0.15, -0.37 ) * aspectcorrect ) * dofblur ); |
| 107 | + col += texture2D( tColor, vUv.xy + ( vec2( 0.0, -0.4 ) * aspectcorrect ) * dofblur ); |
| 108 | + col += texture2D( tColor, vUv.xy + ( vec2( -0.15, 0.37 ) * aspectcorrect ) * dofblur ); |
| 109 | + col += texture2D( tColor, vUv.xy + ( vec2( -0.29, 0.29 ) * aspectcorrect ) * dofblur ); |
| 110 | + col += texture2D( tColor, vUv.xy + ( vec2( 0.37, 0.15 ) * aspectcorrect ) * dofblur ); |
| 111 | + col += texture2D( tColor, vUv.xy + ( vec2( -0.4, 0.0 ) * aspectcorrect ) * dofblur ); |
| 112 | + col += texture2D( tColor, vUv.xy + ( vec2( -0.37, -0.15 ) * aspectcorrect ) * dofblur ); |
| 113 | + col += texture2D( tColor, vUv.xy + ( vec2( -0.29, -0.29 ) * aspectcorrect ) * dofblur ); |
| 114 | + col += texture2D( tColor, vUv.xy + ( vec2( 0.15, -0.37 ) * aspectcorrect ) * dofblur ); |
| 115 | +
|
| 116 | + col += texture2D( tColor, vUv.xy + ( vec2( 0.15, 0.37 ) * aspectcorrect ) * dofblur9 ); |
| 117 | + col += texture2D( tColor, vUv.xy + ( vec2( -0.37, 0.15 ) * aspectcorrect ) * dofblur9 ); |
| 118 | + col += texture2D( tColor, vUv.xy + ( vec2( 0.37, -0.15 ) * aspectcorrect ) * dofblur9 ); |
| 119 | + col += texture2D( tColor, vUv.xy + ( vec2( -0.15, -0.37 ) * aspectcorrect ) * dofblur9 ); |
| 120 | + col += texture2D( tColor, vUv.xy + ( vec2( -0.15, 0.37 ) * aspectcorrect ) * dofblur9 ); |
| 121 | + col += texture2D( tColor, vUv.xy + ( vec2( 0.37, 0.15 ) * aspectcorrect ) * dofblur9 ); |
| 122 | + col += texture2D( tColor, vUv.xy + ( vec2( -0.37, -0.15 ) * aspectcorrect ) * dofblur9 ); |
| 123 | + col += texture2D( tColor, vUv.xy + ( vec2( 0.15, -0.37 ) * aspectcorrect ) * dofblur9 ); |
| 124 | +
|
| 125 | + col += texture2D( tColor, vUv.xy + ( vec2( 0.29, 0.29 ) * aspectcorrect ) * dofblur7 ); |
| 126 | + col += texture2D( tColor, vUv.xy + ( vec2( 0.40, 0.0 ) * aspectcorrect ) * dofblur7 ); |
| 127 | + col += texture2D( tColor, vUv.xy + ( vec2( 0.29, -0.29 ) * aspectcorrect ) * dofblur7 ); |
| 128 | + col += texture2D( tColor, vUv.xy + ( vec2( 0.0, -0.4 ) * aspectcorrect ) * dofblur7 ); |
| 129 | + col += texture2D( tColor, vUv.xy + ( vec2( -0.29, 0.29 ) * aspectcorrect ) * dofblur7 ); |
| 130 | + col += texture2D( tColor, vUv.xy + ( vec2( -0.4, 0.0 ) * aspectcorrect ) * dofblur7 ); |
| 131 | + col += texture2D( tColor, vUv.xy + ( vec2( -0.29, -0.29 ) * aspectcorrect ) * dofblur7 ); |
| 132 | + col += texture2D( tColor, vUv.xy + ( vec2( 0.0, 0.4 ) * aspectcorrect ) * dofblur7 ); |
| 133 | +
|
| 134 | + col += texture2D( tColor, vUv.xy + ( vec2( 0.29, 0.29 ) * aspectcorrect ) * dofblur4 ); |
| 135 | + col += texture2D( tColor, vUv.xy + ( vec2( 0.4, 0.0 ) * aspectcorrect ) * dofblur4 ); |
| 136 | + col += texture2D( tColor, vUv.xy + ( vec2( 0.29, -0.29 ) * aspectcorrect ) * dofblur4 ); |
| 137 | + col += texture2D( tColor, vUv.xy + ( vec2( 0.0, -0.4 ) * aspectcorrect ) * dofblur4 ); |
| 138 | + col += texture2D( tColor, vUv.xy + ( vec2( -0.29, 0.29 ) * aspectcorrect ) * dofblur4 ); |
| 139 | + col += texture2D( tColor, vUv.xy + ( vec2( -0.4, 0.0 ) * aspectcorrect ) * dofblur4 ); |
| 140 | + col += texture2D( tColor, vUv.xy + ( vec2( -0.29, -0.29 ) * aspectcorrect ) * dofblur4 ); |
| 141 | + col += texture2D( tColor, vUv.xy + ( vec2( 0.0, 0.4 ) * aspectcorrect ) * dofblur4 ); |
| 142 | +
|
| 143 | + gl_FragColor = col / 41.0; |
| 144 | + gl_FragColor.a = 1.0; |
| 145 | +
|
| 146 | + }` |
44 | 147 | }; |
45 | 148 |
|
46 | 149 | THREE.BokehShader = BokehShader; |
|
0 commit comments