{"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\nclass 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\nexport { Refractor }\n"],"names":["Mesh","PerspectiveCamera","Color","Plane","Matrix4","WebGLRenderTarget","HalfFloatType","ShaderMaterial","UniformsUtils","Vector3","visible","Quaternion","updateRefractorPlane","Vector4","updateVirtualCamera","NoToneMapping","version"],"mappings":"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"}