(function (global, factory) {
  if (typeof define === "function" && define.amd) {
    define(["exports", "three"], factory);
  } else if (typeof exports !== "undefined") {
    factory(exports, require("three"));
  } else {
    var mod = {
      exports: {}
    };
    factory(mod.exports, global.three);
    global.DepthLimitedBlurShader = mod.exports;
  }
})(typeof globalThis !== "undefined" ? globalThis : typeof self !== "undefined" ? self : this, function (_exports, _three) {
  "use strict";

  Object.defineProperty(_exports, "__esModule", {
    value: true
  });
  _exports.DepthLimitedBlurShader = _exports.BlurShaderUtils = void 0;

  /**
   * TODO
   */
  var DepthLimitedBlurShader = {
    defines: {
      'KERNEL_RADIUS': 4,
      'DEPTH_PACKING': 1,
      'PERSPECTIVE_CAMERA': 1
    },
    uniforms: {
      'tDiffuse': {
        value: null
      },
      'size': {
        value: new _three.Vector2(512, 512)
      },
      'sampleUvOffsets': {
        value: [new _three.Vector2(0, 0)]
      },
      'sampleWeights': {
        value: [1.0]
      },
      'tDepth': {
        value: null
      },
      'cameraNear': {
        value: 10
      },
      'cameraFar': {
        value: 1000
      },
      'depthCutoff': {
        value: 10
      }
    },
    vertexShader:
    /* glsl */
    "\n\n\t\t#include <common>\n\n\t\tuniform vec2 size;\n\n\t\tvarying vec2 vUv;\n\t\tvarying vec2 vInvSize;\n\n\t\tvoid main() {\n\t\t\tvUv = uv;\n\t\t\tvInvSize = 1.0 / size;\n\n\t\t\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n\t\t}",
    fragmentShader:
    /* glsl */
    "\n\n\t\t#include <common>\n\t\t#include <packing>\n\n\t\tuniform sampler2D tDiffuse;\n\t\tuniform sampler2D tDepth;\n\n\t\tuniform float cameraNear;\n\t\tuniform float cameraFar;\n\t\tuniform float depthCutoff;\n\n\t\tuniform vec2 sampleUvOffsets[ KERNEL_RADIUS + 1 ];\n\t\tuniform float sampleWeights[ KERNEL_RADIUS + 1 ];\n\n\t\tvarying vec2 vUv;\n\t\tvarying vec2 vInvSize;\n\n\t\tfloat getDepth( const in vec2 screenPosition ) {\n\t\t\t#if DEPTH_PACKING == 1\n\t\t\treturn unpackRGBAToDepth( texture2D( tDepth, screenPosition ) );\n\t\t\t#else\n\t\t\treturn texture2D( tDepth, screenPosition ).x;\n\t\t\t#endif\n\t\t}\n\n\t\tfloat getViewZ( const in float depth ) {\n\t\t\t#if PERSPECTIVE_CAMERA == 1\n\t\t\treturn perspectiveDepthToViewZ( depth, cameraNear, cameraFar );\n\t\t\t#else\n\t\t\treturn orthographicDepthToViewZ( depth, cameraNear, cameraFar );\n\t\t\t#endif\n\t\t}\n\n\t\tvoid main() {\n\t\t\tfloat depth = getDepth( vUv );\n\t\t\tif( depth >= ( 1.0 - EPSILON ) ) {\n\t\t\t\tdiscard;\n\t\t\t}\n\n\t\t\tfloat centerViewZ = -getViewZ( depth );\n\t\t\tbool rBreak = false, lBreak = false;\n\n\t\t\tfloat weightSum = sampleWeights[0];\n\t\t\tvec4 diffuseSum = texture2D( tDiffuse, vUv ) * weightSum;\n\n\t\t\tfor( int i = 1; i <= KERNEL_RADIUS; i ++ ) {\n\n\t\t\t\tfloat sampleWeight = sampleWeights[i];\n\t\t\t\tvec2 sampleUvOffset = sampleUvOffsets[i] * vInvSize;\n\n\t\t\t\tvec2 sampleUv = vUv + sampleUvOffset;\n\t\t\t\tfloat viewZ = -getViewZ( getDepth( sampleUv ) );\n\n\t\t\t\tif( abs( viewZ - centerViewZ ) > depthCutoff ) rBreak = true;\n\n\t\t\t\tif( ! rBreak ) {\n\t\t\t\t\tdiffuseSum += texture2D( tDiffuse, sampleUv ) * sampleWeight;\n\t\t\t\t\tweightSum += sampleWeight;\n\t\t\t\t}\n\n\t\t\t\tsampleUv = vUv - sampleUvOffset;\n\t\t\t\tviewZ = -getViewZ( getDepth( sampleUv ) );\n\n\t\t\t\tif( abs( viewZ - centerViewZ ) > depthCutoff ) lBreak = true;\n\n\t\t\t\tif( ! lBreak ) {\n\t\t\t\t\tdiffuseSum += texture2D( tDiffuse, sampleUv ) * sampleWeight;\n\t\t\t\t\tweightSum += sampleWeight;\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tgl_FragColor = diffuseSum / weightSum;\n\t\t}"
  };
  _exports.DepthLimitedBlurShader = DepthLimitedBlurShader;
  var BlurShaderUtils = {
    createSampleWeights: function createSampleWeights(kernelRadius, stdDev) {
      var weights = [];

      for (var i = 0; i <= kernelRadius; i++) {
        weights.push(gaussian(i, stdDev));
      }

      return weights;
    },
    createSampleOffsets: function createSampleOffsets(kernelRadius, uvIncrement) {
      var offsets = [];

      for (var i = 0; i <= kernelRadius; i++) {
        offsets.push(uvIncrement.clone().multiplyScalar(i));
      }

      return offsets;
    },
    configure: function configure(material, kernelRadius, stdDev, uvIncrement) {
      material.defines['KERNEL_RADIUS'] = kernelRadius;
      material.uniforms['sampleUvOffsets'].value = BlurShaderUtils.createSampleOffsets(kernelRadius, uvIncrement);
      material.uniforms['sampleWeights'].value = BlurShaderUtils.createSampleWeights(kernelRadius, stdDev);
      material.needsUpdate = true;
    }
  };
  _exports.BlurShaderUtils = BlurShaderUtils;

  function gaussian(x, stdDev) {
    return Math.exp(-(x * x) / (2.0 * (stdDev * stdDev))) / (Math.sqrt(2.0 * Math.PI) * stdDev);
  }
});