uniform sampler2D uSceneTexture; uniform mat4 uContentViewProjection; uniform mat4 uContentInverseViewProjection; uniform vec3 uContentCameraPosition; uniform vec3 uLightPosition; uniform float uGlassZ,uGridSize,uStrength,uMosaicStyle; uniform float uGlossStrength; uniform vec2 uViewOffset,uPetSize; uniform vec4 uPaneRect; 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 uv){return texture2D(uSceneTexture,clamp(uv,uPaneRect.xy,uPaneRect.zw));} 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)));} 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(vUv.xuPaneRect.z||vUv.yuPaneRect.w){ gl_FragColor=sampleScene(vUv); #include return; } vec4 f=uContentInverseViewProjection*vec4(vUv*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 grid=vec2(uGridSize,max(1.,uGridSize*uPetSize.y/uPetSize.x)),gridUv=vUv*grid,cell=floor(gridUv),local=fract(gridUv)-.5,cellSize=1./grid,random=hash2(cell); vec3 n=normalize(vec3((random-.5)*.10+local*.025,1.)),r=bend(i,n);vec3 sh=gh+i*(-gh.z/safeZ(i.z)),rh=gh+r*(-gh.z/safeZ(r.z));vec2 viewRefraction=clamp(projectUv(rh)-projectUv(sh),-cellSize*.4,cellSize*.4)+(uViewOffset*(random-.5))*cellSize*.12; float style=clamp(uMosaicStyle,0.,1.);vec2 sourceCenter=(cell+.5)/grid+(random-.5)*.45*cellSize+viewRefraction;float footprint=mix(mix(.35,.50,random.y),mix(.03,.10,random.y),style);float angle=(random.x-.5)*mix(.06,.12,1.-style),c=cos(angle),s=sin(angle);vec2 sampleUv=clamp(sourceCenter+mat2(c,-s,s,c)*local*footprint*cellSize,uPaneRect.xy,uPaneRect.zw); float edgeDistance=min(min(vUv.x-uPaneRect.x,uPaneRect.z-vUv.x),min(vUv.y-uPaneRect.y,uPaneRect.w-vUv.y));float edgeWeight=smoothstep(0.,max(cellSize.x,cellSize.y)*.75,edgeDistance);float strength=clamp(uStrength,0.,1.)*edgeWeight;vec2 blurStep=cellSize*mix(.015,.07,style); vec4 color=samplePane(mix(vUv,sampleUv,strength))*.4;color+=samplePane(mix(vUv,sampleUv+vec2(blurStep.x,0.),strength))*.15;color+=samplePane(mix(vUv,sampleUv-vec2(blurStep.x,0.),strength))*.15;color+=samplePane(mix(vUv,sampleUv+vec2(0.,blurStep.y),strength))*.15;color+=samplePane(mix(vUv,sampleUv-vec2(0.,blurStep.y),strength))*.15;color.a=1.; vec3 l=normalize(uLightPosition-gh),v=normalize(uContentCameraPosition-gh),h=normalize(l+v);float spec=pow(max(dot(n,h),0.),64.);float gloss=spec*clamp(uGlossStrength,0.,1.)*.28*edgeWeight*clamp(uStrength,0.,1.);color.rgb=mix(color.rgb,vec3(1.),gloss);gl_FragColor=color; #include }