{"version":3,"file":"Refractor.cjs","sources":["../../src/objects/Refractor.js"],"sourcesContent":["import {\n  Color,\n  Matrix4,\n  Mesh,\n  PerspectiveCamera,\n  Plane,\n  Quaternion,\n  ShaderMaterial,\n  UniformsUtils,\n  Vector3,\n  Vector4,\n  WebGLRenderTarget,\n  NoToneMapping,\n  HalfFloatType,\n} from 'three'\nimport { version } from '../_polyfill/constants'\n\nconst Refractor = /* @__PURE__ */ (() => {\n  class Refractor extends Mesh {\n    static RefractorShader = {\n      uniforms: {\n        color: {\n          value: null,\n        },\n\n        tDiffuse: {\n          value: null,\n        },\n\n        textureMatrix: {\n          value: null,\n        },\n      },\n\n      vertexShader: /* glsl */ `\n\n\t\tuniform mat4 textureMatrix;\n\n\t\tvarying vec4 vUv;\n\n\t\tvoid main() {\n\n\t\t\tvUv = textureMatrix * vec4( position, 1.0 );\n\t\t\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n\n\t\t}`,\n\n      fragmentShader: /* glsl */ `\n\n\t\tuniform vec3 color;\n\t\tuniform sampler2D tDiffuse;\n\n\t\tvarying vec4 vUv;\n\n\t\tfloat blendOverlay( float base, float blend ) {\n\n\t\t\treturn( base < 0.5 ? ( 2.0 * base * blend ) : ( 1.0 - 2.0 * ( 1.0 - base ) * ( 1.0 - blend ) ) );\n\n\t\t}\n\n\t\tvec3 blendOverlay( vec3 base, vec3 blend ) {\n\n\t\t\treturn vec3( blendOverlay( base.r, blend.r ), blendOverlay( base.g, blend.g ), blendOverlay( base.b, blend.b ) );\n\n\t\t}\n\n\t\tvoid main() {\n\n\t\t\tvec4 base = texture2DProj( tDiffuse, vUv );\n\t\t\tgl_FragColor = vec4( blendOverlay( base.rgb, color ), 1.0 );\n\n\t\t\t#include <tonemapping_fragment>\n\t\t\t#include <${version >= 154 ? 'colorspace_fragment' : 'encodings_fragment'}>\n\n\t\t}`,\n    }\n\n    constructor(geometry, options = {}) {\n      super(geometry)\n\n      this.isRefractor = true\n\n      this.type = 'Refractor'\n      this.camera = new PerspectiveCamera()\n\n      const scope = this\n\n      const color = options.color !== undefined ? new Color(options.color) : new Color(0x7f7f7f)\n      const textureWidth = options.textureWidth || 512\n      const textureHeight = options.textureHeight || 512\n      const clipBias = options.clipBias || 0\n      const shader = options.shader || Refractor.RefractorShader\n      const multisample = options.multisample !== undefined ? options.multisample : 4\n\n      //\n\n      const virtualCamera = this.camera\n      virtualCamera.matrixAutoUpdate = false\n      virtualCamera.userData.refractor = true\n\n      //\n\n      const refractorPlane = new Plane()\n      const textureMatrix = new Matrix4()\n\n      // render target\n\n      const renderTarget = new WebGLRenderTarget(textureWidth, textureHeight, {\n        samples: multisample,\n        type: HalfFloatType,\n      })\n\n      // material\n\n      this.material = new ShaderMaterial({\n        uniforms: UniformsUtils.clone(shader.uniforms),\n        vertexShader: shader.vertexShader,\n        fragmentShader: shader.fragmentShader,\n        transparent: true, // ensures, refractors are drawn from farthest to closest\n      })\n\n      this.material.uniforms['color'].value = color\n      this.material.uniforms['tDiffuse'].value = renderTarget.texture\n      this.material.uniforms['textureMatrix'].value = textureMatrix\n\n      // functions\n\n      const visible = (function () {\n        const refractorWorldPosition = new Vector3()\n        const cameraWorldPosition = new Vector3()\n        const rotationMatrix = new Matrix4()\n\n        const view = new Vector3()\n        const normal = new Vector3()\n\n        return function visible(camera) {\n          refractorWorldPosition.setFromMatrixPosition(scope.matrixWorld)\n          cameraWorldPosition.setFromMatrixPosition(camera.matrixWorld)\n\n          view.subVectors(refractorWorldPosition, cameraWorldPosition)\n\n          rotationMatrix.extractRotation(scope.matrixWorld)\n\n          normal.set(0, 0, 1)\n          normal.applyMatrix4(rotationMatrix)\n\n          return view.dot(normal) < 0\n        }\n      })()\n\n      const updateRefractorPlane = (function () {\n        const normal = new Vector3()\n        const position = new Vector3()\n        const quaternion = new Quaternion()\n        const scale = new Vector3()\n\n        return function updateRefractorPlane() {\n          scope.matrixWorld.decompose(position, quaternion, scale)\n          normal.set(0, 0, 1).applyQuaternion(quaternion).normalize()\n\n          // flip the normal because we want to cull everything above the plane\n\n          normal.negate()\n\n          refractorPlane.setFromNormalAndCoplanarPoint(normal, position)\n        }\n      })()\n\n      const updateVirtualCamera = (function () {\n        const clipPlane = new Plane()\n        const clipVector = new Vector4()\n        const q = new Vector4()\n\n        return function updateVirtualCamera(camera) {\n          virtualCamera.matrixWorld.copy(camera.matrixWorld)\n          virtualCamera.matrixWorldInverse.copy(virtualCamera.matrixWorld).invert()\n          virtualCamera.projectionMatrix.copy(camera.projectionMatrix)\n          virtualCamera.far = camera.far // used in WebGLBackground\n\n          // The following code creates an oblique view frustum for clipping.\n          // see: Lengyel, Eric. “Oblique View Frustum Depth Projection and Clipping”.\n          // Journal of Game Development, Vol. 1, No. 2 (2005), Charles River Media, pp. 5–16\n\n          clipPlane.copy(refractorPlane)\n          clipPlane.applyMatrix4(virtualCamera.matrixWorldInverse)\n\n          clipVector.set(clipPlane.normal.x, clipPlane.normal.y, clipPlane.normal.z, clipPlane.constant)\n\n          // calculate the clip-space corner point opposite the clipping plane and\n          // transform it into camera space by multiplying it by the inverse of the projection matrix\n\n          const projectionMatrix = virtualCamera.projectionMatrix\n\n          q.x = (Math.sign(clipVector.x) + projectionMatrix.elements[8]) / projectionMatrix.elements[0]\n          q.y = (Math.sign(clipVector.y) + projectionMatrix.elements[9]) / projectionMatrix.elements[5]\n          q.z = -1.0\n          q.w = (1.0 + projectionMatrix.elements[10]) / projectionMatrix.elements[14]\n\n          // calculate the scaled plane vector\n\n          clipVector.multiplyScalar(2.0 / clipVector.dot(q))\n\n          // replacing the third row of the projection matrix\n\n          projectionMatrix.elements[2] = clipVector.x\n          projectionMatrix.elements[6] = clipVector.y\n          projectionMatrix.elements[10] = clipVector.z + 1.0 - clipBias\n          projectionMatrix.elements[14] = clipVector.w\n        }\n      })()\n\n      // This will update the texture matrix that is used for projective texture mapping in the shader.\n      // see: http://developer.download.nvidia.com/assets/gamedev/docs/projective_texture_mapping.pdf\n\n      function updateTextureMatrix(camera) {\n        // this matrix does range mapping to [ 0, 1 ]\n\n        textureMatrix.set(0.5, 0.0, 0.0, 0.5, 0.0, 0.5, 0.0, 0.5, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 1.0)\n\n        // we use \"Object Linear Texgen\", so we need to multiply the texture matrix T\n        // (matrix above) with the projection and view matrix of the virtual camera\n        // and the model matrix of the refractor\n\n        textureMatrix.multiply(camera.projectionMatrix)\n        textureMatrix.multiply(camera.matrixWorldInverse)\n        textureMatrix.multiply(scope.matrixWorld)\n      }\n\n      //\n\n      function render(renderer, scene, camera) {\n        scope.visible = false\n\n        const currentRenderTarget = renderer.getRenderTarget()\n        const currentXrEnabled = renderer.xr.enabled\n        const currentShadowAutoUpdate = renderer.shadowMap.autoUpdate\n        const currentToneMapping = renderer.toneMapping\n\n        let isSRGB = false\n        if ('outputColorSpace' in renderer) isSRGB = renderer.outputColorSpace === 'srgb'\n        else isSRGB = renderer.outputEncoding === 3001 // sRGBEncoding\n\n        renderer.xr.enabled = false // avoid camera modification\n        renderer.shadowMap.autoUpdate = false // avoid re-computing shadows\n        if ('outputColorSpace' in renderer) renderer.outputColorSpace = 'srgb-linear'\n        else renderer.outputEncoding = 3000 // LinearEncoding\n        renderer.toneMapping = NoToneMapping\n\n        renderer.setRenderTarget(renderTarget)\n        if (renderer.autoClear === false) renderer.clear()\n        renderer.render(scene, virtualCamera)\n\n        renderer.xr.enabled = currentXrEnabled\n        renderer.shadowMap.autoUpdate = currentShadowAutoUpdate\n        renderer.toneMapping = currentToneMapping\n        renderer.setRenderTarget(currentRenderTarget)\n\n        if ('outputColorSpace' in renderer) renderer.outputColorSpace = isSRGB ? 'srgb' : 'srgb-linear'\n        else renderer.outputEncoding = isSRGB ? 3001 : 3000\n\n        // restore viewport\n\n        const viewport = camera.viewport\n\n        if (viewport !== undefined) {\n          renderer.state.viewport(viewport)\n        }\n\n        scope.visible = true\n      }\n\n      //\n\n      this.onBeforeRender = function (renderer, scene, camera) {\n        // ensure refractors are rendered only once per frame\n\n        if (camera.userData.refractor === true) return\n\n        // avoid rendering when the refractor is viewed from behind\n\n        if (!visible(camera) === true) return\n\n        // update\n\n        updateRefractorPlane()\n\n        updateTextureMatrix(camera)\n\n        updateVirtualCamera(camera)\n\n        render(renderer, scene, camera)\n      }\n\n      this.getRenderTarget = function () {\n        return renderTarget\n      }\n\n      this.dispose = function () {\n        renderTarget.dispose()\n        scope.material.dispose()\n      }\n    }\n  }\n\n  return Refractor\n})()\n\nexport { Refractor }\n"],"names":["Mesh","PerspectiveCamera","Color","Plane","Matrix4","WebGLRenderTarget","HalfFloatType","ShaderMaterial","UniformsUtils","Vector3","visible","Quaternion","updateRefractorPlane","Vector4","updateVirtualCamera","NoToneMapping","Refractor","version"],"mappings":"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"}