"use strict"; Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" }); const THREE = require("three"); const SSRShader = { defines: { MAX_STEP: 0, isPerspectiveCamera: true, isDistanceAttenuation: true, isFresnel: true, isInfiniteThick: false, isSelective: false }, uniforms: { tDiffuse: { value: null }, tNormal: { value: null }, tMetalness: { value: null }, tDepth: { value: null }, cameraNear: { value: null }, cameraFar: { value: null }, resolution: { value: /* @__PURE__ */ new THREE.Vector2() }, cameraProjectionMatrix: { value: /* @__PURE__ */ new THREE.Matrix4() }, cameraInverseProjectionMatrix: { value: /* @__PURE__ */ new THREE.Matrix4() }, opacity: { value: 0.5 }, maxDistance: { value: 180 }, cameraRange: { value: 0 }, surfDist: { value: 7e-3 }, thickTolerance: { value: 0.03 } }, vertexShader: ( /* glsl */ ` varying vec2 vUv; void main() { vUv = uv; gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); } ` ), fragmentShader: ( /* glsl */ ` // precision highp float; precision highp sampler2D; varying vec2 vUv; uniform sampler2D tDepth; uniform sampler2D tNormal; uniform sampler2D tMetalness; uniform sampler2D tDiffuse; uniform float cameraRange; uniform vec2 resolution; uniform float opacity; uniform float cameraNear; uniform float cameraFar; uniform float maxDistance; uniform float surfDist; uniform mat4 cameraProjectionMatrix; uniform mat4 cameraInverseProjectionMatrix; uniform float thickTolerance; #include float pointToLineDistance(vec3 x0, vec3 x1, vec3 x2) { //x0: point, x1: linePointA, x2: linePointB //https://mathworld.wolfram.com/Point-LineDistance3-Dimensional.html return length(cross(x0-x1,x0-x2))/length(x2-x1); } float pointPlaneDistance(vec3 point,vec3 planePoint,vec3 planeNormal){ // https://mathworld.wolfram.com/Point-PlaneDistance.html //// https://en.wikipedia.org/wiki/Plane_(geometry) //// http://paulbourke.net/geometry/pointlineplane/ float a=planeNormal.x,b=planeNormal.y,c=planeNormal.z; float x0=point.x,y0=point.y,z0=point.z; float x=planePoint.x,y=planePoint.y,z=planePoint.z; float d=-(a*x+b*y+c*z); float distance=(a*x0+b*y0+c*z0+d)/sqrt(a*a+b*b+c*c); return distance; } float getDepth( const in vec2 uv ) { return texture2D( tDepth, uv ).x; } float getViewZ( const in float depth ) { #ifdef isPerspectiveCamera return perspectiveDepthToViewZ( depth, cameraNear, cameraFar ); #else return orthographicDepthToViewZ( depth, cameraNear, cameraFar ); #endif } vec3 getViewPosition( const in vec2 uv, const in float depth/*clip space*/, const in float clipW ) { vec4 clipPosition = vec4( ( vec3( uv, depth ) - 0.5 ) * 2.0, 1.0 );//ndc clipPosition *= clipW; //clip return ( cameraInverseProjectionMatrix * clipPosition ).xyz;//view } vec3 getViewNormal( const in vec2 uv ) { return unpackRGBToNormal( texture2D( tNormal, uv ).xyz ); } vec2 viewPositionToXY(vec3 viewPosition){ vec2 xy; vec4 clip=cameraProjectionMatrix*vec4(viewPosition,1); xy=clip.xy;//clip float clipW=clip.w; xy/=clipW;//NDC xy=(xy+1.)/2.;//uv xy*=resolution;//screen return xy; } void main(){ #ifdef isSelective float metalness=texture2D(tMetalness,vUv).r; if(metalness==0.) return; #endif float depth = getDepth( vUv ); float viewZ = getViewZ( depth ); if(-viewZ>=cameraFar) return; float clipW = cameraProjectionMatrix[2][3] * viewZ+cameraProjectionMatrix[3][3]; vec3 viewPosition=getViewPosition( vUv, depth, clipW ); vec2 d0=gl_FragCoord.xy; vec2 d1; vec3 viewNormal=getViewNormal( vUv ); #ifdef isPerspectiveCamera vec3 viewIncidenceDir=normalize(viewPosition); vec3 viewReflectDir=reflect(viewIncidenceDir,viewNormal); #else vec3 viewIncidenceDir=vec3(0,0,-1); vec3 viewReflectDir=reflect(viewIncidenceDir,viewNormal); #endif float maxReflectRayLen=maxDistance/dot(-viewIncidenceDir,viewNormal); // dot(a,b)==length(a)*length(b)*cos(theta) // https://www.mathsisfun.com/algebra/vectors-dot-product.html // if(a.isNormalized&&b.isNormalized) dot(a,b)==cos(theta) // maxDistance/maxReflectRayLen=cos(theta) // maxDistance/maxReflectRayLen==dot(a,b) // maxReflectRayLen==maxDistance/dot(a,b) vec3 d1viewPosition=viewPosition+viewReflectDir*maxReflectRayLen; #ifdef isPerspectiveCamera if(d1viewPosition.z>-cameraNear){ //https://tutorial.math.lamar.edu/Classes/CalcIII/EqnsOfLines.aspx float t=(-cameraNear-viewPosition.z)/viewReflectDir.z; d1viewPosition=viewPosition+viewReflectDir*t; } #endif d1=viewPositionToXY(d1viewPosition); float totalLen=length(d1-d0); float xLen=d1.x-d0.x; float yLen=d1.y-d0.y; float totalStep=max(abs(xLen),abs(yLen)); float xSpan=xLen/totalStep; float ySpan=yLen/totalStep; for(float i=0.;i=totalStep) break; vec2 xy=vec2(d0.x+i*xSpan,d0.y+i*ySpan); if(xy.x<0.||xy.x>resolution.x||xy.y<0.||xy.y>resolution.y) break; float s=length(xy-d0)/totalLen; vec2 uv=xy/resolution; float d = getDepth(uv); float vZ = getViewZ( d ); if(-vZ>=cameraFar) continue; float cW = cameraProjectionMatrix[2][3] * vZ+cameraProjectionMatrix[3][3]; vec3 vP=getViewPosition( uv, d, cW ); #ifdef isPerspectiveCamera // https://www.comp.nus.edu.sg/~lowkl/publications/lowk_persp_interp_techrep.pdf float recipVPZ=1./viewPosition.z; float viewReflectRayZ=1./(recipVPZ+s*(1./d1viewPosition.z-recipVPZ)); float sD=surfDist*cW; #else float viewReflectRayZ=viewPosition.z+s*(d1viewPosition.z-viewPosition.z); float sD=surfDist; #endif if(viewReflectRayZ-sD>vZ) continue; #ifdef isInfiniteThick if(viewReflectRayZ+thickTolerance*clipW=0.) continue; float distance=pointPlaneDistance(vP,viewPosition,viewNormal); if(distance>maxDistance) break; #ifdef isDistanceAttenuation float ratio=1.-(distance/maxDistance); float attenuation=ratio*ratio; op=opacity*attenuation; #endif #ifdef isFresnel float fresnel=(dot(viewIncidenceDir,viewReflectDir)+1.)/2.; op*=fresnel; #endif vec4 reflectColor=texture2D(tDiffuse,uv); gl_FragColor.xyz=reflectColor.xyz; gl_FragColor.a=op; break; } } } ` ) }; const SSRDepthShader = { defines: { PERSPECTIVE_CAMERA: 1 }, uniforms: { tDepth: { value: null }, cameraNear: { value: null }, cameraFar: { value: null } }, vertexShader: ( /* glsl */ ` varying vec2 vUv; void main() { vUv = uv; gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); } ` ), fragmentShader: ( /* glsl */ ` uniform sampler2D tDepth; uniform float cameraNear; uniform float cameraFar; varying vec2 vUv; #include float getLinearDepth( const in vec2 uv ) { #if PERSPECTIVE_CAMERA == 1 float fragCoordZ = texture2D( tDepth, uv ).x; float viewZ = perspectiveDepthToViewZ( fragCoordZ, cameraNear, cameraFar ); return viewZToOrthographicDepth( viewZ, cameraNear, cameraFar ); #else return texture2D( tDepth, uv ).x; #endif } void main() { float depth = getLinearDepth( vUv ); float d = 1.0 - depth; // d=(d-.999)*1000.; gl_FragColor = vec4( vec3( d ), 1.0 ); } ` ) }; const SSRBlurShader = { uniforms: { tDiffuse: { value: null }, resolution: { value: /* @__PURE__ */ new THREE.Vector2() }, opacity: { value: 0.5 } }, vertexShader: ( /* glsl */ ` varying vec2 vUv; void main() { vUv = uv; gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); } ` ), fragmentShader: ( /* glsl */ ` uniform sampler2D tDiffuse; uniform vec2 resolution; varying vec2 vUv; void main() { //reverse engineering from PhotoShop blur filter, then change coefficient vec2 texelSize = ( 1.0 / resolution ); vec4 c=texture2D(tDiffuse,vUv); vec2 offset; offset=(vec2(-1,0))*texelSize; vec4 cl=texture2D(tDiffuse,vUv+offset); offset=(vec2(1,0))*texelSize; vec4 cr=texture2D(tDiffuse,vUv+offset); offset=(vec2(0,-1))*texelSize; vec4 cb=texture2D(tDiffuse,vUv+offset); offset=(vec2(0,1))*texelSize; vec4 ct=texture2D(tDiffuse,vUv+offset); // float coeCenter=.5; // float coeSide=.125; float coeCenter=.2; float coeSide=.2; float a=c.a*coeCenter+cl.a*coeSide+cr.a*coeSide+cb.a*coeSide+ct.a*coeSide; vec3 rgb=(c.rgb*c.a*coeCenter+cl.rgb*cl.a*coeSide+cr.rgb*cr.a*coeSide+cb.rgb*cb.a*coeSide+ct.rgb*ct.a*coeSide)/a; gl_FragColor=vec4(rgb,a); } ` ) }; exports.SSRBlurShader = SSRBlurShader; exports.SSRDepthShader = SSRDepthShader; exports.SSRShader = SSRShader; //# sourceMappingURL=SSRShader.cjs.map