UNPKG

three-stdlib

Version:

stand-alone library of threejs examples

1 lines 16.4 kB
{"version":3,"file":"ReflectorForSSRPass.cjs","sources":["../../src/objects/ReflectorForSSRPass.js"],"sourcesContent":["import {\n Color,\n Matrix4,\n Mesh,\n PerspectiveCamera,\n ShaderMaterial,\n UniformsUtils,\n Vector2,\n Vector3,\n WebGLRenderTarget,\n DepthTexture,\n UnsignedShortType,\n NearestFilter,\n Plane,\n HalfFloatType,\n} from 'three'\n\nclass ReflectorForSSRPass extends Mesh {\n static ReflectorShader = {\n defines: {\n DISTANCE_ATTENUATION: true,\n FRESNEL: true,\n },\n\n uniforms: {\n color: { value: null },\n tDiffuse: { value: null },\n tDepth: { value: null },\n textureMatrix: { value: new Matrix4() },\n maxDistance: { value: 180 },\n opacity: { value: 0.5 },\n fresnelCoe: { value: null },\n virtualCameraNear: { value: null },\n virtualCameraFar: { value: null },\n virtualCameraProjectionMatrix: { value: new Matrix4() },\n virtualCameraMatrixWorld: { value: new Matrix4() },\n virtualCameraProjectionMatrixInverse: { value: new Matrix4() },\n resolution: { value: new Vector2() },\n },\n\n vertexShader: /* glsl */ `\n\t\tuniform mat4 textureMatrix;\n\t\tvarying vec4 vUv;\n\n\t\tvoid main() {\n\n\t\t\tvUv = textureMatrix * vec4( position, 1.0 );\n\n\t\t\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n\n\t\t}`,\n\n fragmentShader: /* glsl */ `\n\t\tuniform vec3 color;\n\t\tuniform sampler2D tDiffuse;\n\t\tuniform sampler2D tDepth;\n\t\tuniform float maxDistance;\n\t\tuniform float opacity;\n\t\tuniform float fresnelCoe;\n\t\tuniform float virtualCameraNear;\n\t\tuniform float virtualCameraFar;\n\t\tuniform mat4 virtualCameraProjectionMatrix;\n\t\tuniform mat4 virtualCameraProjectionMatrixInverse;\n\t\tuniform mat4 virtualCameraMatrixWorld;\n\t\tuniform vec2 resolution;\n\t\tvarying vec4 vUv;\n\t\t#include <packing>\n\t\tfloat blendOverlay( float base, float blend ) {\n\t\t\treturn( base < 0.5 ? ( 2.0 * base * blend ) : ( 1.0 - 2.0 * ( 1.0 - base ) * ( 1.0 - blend ) ) );\n\t\t}\n\t\tvec3 blendOverlay( vec3 base, vec3 blend ) {\n\t\t\treturn vec3( blendOverlay( base.r, blend.r ), blendOverlay( base.g, blend.g ), blendOverlay( base.b, blend.b ) );\n\t\t}\n\t\tfloat getDepth( const in vec2 uv ) {\n\t\t\treturn texture2D( tDepth, uv ).x;\n\t\t}\n\t\tfloat getViewZ( const in float depth ) {\n\t\t\treturn perspectiveDepthToViewZ( depth, virtualCameraNear, virtualCameraFar );\n\t\t}\n\t\tvec3 getViewPosition( const in vec2 uv, const in float depth/*clip space*/, const in float clipW ) {\n\t\t\tvec4 clipPosition = vec4( ( vec3( uv, depth ) - 0.5 ) * 2.0, 1.0 );//ndc\n\t\t\tclipPosition *= clipW; //clip\n\t\t\treturn ( virtualCameraProjectionMatrixInverse * clipPosition ).xyz;//view\n\t\t}\n\t\tvoid main() {\n\t\t\tvec4 base = texture2DProj( tDiffuse, vUv );\n\t\t\t#ifdef useDepthTexture\n\t\t\t\tvec2 uv=(gl_FragCoord.xy-.5)/resolution.xy;\n\t\t\t\tuv.x=1.-uv.x;\n\t\t\t\tfloat depth = texture2DProj( tDepth, vUv ).r;\n\t\t\t\tfloat viewZ = getViewZ( depth );\n\t\t\t\tfloat clipW = virtualCameraProjectionMatrix[2][3] * viewZ+virtualCameraProjectionMatrix[3][3];\n\t\t\t\tvec3 viewPosition=getViewPosition( uv, depth, clipW );\n\t\t\t\tvec3 worldPosition=(virtualCameraMatrixWorld*vec4(viewPosition,1)).xyz;\n\t\t\t\tif(worldPosition.y>maxDistance) discard;\n\t\t\t\tfloat op=opacity;\n\t\t\t\t#ifdef DISTANCE_ATTENUATION\n\t\t\t\t\tfloat ratio=1.-(worldPosition.y/maxDistance);\n\t\t\t\t\tfloat attenuation=ratio*ratio;\n\t\t\t\t\top=opacity*attenuation;\n\t\t\t\t#endif\n\t\t\t\t#ifdef FRESNEL\n\t\t\t\t\top*=fresnelCoe;\n\t\t\t\t#endif\n\t\t\t\tgl_FragColor = vec4( blendOverlay( base.rgb, color ), op );\n\t\t\t#else\n\t\t\t\tgl_FragColor = vec4( blendOverlay( base.rgb, color ), 1.0 );\n\t\t\t#endif\n\t\t}\n\t`,\n }\n\n constructor(geometry, options = {}) {\n super(geometry)\n\n this.isReflectorForSSRPass = true\n\n this.type = 'ReflectorForSSRPass'\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 || ReflectorForSSRPass.ReflectorShader\n const useDepthTexture = options.useDepthTexture === true\n const yAxis = new Vector3(0, 1, 0)\n const vecTemp0 = new Vector3()\n const vecTemp1 = new Vector3()\n\n //\n\n scope.needsUpdate = false\n scope.maxDistance = ReflectorForSSRPass.ReflectorShader.uniforms.maxDistance.value\n scope.opacity = ReflectorForSSRPass.ReflectorShader.uniforms.opacity.value\n scope.color = color\n scope.resolution = options.resolution || new Vector2(window.innerWidth, window.innerHeight)\n\n scope._distanceAttenuation = ReflectorForSSRPass.ReflectorShader.defines.DISTANCE_ATTENUATION\n Object.defineProperty(scope, 'distanceAttenuation', {\n get() {\n return scope._distanceAttenuation\n },\n set(val) {\n if (scope._distanceAttenuation === val) return\n scope._distanceAttenuation = val\n scope.material.defines.DISTANCE_ATTENUATION = val\n scope.material.needsUpdate = true\n },\n })\n\n scope._fresnel = ReflectorForSSRPass.ReflectorShader.defines.FRESNEL\n Object.defineProperty(scope, 'fresnel', {\n get() {\n return scope._fresnel\n },\n set(val) {\n if (scope._fresnel === val) return\n scope._fresnel = val\n scope.material.defines.FRESNEL = val\n scope.material.needsUpdate = true\n },\n })\n\n const normal = new Vector3()\n const reflectorWorldPosition = new Vector3()\n const cameraWorldPosition = new Vector3()\n const rotationMatrix = new Matrix4()\n const lookAtPosition = new Vector3(0, 0, -1)\n\n const view = new Vector3()\n const target = new Vector3()\n\n const textureMatrix = new Matrix4()\n const virtualCamera = new PerspectiveCamera()\n\n let depthTexture\n\n if (useDepthTexture) {\n depthTexture = new DepthTexture()\n depthTexture.type = UnsignedShortType\n depthTexture.minFilter = NearestFilter\n depthTexture.magFilter = NearestFilter\n }\n\n const parameters = {\n depthTexture: useDepthTexture ? depthTexture : null,\n type: HalfFloatType,\n }\n\n const renderTarget = new WebGLRenderTarget(textureWidth, textureHeight, parameters)\n\n const material = new ShaderMaterial({\n transparent: useDepthTexture,\n defines: Object.assign({}, ReflectorForSSRPass.ReflectorShader.defines, {\n useDepthTexture,\n }),\n uniforms: UniformsUtils.clone(shader.uniforms),\n fragmentShader: shader.fragmentShader,\n vertexShader: shader.vertexShader,\n })\n\n material.uniforms['tDiffuse'].value = renderTarget.texture\n material.uniforms['color'].value = scope.color\n material.uniforms['textureMatrix'].value = textureMatrix\n if (useDepthTexture) {\n material.uniforms['tDepth'].value = renderTarget.depthTexture\n }\n\n this.material = material\n\n const globalPlane = new Plane(new Vector3(0, 1, 0), clipBias)\n const globalPlanes = [globalPlane]\n\n this.doRender = function (renderer, scene, camera) {\n material.uniforms['maxDistance'].value = scope.maxDistance\n material.uniforms['color'].value = scope.color\n material.uniforms['opacity'].value = scope.opacity\n\n vecTemp0.copy(camera.position).normalize()\n vecTemp1.copy(vecTemp0).reflect(yAxis)\n material.uniforms['fresnelCoe'].value = (vecTemp0.dot(vecTemp1) + 1) / 2 // TODO: Also need to use glsl viewPosition and viewNormal per pixel.\n\n reflectorWorldPosition.setFromMatrixPosition(scope.matrixWorld)\n cameraWorldPosition.setFromMatrixPosition(camera.matrixWorld)\n\n rotationMatrix.extractRotation(scope.matrixWorld)\n\n normal.set(0, 0, 1)\n normal.applyMatrix4(rotationMatrix)\n\n view.subVectors(reflectorWorldPosition, cameraWorldPosition)\n\n // Avoid rendering when reflector is facing away\n\n if (view.dot(normal) > 0) return\n\n view.reflect(normal).negate()\n view.add(reflectorWorldPosition)\n\n rotationMatrix.extractRotation(camera.matrixWorld)\n\n lookAtPosition.set(0, 0, -1)\n lookAtPosition.applyMatrix4(rotationMatrix)\n lookAtPosition.add(cameraWorldPosition)\n\n target.subVectors(reflectorWorldPosition, lookAtPosition)\n target.reflect(normal).negate()\n target.add(reflectorWorldPosition)\n\n virtualCamera.position.copy(view)\n virtualCamera.up.set(0, 1, 0)\n virtualCamera.up.applyMatrix4(rotationMatrix)\n virtualCamera.up.reflect(normal)\n virtualCamera.lookAt(target)\n\n virtualCamera.far = camera.far // Used in WebGLBackground\n\n virtualCamera.updateMatrixWorld()\n virtualCamera.projectionMatrix.copy(camera.projectionMatrix)\n\n material.uniforms['virtualCameraNear'].value = camera.near\n material.uniforms['virtualCameraFar'].value = camera.far\n material.uniforms['virtualCameraMatrixWorld'].value = virtualCamera.matrixWorld\n material.uniforms['virtualCameraProjectionMatrix'].value = camera.projectionMatrix\n material.uniforms['virtualCameraProjectionMatrixInverse'].value = camera.projectionMatrixInverse\n material.uniforms['resolution'].value = scope.resolution\n\n // Update the texture matrix\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 textureMatrix.multiply(virtualCamera.projectionMatrix)\n textureMatrix.multiply(virtualCamera.matrixWorldInverse)\n textureMatrix.multiply(scope.matrixWorld)\n\n // scope.visible = false;\n\n const currentRenderTarget = renderer.getRenderTarget()\n\n const currentXrEnabled = renderer.xr.enabled\n const currentShadowAutoUpdate = renderer.shadowMap.autoUpdate\n const currentClippingPlanes = renderer.clippingPlanes\n\n renderer.xr.enabled = false // Avoid camera modification\n renderer.shadowMap.autoUpdate = false // Avoid re-computing shadows\n renderer.clippingPlanes = globalPlanes\n\n renderer.setRenderTarget(renderTarget)\n\n renderer.state.buffers.depth.setMask(true) // make sure the depth buffer is writable so it can be properly cleared, see #18897\n\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.clippingPlanes = currentClippingPlanes\n\n renderer.setRenderTarget(currentRenderTarget)\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 this.getRenderTarget = function () {\n return renderTarget\n }\n }\n}\n\nexport { ReflectorForSSRPass }\n"],"names":["Mesh","Color","Vector3","Vector2","Matrix4","PerspectiveCamera","DepthTexture","UnsignedShortType","NearestFilter","HalfFloatType","WebGLRenderTarget","ShaderMaterial","UniformsUtils","Plane"],"mappings":"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"}