Files
behind_glass/dist/assets/OriginalGlassRenderer-BAqBMSXc.js

535 lines
40 KiB
JavaScript

import{a as e,c as t,d as n,f as r,h as i,i as a,l as o,m as s,n as c,o as l,p as u,r as ee,u as d}from"./index-DoRt0pZc.js";var f=`uniform sampler2D uSceneTexture,uSceneDepth;
uniform sampler2D uProtectionDepthMap;
uniform mat4 uContentViewProjection,uContentInverseViewProjection;
uniform mat4 uPetWorldToLocal;
uniform vec3 uContentCameraPosition,uLightPosition,uBackgroundColor;
uniform float uGlassZ,uSourceZ,uGridSize,uStrength,uMosaicStyle,uCurvature,uGlossStrength;
uniform vec2 uViewOffset,uPetSize,uPaneSize;
uniform vec2 uDepthEvidenceRange,uDepthCorrection;
uniform float uEnvironmentStrength;
uniform vec4 uGobangSurface;
uniform float uGobangEnvironmentStrength;
uniform float uGobangBevelRound;
uniform vec4 uPaneRect;
uniform sampler2D uRegionPalette;
uniform sampler2D uRegionAtlas,uRegionHistory;
uniform vec2 uRegionAtlasSize,uRegionGridSize,uRegionPaletteSize;
uniform float uRegionStrength,uRegionAvailable;
varying vec2 vUv;
vec2 projectUv(vec3 p){vec4 c=uContentViewProjection*vec4(p,1.);float w=abs(c.w)<.0001?(c.w<0.?-.0001:.0001):c.w;return c.xy/w*.5+.5;}
vec4 sampleScene(vec2 uv){return texture2D(uSceneTexture,clamp(uv,0.,1.));}
vec4 samplePane(vec2 pane){return sampleScene(projectUv(vec3((pane-.5)*uPaneSize,uGlassZ)));}
float hash(vec2 p){return fract(sin(dot(p,vec2(127.1,311.7)))*43758.5453);}
vec2 hash2(vec2 p){return vec2(hash(p),hash(p+vec2(19.19,73.73)));}
vec2 cellBlurStep(vec2 cell,vec2 cellSize,float style){
if(style<=.5)return cellSize*mix(.006,.018,hash(cell+vec2(5.)));
return cellSize*mix(.006,.012,hash(cell+vec2(5.)));
}
vec4 sampleCell(vec2 pane,vec2 sourceUv,float strength,vec2 cell,vec2 cellSize,float style){
vec2 center=mix(pane,sourceUv,strength);
vec2 blurOffset=strength*cellBlurStep(cell,cellSize,style);
vec4 color;
if(style<=.5){
color=samplePane(center)*.6;
color+=samplePane(center+vec2(blurOffset.x,0.))*.1;
color+=samplePane(center-vec2(blurOffset.x,0.))*.1;
color+=samplePane(center+vec2(0.,blurOffset.y))*.1;
color+=samplePane(center-vec2(0.,blurOffset.y))*.1;
}else{
color=samplePane(center)*.4;
color+=samplePane(center+vec2(blurOffset.x,0.))*.15;
color+=samplePane(center-vec2(blurOffset.x,0.))*.15;
color+=samplePane(center+vec2(0.,blurOffset.y))*.15;
color+=samplePane(center-vec2(0.,blurOffset.y))*.15;
}
return color;
}
float safeZ(float z){return abs(z)<.0001?(z<0.?-.0001:.0001):z;}
vec3 bend(vec3 i,vec3 n){vec3 r=refract(i,n,.75);return length(r)<.0001?i:r;}
float softLimit(float value,float limit){return value*limit/(limit+abs(value));}
float surfaceCurvature(){float curvature=clamp(uCurvature,-1.,1.),excess=max(curvature-.65,0.);return curvature-(.25/.35)*excess*excess;}
float signedCurvatureScale(){return clamp(surfaceCurvature()/.65,-1.25,1.25);}
float regionDistance(vec3 a,vec3 b){vec3 d=a-b;float y=dot(d,vec3(.299,.587,.114));return dot(d,d)+.35*y*y;}
float regionLuminance(vec3 c){return dot(c,vec3(.299,.587,.114));}
vec3 regionColor(vec2 cell,float index){vec2 uv=(vec2(cell.x*5.+index,cell.y)+.5)/uRegionPaletteSize;return texture2D(uRegionPalette,uv).rgb;}
float nearestRegion(vec3 color,vec2 cell){float best=0.,distance=regionDistance(color,regionColor(cell,0.));for(int i=1;i<4;i++){float candidate=regionDistance(color,regionColor(cell,float(i)));if(candidate<distance){distance=candidate;best=float(i);}}return best;}
float nearestRegion(vec3 color,vec3 p0,vec3 p1,vec3 p2,vec3 p3){float best=0.,distance=regionDistance(color,p0);float candidate=regionDistance(color,p1);if(candidate<distance){distance=candidate;best=1.;}candidate=regionDistance(color,p2);if(candidate<distance){distance=candidate;best=2.;}candidate=regionDistance(color,p3);if(candidate<distance)best=3.;return best;}
vec3 selectRegion(vec3 p0,vec3 p1,vec3 p2,vec3 p3,float index){if(index<.5)return p0;if(index<1.5)return p1;if(index<2.5)return p2;return p3;}
vec3 regionAtlasColor(vec2 cell,vec2 texel){vec2 uv=(cell*8.+clamp(texel,vec2(0.),vec2(7.))+.5)/uRegionAtlasSize;return texture2D(uRegionAtlas,uv).rgb;}
bool reconstructScenePoint(vec2 sceneUv,out vec3 worldPoint){
if(sceneUv.x<0.||sceneUv.x>1.||sceneUv.y<0.||sceneUv.y>1.)return false;
float depth=texture2D(uSceneDepth,sceneUv).x;
if(depth>=.999999)return false;
vec4 clip=vec4(sceneUv*2.-1.,depth*2.-1.,1.);
vec4 world=uContentInverseViewProjection*clip;
if(abs(world.w)<.0001)return false;
worldPoint=world.xyz/world.w;
return true;
}
float regionSurfaceValid(vec2 sceneUv,vec3 glassHit){
vec3 worldPoint;
if(!reconstructScenePoint(sceneUv,worldPoint))return 0.;
float axialGap=glassHit.z-worldPoint.z;
if(axialGap<=.0001)return 0.;
return 1.;
}
float regionProtectionWeight(vec2 sceneUv){
vec3 worldPoint;
if(!reconstructScenePoint(sceneUv,worldPoint))return 0.;
vec3 localPoint=(uPetWorldToLocal*vec4(worldPoint,1.)).xyz;
if(localPoint.x<-.5||localPoint.x>.5||localPoint.y<-.5||localPoint.y>.5)return 0.;
vec2 sourceUv=localPoint.xy+.5;
float sourceDepth=texture2D(uProtectionDepthMap,sourceUv).r;
if(uDepthEvidenceRange.y-uDepthEvidenceRange.x<.0001)return 0.;
return smoothstep(uDepthEvidenceRange.x,uDepthEvidenceRange.y,sourceDepth);
}
// Screen-depth refinement of an artistic ray. Occluded surfaces are unavailable;
// retain the original sample if the visible-depth solve cannot converge.
vec3 refineSceneHit(vec3 glassHit,vec3 ray,vec3 artisticHit,float cellWorld){
vec3 planeHit=glassHit+ray*((uSourceZ-glassHit.z)/safeZ(ray.z));
vec3 origin=glassHit+vec3(artisticHit.xy-planeHit.xy,0.);
vec3 hit=artisticHit,surface;
for(int iteration=0;iteration<3;iteration++){
if(!reconstructScenePoint(projectUv(hit),surface))return artisticHit;
vec3 localPoint=(uPetWorldToLocal*vec4(surface,1.)).xyz;
if(any(greaterThan(abs(localPoint.xy),vec2(.5)))||surface.z>=uGlassZ-.0001)return artisticHit;
hit=origin+ray*((surface.z-origin.z)/safeZ(ray.z));
}
if(!reconstructScenePoint(projectUv(hit),surface))return artisticHit;
if(surface.z>=uGlassZ-.0001)return artisticHit;
float confidence=1.-smoothstep(cellWorld*.05,cellWorld*.25,abs(hit.z-surface.z));
// Compare at the same reference Z, so only the projected sampling position changes.
vec3 viewRay=hit-uContentCameraPosition;
vec3 projected=uContentCameraPosition+viewRay*((uSourceZ-uContentCameraPosition.z)/safeZ(viewRay.z));
vec2 delta=projected.xy-artisticHit.xy;
float limit=cellWorld*uDepthCorrection.y;
delta*=min(1.,limit/max(length(delta),.00001));
return artisticHit+vec3(delta*uDepthCorrection.x*confidence,0.);
}
#ifdef REGION_ATLAS
float regionAtlasEvidence(vec2 sceneUv,vec3 color,vec3 glassHit){
if(regionSurfaceValid(sceneUv,glassHit)<=0.)return 0.;
return regionProtectionWeight(sceneUv)*(1.-smoothstep(.10,.20,regionLuminance(color)));
}
vec4 regionAtlasProbe(vec3 sceneHit,vec2 worldOffset,vec3 glassHit){
vec2 probeSceneUv=projectUv(sceneHit+vec3(worldOffset,0.));
vec4 probe=sampleScene(probeSceneUv);
return vec4(probe.rgb,regionAtlasEvidence(probeSceneUv,probe.rgb,glassHit));
}
vec4 regionAtlasScore(vec3 centerColor,float centerEvidence,vec3 probeColor,float probeEvidence){
float evidenceGain=probeEvidence-centerEvidence,darkGain=regionLuminance(centerColor)-regionLuminance(probeColor),blend=0.;
if(probeEvidence>.05&&evidenceGain>.02&&darkGain>.015)blend=min(.4,evidenceGain*2.)*min(1.,max(0.,darkGain*4.));
return vec4(blend,probeEvidence,0.,0.);
}
vec3 regionAtlasRepresentative(vec3 centerColor,float centerEvidence,vec3 sceneHit,vec3 glassHit,out float evidence){
vec3 bestColor=centerColor;float bestEvidence=centerEvidence,bestBlend=0.;
vec2 probeStep=uPaneSize/(uRegionGridSize*8.)*.25;
vec4 probe,score;
probe=regionAtlasProbe(sceneHit,vec2(probeStep.x,0.),glassHit);score=regionAtlasScore(centerColor,centerEvidence,probe.rgb,probe.a);if(score.x>bestBlend){bestColor=mix(centerColor,probe.rgb,score.x);bestEvidence=max(centerEvidence,probe.a);bestBlend=score.x;}
probe=regionAtlasProbe(sceneHit,vec2(-probeStep.x,0.),glassHit);score=regionAtlasScore(centerColor,centerEvidence,probe.rgb,probe.a);if(score.x>bestBlend){bestColor=mix(centerColor,probe.rgb,score.x);bestEvidence=max(centerEvidence,probe.a);bestBlend=score.x;}
probe=regionAtlasProbe(sceneHit,vec2(0.,probeStep.y),glassHit);score=regionAtlasScore(centerColor,centerEvidence,probe.rgb,probe.a);if(score.x>bestBlend){bestColor=mix(centerColor,probe.rgb,score.x);bestEvidence=max(centerEvidence,probe.a);bestBlend=score.x;}
probe=regionAtlasProbe(sceneHit,vec2(0.,-probeStep.y),glassHit);score=regionAtlasScore(centerColor,centerEvidence,probe.rgb,probe.a);if(score.x>bestBlend){bestColor=mix(centerColor,probe.rgb,score.x);bestEvidence=max(centerEvidence,probe.a);bestBlend=score.x;}
evidence=bestEvidence;
return bestColor;
}
#endif
void evaluateCell(vec2 cell,vec2 local,vec2 grid,vec2 cellSize,vec2 cellDimensions,float cellWorld,float opticalTravel,float style,out vec2 affineUv,out mat2 transform,out vec2 curvedSlope,out vec2 facetSlope){
vec2 random=hash2(cell),widths;
if(style>.5){
widths=mix(vec2(.82),vec2(1.12),hash2(cell+vec2(11.4,9.8)));
float angle=(random.x-.5)*.08,c=cos(angle),s=sin(angle);
transform=mat2(widths.x*c,-widths.y*s,widths.x*s,widths.y*c);
float centerJitter=.16;
vec2 sourceCenter=(cell+.5)/grid+(random-.5)*centerJitter*cellSize;
affineUv=sourceCenter+transform*(local*cellSize);
}else{
// Default style keeps a single continuous image footprint across cells.
transform=mat2(1.);
affineUv=(cell+.5)/grid+local*cellSize;
}
// Positive height bulges toward the observer (+Z); negative height is concave.
float curvature=clamp(uCurvature,-1.,1.),surfaceCurvatureValue=surfaceCurvature();
vec2 q=clamp(2.*local,-1.,1.),q2=q*q,q3=q2*q,b=1.-q2*q2;
if(style>.5){
float amplitude=mix(.92,1.08,hash(cell+vec2(41.7,17.3))),height=.009*cellWorld*surfaceCurvatureValue*amplitude;
vec2 skew=(hash2(cell+vec2(23.8,61.2))-.5)*.28;float asym=1.+dot(skew,q);
vec2 dhdq=height*vec2(-4.*q3.x*b.y*asym+b.x*b.y*skew.x,-4.*q3.y*b.x*asym+b.x*b.y*skew.y);
vec2 grad=-2.*dhdq/cellDimensions;
curvedSlope=grad+(random-.5)*.012;facetSlope=(random-.5)*.012;
}else{
curvedSlope=.30*cellDimensions/max(abs(opticalTravel),.6)*signedCurvatureScale()*sin(6.2831853*local);
facetSlope=vec2(0.);
}
}
#ifndef REGION_ATLAS
// Broad prism faces, with narrow rounded transitions at the ridge and center.
// The height and slope meet at cell boundaries; no outline is painted on top.
float gobangProfile(float coordinate,out float derivative){
float span=.5-uGobangSurface.y;
float t=clamp((abs(coordinate)-uGobangSurface.y)/span,0.,1.);
float rounding=uGobangBevelRound,ramp=t-rounding*.5,slope=1.;
if(t<rounding){ramp=t*t/(2.*rounding);slope=t/rounding;}
else if(t>1.-rounding){ramp=1.-rounding-(1.-t)*(1.-t)/(2.*rounding);slope=(1.-t)/rounding;}
derivative=-slope*sign(coordinate)/(span*(1.-rounding));
return 1.-ramp/(1.-rounding);
}
void gobangSurface(vec2 paneUv,vec2 grid,vec2 dimensions,float cellWorld,out float height,out vec3 normal){
vec2 local=fract(paneUv*grid)-.5;
float dx,dy;
float px=gobangProfile(local.x,dx),py=gobangProfile(local.y,dy);
// Crossing directional ribs produce rectangular optical pieces. A minimum
// of X/Y profiles would instead produce conspicuous diagonal triangles.
float shape=.25*px+.55*py+.20*px*py;
vec2 shapeDerivative=vec2((.25+.20*py)*dx,(.55+.20*px)*dy);
// A small continuous ripple bends the ribs without independent cell crops.
vec2 phase=paneUv*grid*6.2831853;
float ripple=.008*sin(phase.x*3.+sin(phase.y))*sin(phase.y);
vec2 rippleDerivative=.008*6.2831853*vec2(3.*cos(phase.x*3.+sin(phase.y))*sin(phase.y),cos(phase.x*3.+sin(phase.y))*cos(phase.y)*sin(phase.y)+sin(phase.x*3.+sin(phase.y))*cos(phase.y));
float amplitude=uGobangSurface.x*cellWorld*clamp(uCurvature,-1.,1.);
height=amplitude*(shape+ripple);
vec2 gradient=amplitude*(shapeDerivative+rippleDerivative)/dimensions;
normal=normalize(vec3(-gradient,1.));
}
vec4 renderGobang(vec3 incident,vec3 glassHit,vec2 paneUv,vec2 grid,float cellWorld){
vec2 dimensions=uPaneSize/grid;
float height;vec3 normal;
gobangSurface(paneUv,grid,dimensions,cellWorld,height,normal);
// Two refinements locate the shallow front surface along this camera ray.
vec3 frontHit=glassHit;
for(int iteration=0;iteration<2;iteration++){
frontHit=uContentCameraPosition+incident*((uGlassZ+height-uContentCameraPosition.z)/safeZ(incident.z));
gobangSurface(frontHit.xy/uPaneSize+.5,grid,dimensions,cellWorld,height,normal);
}
float ior=uGobangSurface.z;
vec3 internalRay=refract(incident,normal,1./ior);
float backZ=uGlassZ-uGobangSurface.w-uGobangSurface.x*cellWorld;
vec3 backHit=frontHit+internalRay*((backZ-frontHit.z)/safeZ(internalRay.z));
vec3 exitRay=refract(internalRay,vec3(0.,0.,1.),ior);
float transmission=step(.0001,dot(exitRay,exitRay));
if(transmission<.5)exitRay=incident;
vec3 sourceHit=backHit+exitRay*((uSourceZ-backHit.z)/safeZ(exitRay.z));
vec3 straightSource=glassHit+incident*((uSourceZ-glassHit.z)/safeZ(incident.z));
float edgeDistance=min(min(paneUv.x,paneUv.y),min(1.-paneUv.x,1.-paneUv.y));
float paneWeight=smoothstep(0.,max(1./grid.x,1./grid.y)*.75,edgeDistance);
float amount=clamp(uStrength,0.,1.)*paneWeight;
sourceHit=mix(straightSource,sourceHit,amount);
// Reuse the visible-depth solve; hidden surfaces still fall back to the plane.
sourceHit=refineSceneHit(backHit,normalize(mix(incident,exitRay,amount)),sourceHit,cellWorld);
vec4 result=sampleScene(projectUv(sourceHit));
// One static room environment; the same surface normal controls its reflection.
vec3 viewDirection=-incident,reflected=reflect(incident,normal);
float fresnel=.04+.96*pow(1.-clamp(dot(normal,viewDirection),0.,1.),5.);
vec3 room=mix(vec3(.09,.13,.17),vec3(.78,.84,.86),smoothstep(-.4,.65,reflected.y));
float lightTravel=(uLightPosition.z-frontHit.z)/safeZ(reflected.z);
vec2 lightUv=(frontHit.xy+reflected.xy*lightTravel-uLightPosition.xy)/(min(uPaneSize.x,uPaneSize.y)*vec2(.38,.52));
vec2 window=1.-smoothstep(vec2(.75),vec2(1.1),abs(lightUv));
float windowLight=window.x*window.y*step(0.,lightTravel)*step(.001,reflected.z);
room=mix(room,vec3(.94,.97,1.),windowLight);
float mullion=1.-smoothstep(.015,.06,abs(reflected.x+.12));
room=mix(room,vec3(.12,.16,.20),mullion*.55);
float gloss=clamp(uGlossStrength,0.,1.);
float reflectionWeight=gloss*uGobangEnvironmentStrength*(.35+.65*fresnel)*amount;
reflectionWeight=mix(reflectionWeight,1.,(1.-transmission)*amount);
result.rgb=mix(result.rgb,room,reflectionWeight);
result.a=1.;
return result;
}
#endif
void main(){
vec2 screenUv=vUv;
#ifdef REGION_ATLAS
vec2 atlasPixel=floor(vUv*uRegionAtlasSize),atlasCell=floor(atlasPixel/8.),atlasLocal=(mod(atlasPixel,8.)+.5)/8.;
vec2 atlasPaneUv=(atlasCell+atlasLocal)/uRegionGridSize;
screenUv=projectUv(vec3((atlasPaneUv-.5)*uPaneSize,uGlassZ));
#endif
if(uStrength<=.001){
#ifdef REGION_ATLAS
gl_FragColor=vec4(sampleScene(screenUv).rgb,0.);
#else
gl_FragColor=sampleScene(screenUv);
#include <colorspace_fragment>
#endif
return;}
vec4 f=uContentInverseViewProjection*vec4(screenUv*2.-1.,1.,1.);float fw=abs(f.w)<.0001?(f.w<0.?-.0001:.0001):f.w;vec3 farWorld=f.xyz/fw;vec3 i=normalize(farWorld-uContentCameraPosition);float gt=(uGlassZ-uContentCameraPosition.z)/safeZ(i.z);vec3 gh=uContentCameraPosition+i*gt;
vec2 paneUv=gh.xy/uPaneSize+.5;vec2 grid=vec2(uGridSize,max(1.,uGridSize*uPaneSize.y/uPaneSize.x));vec2 gridUv=paneUv*grid,cell=floor(gridUv),local=fract(gridUv)-.5,cellSize=1./grid;float style=clamp(uMosaicStyle,0.,2.),cellWorld=min(uPaneSize.x/grid.x,uPaneSize.y/grid.y);
#ifdef REGION_ATLAS
paneUv=atlasPaneUv;grid= uRegionGridSize;gridUv=paneUv*grid;cell=floor(gridUv);local=fract(gridUv)-.5;cellSize=1./grid;cellWorld=min(uPaneSize.x/grid.x,uPaneSize.y/grid.y);
#endif
if(paneUv.x<0.||paneUv.x>1.||paneUv.y<0.||paneUv.y>1.){
#ifdef REGION_ATLAS
gl_FragColor=vec4(uBackgroundColor,0.);
#else
gl_FragColor=vec4(uBackgroundColor,1.);
#include <colorspace_fragment>
#endif
return;}
#ifndef REGION_ATLAS
if(style>1.5){
gl_FragColor=renderGobang(i,gh,paneUv,grid,cellWorld);
#include <colorspace_fragment>
return;
}
#endif
vec2 cellDimensions=uPaneSize/grid;
float opticalTravel=-max(abs(uSourceZ-gh.z),.6);
vec2 affineUv,curvedSlope,facetSlope;mat2 transform;
evaluateCell(cell,local,grid,cellSize,cellDimensions,cellWorld,opticalTravel,style,affineUv,transform,curvedSlope,facetSlope);
if(style<=.5){
vec2 smoothFacet=.003*vec2(sin(6.2831853*paneUv.x),sin(6.2831853*paneUv.y));
curvedSlope+=smoothFacet;facetSlope=smoothFacet;
}else{
vec2 edge=.5-abs(local),neighborSign=mix(vec2(-1.),vec2(1.),step(vec2(0.),local));
float normalBlend=.16;
vec2 weights=1.-smoothstep(vec2(-normalBlend),vec2(normalBlend),edge);
float xSplitWeight=weights.x*(1.-weights.y),ySplitWeight=(1.-weights.x)*weights.y;
float diagonalSplitWeight=weights.x*weights.y,centerSplitWeight=(1.-weights.x)*(1.-weights.y);
if(weights.x>0.||weights.y>0.){
vec2 neighborAffine,neighborCurved,neighborFacet;mat2 neighborTransform;
vec2 xWeight=vec2(xSplitWeight,0.);
vec2 yWeight=vec2(0.,ySplitWeight);
affineUv*=centerSplitWeight;transform*=centerSplitWeight;curvedSlope*=centerSplitWeight;facetSlope*=centerSplitWeight;
if(xWeight.x>0.){
vec2 offset=vec2(neighborSign.x,0.);
evaluateCell(cell+offset,local-offset,grid,cellSize,cellDimensions,cellWorld,opticalTravel,style,neighborAffine,neighborTransform,neighborCurved,neighborFacet);
affineUv+=neighborAffine*xWeight.x;transform+=neighborTransform*xWeight.x;curvedSlope+=neighborCurved*xWeight.x;facetSlope+=neighborFacet*xWeight.x;
}
if(yWeight.y>0.){
vec2 offset=vec2(0.,neighborSign.y);
evaluateCell(cell+offset,local-offset,grid,cellSize,cellDimensions,cellWorld,opticalTravel,style,neighborAffine,neighborTransform,neighborCurved,neighborFacet);
affineUv+=neighborAffine*yWeight.y;transform+=neighborTransform*yWeight.y;curvedSlope+=neighborCurved*yWeight.y;facetSlope+=neighborFacet*yWeight.y;
}
if(diagonalSplitWeight>0.){
vec2 offset=neighborSign;
evaluateCell(cell+offset,local-offset,grid,cellSize,cellDimensions,cellWorld,opticalTravel,style,neighborAffine,neighborTransform,neighborCurved,neighborFacet);
affineUv+=neighborAffine*diagonalSplitWeight;transform+=neighborTransform*diagonalSplitWeight;curvedSlope+=neighborCurved*diagonalSplitWeight;facetSlope+=neighborFacet*diagonalSplitWeight;
}
}
}
vec3 nCurved=normalize(vec3(curvedSlope,1.)),nFacet=normalize(vec3(facetSlope,1.));
vec3 straightHit=gh+i*((uSourceZ-gh.z)/safeZ(i.z));
vec3 curvedRay=bend(i,nCurved),curvedHit=gh+curvedRay*((uSourceZ-gh.z)/safeZ(curvedRay.z));
// Keep the artistic Mosaic optical path independent of physical glass-to-photo contact distance.
vec2 rawDelta=(curvedRay.xy/safeZ(curvedRay.z)-i.xy/safeZ(i.z))*opticalTravel;
vec2 worldDelta=vec2(softLimit(rawDelta.x,cellWorld*.55),softLimit(rawDelta.y,cellWorld*.55));
if(style>.5){
vec3 facetRay=bend(i,nFacet);vec3 facetHit=gh+facetRay*((uSourceZ-gh.z)/safeZ(facetRay.z));
vec2 base=facetHit.xy-straightHit.xy,curve=curvedHit.xy-facetHit.xy;
worldDelta=vec2(softLimit(base.x,cellWorld*.08),softLimit(base.y,cellWorld*.08));
vec2 d=curve/cellWorld;
worldDelta+=vec2(.3*d.x/(.3+abs(d.x)),.3*d.y/(.3+abs(d.y)))*cellWorld;
}else{
vec3 referenceI=normalize(gh-vec3(0.,0.,uContentCameraPosition.z)),referenceRay=bend(referenceI,nCurved);
vec2 incidenceDelta=curvedRay.xy/max(-curvedRay.z,.0001)-referenceRay.xy/max(-referenceRay.z,.0001);
vec2 boundedIncidence=incidenceDelta/sqrt(incidenceDelta*incidenceDelta+vec2(.025*.025));
vec2 cellEnvelope=.5+.5*cos(6.2831853*local);
worldDelta+=boundedIncidence*cellEnvelope*cellDimensions*signedCurvatureScale()*.18;
}
vec2 sampleUv=affineUv+transform*(worldDelta/uPaneSize);
float edgeDistance=min(min(paneUv.x,paneUv.y),min(1.-paneUv.x,1.-paneUv.y));float edgeTaper=style<=.5?1.25:.75;float edgeWeight=smoothstep(0.,max(cellSize.x,cellSize.y)*edgeTaper,edgeDistance);float strength=clamp(uStrength,0.,1.)*edgeWeight;
vec4 color;vec3 sceneHit=straightHit+vec3(worldDelta*strength,0.);vec2 finalSceneUv=projectUv(sceneHit);
if(style<=.5){
sceneHit=refineSceneHit(gh,normalize(mix(i,curvedRay,strength)),sceneHit,cellWorld);
finalSceneUv=projectUv(sceneHit);
}
#ifdef REGION_ATLAS
vec3 atlasCenterColor=sampleScene(finalSceneUv).rgb;
float atlasEvidence=regionProtectionWeight(finalSceneUv)*(1.-smoothstep(.10,.20,regionLuminance(atlasCenterColor)));
#endif
#ifdef REGION_ATLAS
if(style<=.5){
float representativeEvidence=atlasEvidence;
color=vec4(regionAtlasRepresentative(atlasCenterColor,atlasEvidence,sceneHit,gh,representativeEvidence),representativeEvidence);
atlasEvidence=representativeEvidence;
}else{
color=sampleCell(paneUv,sampleUv,strength,cell,cellSize,style);
}
#else
if(style<=.5){
color=sampleScene(finalSceneUv);
}else{
color=sampleCell(paneUv,sampleUv,strength,cell,cellSize,style);
}
#endif
#ifndef REGION_ATLAS
if(uRegionAvailable>.5&&uRegionStrength>.001&&uMosaicStyle<.5){
vec3 p0=regionColor(cell,0.),p1=regionColor(cell,1.),p2=regionColor(cell,2.),p3=regionColor(cell,3.);
float ownLabel=nearestRegion(color.rgb,p0,p1,p2,p3);vec4 votes=vec4(0.);float totalWeight=0.,ownWeight=0.;
vec2 texelCoord=fract(gridUv)*8.-.5,anchor=floor(texelCoord+.5);
for(int y=-1;y<=1;y++)for(int x=-1;x<=1;x++){
vec2 offset=vec2(float(x),float(y)),delta=anchor+offset-texelCoord;
float weight=pow(max(0.,1.-length(delta)/1.5),2.);
if(weight>0.){
vec3 atlasColor=regionAtlasColor(cell,anchor+offset);float label=nearestRegion(atlasColor,p0,p1,p2,p3);
votes+=vec4(step(abs(label-vec4(0.,1.,2.,3.)),vec4(.1)))*weight;totalWeight+=weight;
ownWeight+=step(abs(label-ownLabel),.1)*weight;
}
}
float winningLabel=ownLabel,winningWeight=ownWeight;
if(votes.x>winningWeight){winningLabel=0.;winningWeight=votes.x;}if(votes.y>winningWeight){winningLabel=1.;winningWeight=votes.y;}if(votes.z>winningWeight){winningLabel=2.;winningWeight=votes.z;}if(votes.w>winningWeight){winningLabel=3.;winningWeight=votes.w;}
bool simplify=totalWeight>0.&&winningWeight/totalWeight>.55&&ownWeight/totalWeight<.40;
float radialLabel=simplify?winningLabel:ownLabel;vec3 radialColor=selectRegion(p0,p1,p2,p3,radialLabel);
vec2 historyTexel=clamp(floor(fract(gridUv)*8.),vec2(0.),vec2(7.));
vec2 historyUv=(cell*8.+historyTexel+.5)/uRegionAtlasSize;
vec4 splitHistory=texture2D(uRegionHistory,historyUv);
vec3 splitColor=splitHistory.a>.00001?splitHistory.rgb/splitHistory.a:radialColor;
vec3 candidateColor=mix(radialColor,splitColor,splitHistory.a);
color.rgb=mix(color.rgb,candidateColor,clamp(uRegionStrength*clamp(uStrength,0.,1.)*regionSurfaceValid(finalSceneUv,gh),0.,1.));
}
#endif
#ifndef REGION_ATLAS
color.a=1.;
vec3 v=normalize(uContentCameraPosition-gh),reflected=reflect(-v,nCurved); float lightT=(uLightPosition.z-gh.z)/safeZ(reflected.z); vec2 lightHit=gh.xy+reflected.xy*lightT; vec2 halfSize=vec2(.32,.42)*min(uPaneSize.x,uPaneSize.y); vec2 windowCoord=abs(lightHit-uLightPosition.xy)/halfSize; vec2 windowMask=1.-smoothstep(vec2(.45),vec2(1.15),windowCoord); float surfaceReflectionWeight=mix(.35,1.,edgeWeight); float glossStrength=clamp(uGlossStrength,0.,1.); float spec=windowMask.x*windowMask.y*step(.0001,reflected.z)*step(0.,lightT); float specGloss=spec*glossStrength*.12*surfaceReflectionWeight*clamp(uStrength,0.,1.); vec2 broadWindowMask=1.-smoothstep(vec2(.15),vec2(1.75),windowCoord); float broadFacing=pow(max(dot(nCurved,v),0.),2.); float broadReflection=broadWindowMask.x*broadWindowMask.y*broadFacing*glossStrength*.035*surfaceReflectionWeight*clamp(uStrength,0.,1.); color.rgb=mix(color.rgb,vec3(1.),specGloss+broadReflection); gl_FragColor=color;
// Common, static room environment. Reflected direction varies with the same
// curved normal as transmission; no image relighting or timed sparkle.
float fresnel=.04+.96*pow(1.-clamp(dot(nCurved,v),0.,1.),5.);
float environmentWeight=uEnvironmentStrength*glossStrength*(.35+.65*fresnel)*surfaceReflectionWeight*clamp(uStrength,0.,1.);
vec3 environmentColor=mix(vec3(.10,.13,.18),vec3(.65,.72,.80),smoothstep(-.35,.65,reflected.y));
if(style<=.5)color.rgb=mix(color.rgb,environmentColor,environmentWeight);
gl_FragColor=color;
#include <colorspace_fragment>
#else
color.a=atlasEvidence;
gl_FragColor=color;
#endif
}
`,p=`uniform sampler2D uSceneTexture; uniform mat4 uContentViewProjection; uniform mat4 uContentInverseViewProjection; uniform vec3 uContentCameraPosition,uBackgroundColor; uniform float uSceneZoom; uniform float uGlassZ,uSourceZ,uGridSize,uStrength,uTime; uniform vec2 uSceneOffset,uViewOffset,uResolution,uPetSize,uPaneSize;
varying vec2 vUv;
// Preserve the existing 1x material coordinates as the common projection magnifies and translates.
vec2 patternScreenUv(vec2 uv){return (uv-.5-uSceneOffset*.5)/max(uSceneZoom,1.)+.5;}
vec2 projectUv(vec3 p){vec4 c=uContentViewProjection*vec4(p,1.);float w=abs(c.w)<.0001?(c.w<0.?-.0001:.0001):c.w;return c.xy/w*.5+.5;} vec4 sampleScene(vec2 uv){if(any(lessThan(uv,vec2(0.)))||any(greaterThan(uv,vec2(1.))))return vec4(.005605,.009721,.016807,1.);return texture2D(uSceneTexture,uv);} float hash(float x){return fract(sin(x*91.7)*43758.5453);} float safeZ(float z){return abs(z)<.0001?(z<0.?-.0001:.0001):z;} vec3 bend(vec3 i,vec3 n){vec3 r=refract(i,n,.75);return length(r)<.0001?i:r;}
void main(){if(uStrength<=.001){gl_FragColor=texture2D(uSceneTexture,vUv);
#include <colorspace_fragment>
return;}vec2 q=vUv*2.-1.;vec4 fh=uContentInverseViewProjection*vec4(q,1.,1.);float fwDen=abs(fh.w)<.0001?(fh.w<0.?-.0001:.0001):fh.w;vec3 fw=fh.xyz/fwDen;vec3 i=normalize(fw-uContentCameraPosition);float gt=(uGlassZ-uContentCameraPosition.z)/safeZ(i.z);vec3 gh=uContentCameraPosition+i*gt;vec2 paneUv=gh.xy/uPaneSize+.5;if(any(lessThan(paneUv,vec2(0.)))||any(greaterThan(paneUv,vec2(1.)))){gl_FragColor=vec4(uBackgroundColor,1.);
#include <colorspace_fragment>
return;}float count=max(1.,uGridSize*uPetSize.x/uPetSize.y),coord=patternScreenUv(vUv).x*count,cell=floor(coord),phase=fract(coord)*6.2831853,ridge=sin(phase+uViewOffset.x*.9),variation=mix(.92,1.08,hash(cell));vec3 r=bend(i,normalize(vec3(-ridge*.34*variation,0.,1.)));vec3 sh=gh+i*((uSourceZ-gh.z)/safeZ(i.z)),bh=gh+r*((uSourceZ-gh.z)/safeZ(r.z));vec2 ru=vUv+projectUv(bh)-projectUv(sh);vec2 uv=mix(vUv,ru,clamp(uStrength,0.,1.));vec4 c=sampleScene(uv);c.a=1.;gl_FragColor=c;
#include <colorspace_fragment>
}
`,m=`uniform sampler2D uSceneTexture; uniform mat4 uContentViewProjection; uniform mat4 uContentInverseViewProjection; uniform vec3 uContentCameraPosition,uBackgroundColor; uniform float uSceneZoom; uniform float uGlassZ,uSourceZ,uGridSize,uStrength,uTime; uniform vec2 uSceneOffset,uViewOffset,uResolution,uPetSize,uPaneSize;
varying vec2 vUv;
// Preserve the existing 1x material coordinates as the common projection magnifies and translates.
vec2 patternScreenUv(vec2 uv){return (uv-.5-uSceneOffset*.5)/max(uSceneZoom,1.)+.5;}
vec2 projectUv(vec3 p){vec4 c=uContentViewProjection*vec4(p,1.);float w=abs(c.w)<.0001?(c.w<0.?-.0001:.0001):c.w;return c.xy/w*.5+.5;} vec4 sampleScene(vec2 uv){if(any(lessThan(uv,vec2(0.)))||any(greaterThan(uv,vec2(1.))))return vec4(.005605,.009721,.016807,1.);return texture2D(uSceneTexture,uv);} float hash(vec2 p){return fract(sin(dot(p,vec2(41.3,17.9)))*15731.743);} float noise(vec2 p){vec2 i=floor(p),f=fract(p);f=f*f*(3.-2.*f);return mix(mix(hash(i),hash(i+vec2(1.,0.)),f.x),mix(hash(i+vec2(0.,1.)),hash(i+vec2(1.)),f.x),f.y);} float safeZ(float z){return abs(z)<.0001?(z<0.?-.0001:.0001):z;} vec3 bend(vec3 i,vec3 n){vec3 r=refract(i,n,.75);return length(r)<.0001?i:r;}
void main(){if(uStrength<=.001){gl_FragColor=texture2D(uSceneTexture,vUv);
#include <colorspace_fragment>
return;}vec2 q=vUv*2.-1.;vec4 fh=uContentInverseViewProjection*vec4(q,1.,1.);float fwDen=abs(fh.w)<.0001?(fh.w<0.?-.0001:.0001):fh.w;vec3 fw=fh.xyz/fwDen;vec3 i=normalize(fw-uContentCameraPosition);float gt=(uGlassZ-uContentCameraPosition.z)/safeZ(i.z);vec3 gh=uContentCameraPosition+i*gt;vec2 paneUv=gh.xy/uPaneSize+.5;if(any(lessThan(paneUv,vec2(0.)))||any(greaterThan(paneUv,vec2(1.)))){gl_FragColor=vec4(uBackgroundColor,1.);
#include <colorspace_fragment>
return;}vec2 st=patternScreenUv(vUv)*(uResolution/max(uResolution.y,1.)),np=st*9.+uViewOffset*.6,nn=vec2(noise(np),noise(np+vec2(23.7)))-vec2(.5);vec3 r=bend(i,normalize(vec3(nn*.32,1.)));vec3 sh=gh+i*((uSourceZ-gh.z)/safeZ(i.z)),bh=gh+r*((uSourceZ-gh.z)/safeZ(r.z));vec2 ru=vUv+projectUv(bh)-projectUv(sh),center=mix(vUv,ru,clamp(uStrength,0.,1.)),rad=vec2(.008)*uSceneZoom*clamp(uStrength,0.,1.);vec4 c=vec4(0.);c+=sampleScene(center+vec2(-rad.x,-rad.y));c+=sampleScene(center+vec2(0.,-rad.y));c+=sampleScene(center+vec2(rad.x,-rad.y));c+=sampleScene(center+vec2(-rad.x,0.));c+=sampleScene(center);c+=sampleScene(center+vec2(rad.x,0.));c+=sampleScene(center+vec2(-rad.x,rad.y));c+=sampleScene(center+vec2(0.,rad.y));c+=sampleScene(center+vec2(rad.x,rad.y));c/=9.;c.a=1.;gl_FragColor=c;
#include <colorspace_fragment>
}
`,h=`varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = vec4(position.xy, 0.0, 1.0);
}
`,g=`uniform sampler2D uRegionAtlas;
uniform vec2 uRegionAtlasSize,uRegionGridSize;
varying vec2 vUv;
float regionLuminance(vec3 c){return dot(c,vec3(.299,.587,.114));}
float distanceColor(vec3 a,vec3 b){vec3 d=a-b;float y=dot(d,vec3(.299,.587,.114));return dot(d,d)+.35*y*y;}
float sideColorCost(vec4 votes,vec3 target,vec3 c0,vec3 c1,vec3 c2,vec3 c3){return votes.x*distanceColor(c0,target)+votes.y*distanceColor(c1,target)+votes.z*distanceColor(c2,target)+votes.w*distanceColor(c3,target);}
vec4 atlasSampleData(vec2 cell,vec2 local){vec2 uv=(cell*8.+local+.5)/uRegionAtlasSize;return texture2D(uRegionAtlas,uv);}
vec3 atlasSample(vec2 cell,vec2 local){return atlasSampleData(cell,local).rgb;}
float nearestLabel(vec3 color,vec3 c0,vec3 c1,vec3 c2,vec3 c3){float d0=distanceColor(color,c0),d1=distanceColor(color,c1),d2=distanceColor(color,c2),d3=distanceColor(color,c3);if(d0<=d1&&d0<=d2&&d0<=d3)return 0.;if(d1<=d2&&d1<=d3)return 1.;if(d2<=d3)return 2.;return 3.;}
float majorityLabel(vec4 votes){float label=0.,count=votes.x;if(votes.y>count){label=1.;count=votes.y;}if(votes.z>count){label=2.;count=votes.z;}if(votes.w>count)label=3.;return label;}
void main(){
vec2 pixel=floor(gl_FragCoord.xy);float paletteIndex=mod(pixel.x,5.);vec3 cell=vec3(floor(pixel.x/5.),pixel.y,0.);
vec3 darkest=vec3(1.),lightest=vec3(0.);float minLum=2.,maxLum=-1.;
for(int y=0;y<8;y++)for(int x=0;x<8;x++){
vec3 c=atlasSample(cell.xy,vec2(float(x),float(y)));float l=regionLuminance(c);
if(l<minLum){minLum=l;darkest=c;}if(l>maxLum){maxLum=l;lightest=c;}
}
vec3 third=darkest;float thirdDistance=-1.;
for(int y=0;y<8;y++)for(int x=0;x<8;x++){
vec3 c=atlasSample(cell.xy,vec2(float(x),float(y)));float d=min(distanceColor(c,darkest),distanceColor(c,lightest));
if(d>thirdDistance){thirdDistance=d;third=c;}
}
vec3 fourth=darkest;float fourthDistance=-1.;
for(int y=0;y<8;y++)for(int x=0;x<8;x++){
vec3 c=atlasSample(cell.xy,vec2(float(x),float(y)));float d=min(distanceColor(c,darkest),min(distanceColor(c,lightest),distanceColor(c,third)));
if(d>fourthDistance){fourthDistance=d;fourth=c;}
}
vec3 c0=darkest,c1=lightest,c2=third,c3=fourth;
for(int iteration=0;iteration<2;iteration++){
vec3 sum0=vec3(0.),sum1=vec3(0.),sum2=vec3(0.),sum3=vec3(0.);float n0=0.,n1=0.,n2=0.,n3=0.;
for(int y=0;y<8;y++)for(int x=0;x<8;x++){
vec3 c=atlasSample(cell.xy,vec2(float(x),float(y)));
float d0=distanceColor(c,c0),d1=distanceColor(c,c1),d2=distanceColor(c,c2),d3=distanceColor(c,c3);
if(d0<=d1&&d0<=d2&&d0<=d3){sum0+=c;n0+=1.;}
else if(d1<=d2&&d1<=d3){sum1+=c;n1+=1.;}
else if(d2<=d3){sum2+=c;n2+=1.;}
else{sum3+=c;n3+=1.;}
}
if(n0>0.)c0=sum0/n0;if(n1>0.)c1=sum1/n1;if(n2>0.)c2=sum2/n2;if(n3>0.)c3=sum3/n3;
}
vec4 metadata=vec4(0.);
if(paletteIndex>3.5){
vec4 wholeVotes=vec4(0.);float cellEvidence=0.;
for(int y=0;y<8;y++)for(int x=0;x<8;x++){
vec4 sampleData=atlasSampleData(cell.xy,vec2(float(x),float(y)));vec3 c=sampleData.rgb;float label=nearestLabel(c,c0,c1,c2,c3);
wholeVotes+=vec4(step(abs(label-vec4(0.,1.,2.,3.)),vec4(.1)));
cellEvidence+=sampleData.a;
}
float singleMajority=max(max(wholeVotes.x,wholeVotes.y),max(wholeVotes.z,wholeVotes.w))/64.;
float bestCost=1e20,bestConfidence=0.,bestAxis=0.,bestCut=4.,bestA=0.,bestB=0.;
for(int axis=0;axis<2;axis++)for(int candidateIndex=0;candidateIndex<5;candidateIndex++){
float cut=4.;
if(candidateIndex==1)cut=3.;else if(candidateIndex==2)cut=5.;else if(candidateIndex==3)cut=2.;else if(candidateIndex==4)cut=6.;
vec4 votesA=vec4(0.),votesB=vec4(0.),weightedVotesA=vec4(0.),weightedVotesB=vec4(0.);
for(int y=0;y<8;y++)for(int x=0;x<8;x++){
vec4 sampleData=atlasSampleData(cell.xy,vec2(float(x),float(y)));vec3 c=sampleData.rgb;float label=nearestLabel(c,c0,c1,c2,c3);
vec4 oneHot=vec4(step(abs(label-vec4(0.,1.,2.,3.)),vec4(.1)));float sampleWeight=1.+3.*sampleData.a;
float coordinate=axis==0?float(x)+.5:float(y)+.5;
if(coordinate<cut){votesA+=oneHot;weightedVotesA+=oneHot*sampleWeight;}
else{votesB+=oneHot;weightedVotesB+=oneHot*sampleWeight;}
}
float labelA=0.,labelB=0.,pairCost=1e20,pairVotes=0.;
for(int a=0;a<4;a++)for(int b=0;b<4;b++){
if(a!=b&&votesA[a]>0.&&votesB[b]>0.){
vec3 colorA=a==0?c0:(a==1?c1:(a==2?c2:c3));
vec3 colorB=b==0?c0:(b==1?c1:(b==2?c2:c3));
float candidateCost=sideColorCost(weightedVotesA,colorA,c0,c1,c2,c3)+sideColorCost(weightedVotesB,colorB,c0,c1,c2,c3);
if(candidateCost<pairCost){pairCost=candidateCost;labelA=float(a);labelB=float(b);pairVotes=votesA[a]+votesB[b];}
}
}
if(pairCost<1e20){
float accuracy=pairVotes/64.,gain=accuracy-singleMajority;
float oldConfidence=smoothstep(.55,.75,accuracy)*smoothstep(.015625,.078125,gain);
float confidence=.85+.15*oldConfidence;
confidence=mix(confidence,1.,smoothstep(.02,.06,cellEvidence/64.));
if(pairCost<bestCost){bestCost=pairCost;bestConfidence=confidence;bestAxis=float(axis);bestCut=cut;bestA=labelA;bestB=labelB;}
}
}
metadata=vec4((bestAxis*8.+bestCut)/255.,bestA/255.,bestB/255.,bestConfidence);
}
vec3 result=c0;
if(paletteIndex>.5&&paletteIndex<1.5)result=c1;
else if(paletteIndex>1.5&&paletteIndex<2.5)result=c2;
else if(paletteIndex>2.5&&paletteIndex<3.5)result=c3;
gl_FragColor=paletteIndex>3.5?metadata:vec4(result,1.);
}
`,_=`uniform sampler2D uRegionPalette,uPreviousHistory;
uniform vec2 uRegionAtlasSize,uRegionGridSize,uRegionPaletteSize;
uniform float uHistoryBlend;
varying vec2 vUv;
vec3 paletteColor(vec2 cell,float label){vec2 uv=(vec2(cell.x*5.+label,cell.y)+.5)/uRegionPaletteSize;return texture2D(uRegionPalette,uv).rgb;}
void main(){
vec2 pixel=floor(vUv*uRegionAtlasSize),cell=floor(pixel/8.),local=(mod(pixel,8.)+.5)/8.;
vec2 metadataUv=(vec2(cell.x*5.+4.,cell.y)+.5)/uRegionPaletteSize;
vec4 metadata=texture2D(uRegionPalette,metadataUv);
float packed=floor(metadata.r*255.+.5),axis=floor(packed/8.),cut=packed-axis*8.;
float coordinate=axis<.5?local.x:local.y;
float label=coordinate<cut/8.?floor(metadata.g*255.+.5):floor(metadata.b*255.+.5);
float confidence=clamp(metadata.a,0.,1.);
vec4 current=vec4(paletteColor(cell,label)*confidence,confidence);
if(uHistoryBlend>=.9999){gl_FragColor=current;return;}
vec4 previous=texture2D(uPreviousHistory,vUv);
gl_FragColor=mix(previous,current,clamp(uHistoryBlend,0.,1.));
}
`;function v(v){let{renderer:y,scene:b,frameScene:te,camera:x,petDepth:S,uniforms:C,depthUniforms:w,emptyTex:ne,regionHistoryUniform:T,state:E}=v,D=new n,O=new r({uniforms:C,vertexShader:h,fragmentShader:f}),k=new l(new d(2,2),O);D.add(k);let A=new n,j=new r({uniforms:C,vertexShader:h,fragmentShader:f,defines:{REGION_ATLAS:1},toneMapped:!1}),M=new l(new d(2,2),j);A.add(M);let N=new n,P={uRegionAtlas:{value:null},uRegionAtlasSize:C.uRegionAtlasSize,uRegionGridSize:C.uRegionGridSize},F=new r({uniforms:P,vertexShader:h,fragmentShader:g,toneMapped:!1}),I=new l(new d(2,2),F);N.add(I);let L=new o(-1,1,1,-1,0,1),R=new i(1,1,{colorSpace:``,type:e,depthBuffer:!0});R.depthTexture=new a(1,1,s),R.depthTexture.format=ee,C.uSceneDepth.value=R.depthTexture;let z=new i(104,104,{colorSpace:``,type:e,depthBuffer:!1,minFilter:t,magFilter:t}),B=new i(65,13,{colorSpace:``,type:u,depthBuffer:!1,minFilter:t,magFilter:t}),V=[0,1].map(()=>new i(104,104,{colorSpace:``,type:e,depthBuffer:!1,minFilter:t,magFilter:t})),H=new n,U={uRegionPalette:{value:B.texture},uPreviousHistory:{value:V[0].texture},uRegionAtlasSize:C.uRegionAtlasSize,uRegionGridSize:C.uRegionGridSize,uRegionPaletteSize:C.uRegionPaletteSize,uHistoryBlend:{value:1}},W=new r({uniforms:U,vertexShader:h,fragmentShader:_,toneMapped:!1}),G=new l(new d(2,2),W);H.add(G),C.uRegionPalette.value=B.texture,P.uRegionAtlas.value=z.texture;let K=``,q=``,J=0,Y=!1;function X(){let e=Math.max(1,Math.ceil(C.uGridSize.value)),t=Math.max(1,C.uGridSize.value*C.uPaneSize.value.y/Math.max(C.uPaneSize.value.x,.001)),n=Math.ceil(t),r=e*8,i=n*8,a=e*5,o=n,s=Math.max(r,i,a,o)<=y.capabilities.maxTextureSize,c=C.uRegionAvailable.value!==+!!s||s&&(z.width!==r||z.height!==i||B.width!==a||B.height!==o||V[0].width!==r||V[0].height!==i)||C.uRegionGridSize.value.x!==C.uGridSize.value||C.uRegionGridSize.value.y!==t;s&&(z.width!==r||z.height!==i)&&z.setSize(r,i),s&&(B.width!==a||B.height!==o)&&B.setSize(a,o);for(let e of V)s&&(e.width!==r||e.height!==i)&&e.setSize(r,i);C.uRegionAvailable.value=+!!s,C.uRegionAtlasSize.value.set(s?r:z.width,s?i:z.height),C.uRegionGridSize.value.set(C.uGridSize.value,t),C.uRegionPaletteSize.value.set(s?a:B.width,s?o:B.height),P.uRegionAtlas.value=z.texture,C.uRegionPalette.value=B.texture,C.uRegionAtlas.value=z.texture,c&&(K=``)}function Z(){let{mode:e,active:t,activeIsVideo:n,effect:r,style:i}=E(),a=C.uContentViewProjection.value.elements.map(e=>e.toFixed(4)).join(`,`),o=S.matrixWorld.elements.map(e=>e.toFixed(4)).join(`,`),s=w.uDepthMap.value;return[e,t.uuid,s.uuid,a,o,C.uGridSize.value,C.uStrength.value,C.uCurvature.value,C.uMosaicStyle.value,C.uPaneSize.value.x,C.uPaneSize.value.y,w.uDepthScale.value,w.uDepthBias.value,R.width,R.height,z.width,z.height].join(`|`)}function re(){let{mode:e,active:t,effect:n,style:r}=E(),i=S.matrixWorld.elements.map(e=>e.toFixed(4)).join(`,`),a=w.uDepthMap.value;return[e,n,r,t.uuid,a.uuid,C.uRegionAvailable.value,C.uGridSize.value,C.uMosaicStyle.value,C.uStrength.value,C.uRegionStrength.value,C.uCurvature.value,C.uGlassZ.value,C.uSourceZ.value,C.uPaneSize.value.x,C.uPaneSize.value.y,i,w.uDepthScale.value,w.uDepthBias.value,R.width,R.height,z.width,z.height,B.width,B.height].join(`|`)}function ie(){let e=y.getRenderTarget(),t=y.getClearColor(new c),n=y.getClearAlpha();y.setClearColor(0,0);for(let e of V)y.setRenderTarget(e),y.clear(!0,!1,!1);y.setRenderTarget(e),y.setClearColor(t,n),J=0,Y=!1,T.value=V[0].texture}function Q(e){let{mode:t,effect:n,style:r}=E(),i=re();if(i!==q&&(ie(),q=i),!((t===`final`||t===`glass`)&&n===`mosaic`&&r===`0`&&C.uRegionAvailable.value>.5&&C.uRegionStrength.value>.001&&C.uStrength.value>.001))return;let a=1-J;U.uPreviousHistory.value=V[J].texture,U.uHistoryBlend.value=Y?1-Math.exp(-e/.07):1,y.setRenderTarget(V[a]),y.render(H,L),y.setRenderTarget(null),J=a,Y=!0,T.value=V[J].texture}function ae(){let{effect:e,style:t,activeIsVideo:n}=E();if(!(e===`mosaic`&&t===`0`&&C.uRegionAvailable.value>.5&&C.uRegionStrength.value>.001&&C.uStrength.value>.001))return;let r=Z();(n||r!==K)&&(y.setRenderTarget(z),y.render(A,L),y.setRenderTarget(B),y.render(N,L),y.setRenderTarget(null),K=r)}function oe(e,t=null){let{mode:n}=E();if(n===`final`||n===`glass`){y.setRenderTarget(R),y.render(b,x),C.uSceneTexture.value=R.texture,ae(),Q(e),y.setRenderTarget(t),y.render(D,L);let n=y.autoClear;y.autoClear=!1,y.clearDepth(),y.render(te,x),y.autoClear=n}else Q(e),y.setRenderTarget(t),y.render(b,x)}let $=!1;return{render:oe,setEffect(e){O.fragmentShader=e===`reeded`?p:e===`frosted`?m:f,O.needsUpdate=!0},resize(e,t){R.setSize(e,t),X()},invalidate(){K=``,q=``,Y=!1},dispose(){if(!$){$=!0,R.dispose(),z.dispose(),B.dispose(),V.forEach(e=>e.dispose());for(let e of[k,M,I,G])e.geometry.dispose();for(let e of[O,j,F,W])e.dispose();D.clear(),A.clear(),N.clear(),H.clear()}}}}export{v as createOriginalGlassRenderer};