// From https://github.com/evanw/glfx.js import { Vector2 } from 'three' import DefaultShader from './default' export default { uniforms: { tDiffuse: { value: null }, blurRadius: { value: 0 }, gradientRadius: { value: 0 }, start: { value: new Vector2() }, end: { value: new Vector2() }, delta: { value: new Vector2() }, texSize: { value: new Vector2() }, }, vertexShader: DefaultShader.vertexShader, fragmentShader: ` uniform sampler2D tDiffuse; uniform float blurRadius; uniform float gradientRadius; uniform vec2 start; uniform vec2 end; uniform vec2 delta; uniform vec2 texSize; varying vec2 vUv; float random(vec3 scale, float seed) { /* use the fragment position for a different seed per-pixel */ return fract(sin(dot(gl_FragCoord.xyz + seed, scale)) * 43758.5453 + seed); } void main() { vec4 color = vec4(0.0); float total = 0.0; /* randomize the lookup values to hide the fixed number of samples */ float offset = random(vec3(12.9898, 78.233, 151.7182), 0.0); vec2 normal = normalize(vec2(start.y - end.y, end.x - start.x)); float radius = smoothstep(0.0, 1.0, abs(dot(vUv * texSize - start, normal)) / gradientRadius) * blurRadius; for (float t = -30.0; t <= 30.0; t++) { float percent = (t + offset - 0.5) / 30.0; float weight = 1.0 - abs(percent); vec4 texel = texture2D(tDiffuse, vUv + delta / texSize * percent * radius); // vec4 texel2 = texture2D(tDiffuse, vUv + vec2(-delta.y, delta.x) / texSize * percent * radius); /* switch to pre-multiplied alpha to correctly blur transparent images */ texel.rgb *= texel.a; // texel2.rgb *= texel2.a; color += texel * weight; total += 2.0 * weight; } gl_FragColor = color / total; /* switch back from pre-multiplied alpha */ gl_FragColor.rgb /= gl_FragColor.a + 0.00001; } `, }