{"version":3,"file":"DepthLimitedBlurShader.cjs","sources":["../../src/shaders/DepthLimitedBlurShader.ts"],"sourcesContent":["import { Vector2 } from 'three'\nimport type { IUniform, Texture } from 'three'\nimport type { IShader } from './types'\n\nexport type DepthLimitedBlurShaderDefines = {\n  DEPTH_PACKING: number\n  KERNEL_RADIUS: number\n  PERSPECTIVE_CAMERA: number\n}\n\nexport type DepthLimitedBlurShaderUniforms = {\n  cameraFar: IUniform<number>\n  cameraNear: IUniform<number>\n  depthCutoff: IUniform<number>\n  sampleUvOffsets: IUniform<Vector2[]>\n  sampleWeights: IUniform<number[]>\n  size: IUniform<Vector2>\n  tDepth: IUniform<Texture | null>\n  tDiffuse: IUniform<Texture | null>\n}\n\nexport interface IDepthLimitedBlurShader\n  extends IShader<DepthLimitedBlurShaderUniforms, DepthLimitedBlurShaderDefines> {\n  defines: DepthLimitedBlurShaderDefines\n  needsUpdate?: boolean\n}\n\nexport const DepthLimitedBlurShader: IDepthLimitedBlurShader = {\n  defines: {\n    KERNEL_RADIUS: 4,\n    DEPTH_PACKING: 1,\n    PERSPECTIVE_CAMERA: 1,\n  },\n  uniforms: {\n    tDiffuse: { value: null },\n    size: { value: new Vector2(512, 512) },\n    sampleUvOffsets: { value: [new Vector2(0, 0)] },\n    sampleWeights: { value: [1.0] },\n    tDepth: { value: null },\n    cameraNear: { value: 10 },\n    cameraFar: { value: 1000 },\n    depthCutoff: { value: 10 },\n  },\n  vertexShader: [\n    '#include <common>',\n\n    'uniform vec2 size;',\n\n    'varying vec2 vUv;',\n    'varying vec2 vInvSize;',\n\n    'void main() {',\n    '\tvUv = uv;',\n    '\tvInvSize = 1.0 / size;',\n\n    '\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',\n    '}',\n  ].join('\\n'),\n  fragmentShader: [\n    '#include <common>',\n    '#include <packing>',\n\n    'uniform sampler2D tDiffuse;',\n    'uniform sampler2D tDepth;',\n\n    'uniform float cameraNear;',\n    'uniform float cameraFar;',\n    'uniform float depthCutoff;',\n\n    'uniform vec2 sampleUvOffsets[ KERNEL_RADIUS + 1 ];',\n    'uniform float sampleWeights[ KERNEL_RADIUS + 1 ];',\n\n    'varying vec2 vUv;',\n    'varying vec2 vInvSize;',\n\n    'float getDepth( const in vec2 screenPosition ) {',\n    '\t#if DEPTH_PACKING == 1',\n    '\treturn unpackRGBAToDepth( texture2D( tDepth, screenPosition ) );',\n    '\t#else',\n    '\treturn texture2D( tDepth, screenPosition ).x;',\n    '\t#endif',\n    '}',\n\n    'float getViewZ( const in float depth ) {',\n    '\t#if PERSPECTIVE_CAMERA == 1',\n    '\treturn perspectiveDepthToViewZ( depth, cameraNear, cameraFar );',\n    '\t#else',\n    '\treturn orthographicDepthToViewZ( depth, cameraNear, cameraFar );',\n    '\t#endif',\n    '}',\n\n    'void main() {',\n    '\tfloat depth = getDepth( vUv );',\n    '\tif( depth >= ( 1.0 - EPSILON ) ) {',\n    '\t\tdiscard;',\n    '\t}',\n\n    '\tfloat centerViewZ = -getViewZ( depth );',\n    '\tbool rBreak = false, lBreak = false;',\n\n    '\tfloat weightSum = sampleWeights[0];',\n    '\tvec4 diffuseSum = texture2D( tDiffuse, vUv ) * weightSum;',\n\n    '\tfor( int i = 1; i <= KERNEL_RADIUS; i ++ ) {',\n\n    '\t\tfloat sampleWeight = sampleWeights[i];',\n    '\t\tvec2 sampleUvOffset = sampleUvOffsets[i] * vInvSize;',\n\n    '\t\tvec2 sampleUv = vUv + sampleUvOffset;',\n    '\t\tfloat viewZ = -getViewZ( getDepth( sampleUv ) );',\n\n    '\t\tif( abs( viewZ - centerViewZ ) > depthCutoff ) rBreak = true;',\n\n    '\t\tif( ! rBreak ) {',\n    '\t\t\tdiffuseSum += texture2D( tDiffuse, sampleUv ) * sampleWeight;',\n    '\t\t\tweightSum += sampleWeight;',\n    '\t\t}',\n\n    '\t\tsampleUv = vUv - sampleUvOffset;',\n    '\t\tviewZ = -getViewZ( getDepth( sampleUv ) );',\n\n    '\t\tif( abs( viewZ - centerViewZ ) > depthCutoff ) lBreak = true;',\n\n    '\t\tif( ! lBreak ) {',\n    '\t\t\tdiffuseSum += texture2D( tDiffuse, sampleUv ) * sampleWeight;',\n    '\t\t\tweightSum += sampleWeight;',\n    '\t\t}',\n\n    '\t}',\n\n    '\tgl_FragColor = diffuseSum / weightSum;',\n    '}',\n  ].join('\\n'),\n}\n\nexport const BlurShaderUtils = {\n  createSampleWeights: (kernelRadius: number, stdDev: number): number[] => {\n    const gaussian = (x: number, stdDev: number): number => {\n      return Math.exp(-(x * x) / (2.0 * (stdDev * stdDev))) / (Math.sqrt(2.0 * Math.PI) * stdDev)\n    }\n\n    const weights: number[] = []\n\n    for (let i = 0; i <= kernelRadius; i++) {\n      weights.push(gaussian(i, stdDev))\n    }\n\n    return weights\n  },\n\n  createSampleOffsets: (kernelRadius: number, uvIncrement: Vector2): Vector2[] => {\n    const offsets: Vector2[] = []\n\n    for (let i = 0; i <= kernelRadius; i++) {\n      offsets.push(uvIncrement.clone().multiplyScalar(i))\n    }\n\n    return offsets\n  },\n\n  configure: (shader: IDepthLimitedBlurShader, kernelRadius: number, stdDev: number, uvIncrement: Vector2): void => {\n    shader.defines['KERNEL_RADIUS'] = kernelRadius\n    shader.uniforms['sampleUvOffsets'].value = BlurShaderUtils.createSampleOffsets(kernelRadius, uvIncrement)\n    shader.uniforms['sampleWeights'].value = BlurShaderUtils.createSampleWeights(kernelRadius, stdDev)\n    shader.needsUpdate = true\n  },\n}\n"],"names":["Vector2","stdDev"],"mappings":";;;AA2BO,MAAM,yBAAkD;AAAA,EAC7D,SAAS;AAAA,IACP,eAAe;AAAA,IACf,eAAe;AAAA,IACf,oBAAoB;AAAA,EACtB;AAAA,EACA,UAAU;AAAA,IACR,UAAU,EAAE,OAAO,KAAK;AAAA,IACxB,MAAM,EAAE,OAAO,IAAIA,MAAQ,QAAA,KAAK,GAAG,EAAE;AAAA,IACrC,iBAAiB,EAAE,OAAO,CAAC,IAAIA,MAAQ,QAAA,GAAG,CAAC,CAAC,EAAE;AAAA,IAC9C,eAAe,EAAE,OAAO,CAAC,CAAG,EAAE;AAAA,IAC9B,QAAQ,EAAE,OAAO,KAAK;AAAA,IACtB,YAAY,EAAE,OAAO,GAAG;AAAA,IACxB,WAAW,EAAE,OAAO,IAAK;AAAA,IACzB,aAAa,EAAE,OAAO,GAAG;AAAA,EAC3B;AAAA,EACA,cAAc;AAAA,IACZ;AAAA,IAEA;AAAA,IAEA;AAAA,IACA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA,IAEA;AAAA,IACA;AAAA,EAAA,EACA,KAAK,IAAI;AAAA,EACX,gBAAgB;AAAA,IACd;AAAA,IACA;AAAA,IAEA;AAAA,IACA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA,IAEA;AAAA,IACA;AAAA,IAEA;AAAA,IACA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IAEA;AAAA,IACA;AAAA,IAEA;AAAA,IACA;AAAA,IAEA;AAAA,IAEA;AAAA,IACA;AAAA,IAEA;AAAA,IACA;AAAA,IAEA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IAEA;AAAA,IACA;AAAA,IAEA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IAEA;AAAA,IAEA;AAAA,IACA;AAAA,EAAA,EACA,KAAK,IAAI;AACb;AAEO,MAAM,kBAAkB;AAAA,EAC7B,qBAAqB,CAAC,cAAsB,WAA6B;AACjE,UAAA,WAAW,CAAC,GAAWC,YAA2B;AACtD,aAAO,KAAK,IAAI,EAAE,IAAI,MAAM,KAAOA,UAASA,SAAQ,KAAK,KAAK,KAAK,IAAM,KAAK,EAAE,IAAIA;AAAAA,IAAA;AAGtF,UAAM,UAAoB,CAAA;AAE1B,aAAS,IAAI,GAAG,KAAK,cAAc,KAAK;AACtC,cAAQ,KAAK,SAAS,GAAG,MAAM,CAAC;AAAA,IAClC;AAEO,WAAA;AAAA,EACT;AAAA,EAEA,qBAAqB,CAAC,cAAsB,gBAAoC;AAC9E,UAAM,UAAqB,CAAA;AAE3B,aAAS,IAAI,GAAG,KAAK,cAAc,KAAK;AACtC,cAAQ,KAAK,YAAY,MAAQ,EAAA,eAAe,CAAC,CAAC;AAAA,IACpD;AAEO,WAAA;AAAA,EACT;AAAA,EAEA,WAAW,CAAC,QAAiC,cAAsB,QAAgB,gBAA+B;AACzG,WAAA,QAAQ,eAAe,IAAI;AAClC,WAAO,SAAS,iBAAiB,EAAE,QAAQ,gBAAgB,oBAAoB,cAAc,WAAW;AACxG,WAAO,SAAS,eAAe,EAAE,QAAQ,gBAAgB,oBAAoB,cAAc,MAAM;AACjG,WAAO,cAAc;AAAA,EACvB;AACF;;;"}