@jdultra/threedtiles 13.3.1 → 13.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -28,7 +28,10 @@ Example:
28
28
  * @license MIT License
29
29
  */class kt extends Lc{constructor(t=[],a){super(a);wt(this,"_elements",[]);wt(this,"_DEFAULT_COMPARATOR",(t,a)=>{if(typeof t=="object"||typeof a=="object")throw TypeError("When comparing object types, a custom comparator must be defined in the constructor's options parameter.");return t>a?1:t<a?-1:0});wt(this,"_comparator",this._DEFAULT_COMPARATOR);if(a){const{comparator:i}=a;i&&(this._comparator=i)}this.addMany(t)}get elements(){return this._elements}get size(){return this.elements.length}get leaf(){return this.elements[this.size-1]??void 0}static heapify(t,a){return new kt(t,a)}add(t){return this._elements.push(t),this._bubbleUp(this.elements.length-1)}addMany(t){const a=[];for(const i of t)this._toElementFn?a.push(this.add(this._toElementFn(i))):a.push(this.add(i));return a}poll(){if(this.elements.length===0)return;const t=this.elements[0],a=this.elements.pop();return this.elements.length&&(this.elements[0]=a,this._sinkDown(0,this.elements.length>>1)),t}peek(){return this.elements[0]}isEmpty(){return this.size===0}clear(){this._elements=[]}refill(t){return this._elements=t,this.fix()}has(t){return this.elements.includes(t)}delete(t){const a=this.elements.indexOf(t);return!(a<0)&&(a===0?this.poll():a===this.elements.length-1?this.elements.pop():(this.elements.splice(a,1,this.elements.pop()),this._bubbleUp(a),this._sinkDown(a,this.elements.length>>1)),!0)}dfs(t="PRE"){const a=[],i=n=>{const o=2*n+1,s=o+1;n<this.size&&(t==="IN"?(i(o),a.push(this.elements[n]),i(s)):t==="PRE"?(a.push(this.elements[n]),i(o),i(s)):t==="POST"&&(i(o),i(s),a.push(this.elements[n])))};return i(0),a}clone(){return new kt(this,{comparator:this.comparator,toElementFn:this.toElementFn})}sort(){const t=[],a=new kt(this,{comparator:this.comparator});for(;a.size!==0;){const i=a.poll();i!==void 0&&t.push(i)}return t}fix(){const t=[];for(let a=Math.floor(this.size/2);a>=0;a--)t.push(this._sinkDown(a,this.elements.length>>1));return t}filter(t,a){const i=new kt([],{toElementFn:this.toElementFn,comparator:this.comparator});let n=0;for(const o of this)t.call(a,o,n,this)&&i.add(o),n++;return i}map(t,a,i,n){const o=new kt([],{comparator:a,toElementFn:i});let s=0;for(const A of this)o.add(t.call(n,A,s,this)),s++;return o}get comparator(){return this._comparator}*_getIterator(){for(const t of this.elements)yield t}_bubbleUp(t){const a=this.elements[t];for(;t>0;){const i=t-1>>1,n=this.elements[i];if(this.comparator(n,a)<=0)break;this.elements[t]=n,t=i}return this.elements[t]=a,!0}_sinkDown(t,a){const i=this.elements[t];for(;t<a;){let n=t<<1|1;const o=n+1;let s=this.elements[n];if(o<this.elements.length&&this.comparator(s,this.elements[o])>0&&(n=o,s=this.elements[o]),this.comparator(s,i)>=0)break;this.elements[t]=s,t=n}return this.elements[t]=i,!0}}(function(r){r[r.VISIT=0]="VISIT",r[r.PROCESS=1]="PROCESS"})(Qi||(Qi={}));class ea extends kt{constructor(e=[],t){super(e,t)}clone(){return new ea(this,{comparator:this.comparator,toElementFn:this.toElementFn})}filter(e,t){const a=new ea([],{toElementFn:this.toElementFn,comparator:this.comparator});let i=0;for(const n of this)e.call(t,n,i,this)&&a.add(n),i++;return a}map(e,t,a,i){const n=new ea([],{comparator:t,toElementFn:a});let o=0;for(const s of this)n.add(e.call(i,s,o,this)),o++;return n}}class ta extends ea{constructor(e=[],t){super(e,t)}clone(){return new ta(this,{comparator:this.comparator,toElementFn:this.toElementFn})}filter(e,t){const a=new ta([],{toElementFn:this.toElementFn,comparator:this.comparator});let i=0;for(const n of this)e.call(t,n,i,this)&&a.add(n),i++;return a}map(e,t,a,i){const n=new ta([],{comparator:t,toElementFn:a});let o=0;for(const s of this)n.add(e.call(i,s,o,this)),o++;return n}}function Gc(r){return new Worker(""+(typeof document>"u"?require("url").pathToFileURL(__dirname+"/assets/PointsManager.worker-dH1fNyu8.js").href:new URL("assets/PointsManager.worker-dH1fNyu8.js",document.currentScript&&document.currentScript.tagName.toUpperCase()==="SCRIPT"&&document.currentScript.src||document.baseURI).href),{type:"module",name:r==null?void 0:r.name})}new E.Box3,new E.Vector3,new E.Vector3,new E.Vector3,new E.Vector3;const ua=new E.Vector3,_c=new E.Vector3,qn=new E.Matrix3;qn.set(1,0,0,0,0,1,0,-1,0);const Hc=new E.Matrix4().set(1,0,0,0,0,0,-1,0,0,1,0,0,0,0,0,1);function ar(r,e){return(E.DataUtils.toHalfFloat(r)|E.DataUtils.toHalfFloat(e)<<16)>>>0}class Oc extends E.Mesh{constructor(e,t,a){const n=Math.min(Math.ceil(4)*1024,Math.pow(1024,2));let o=1*Math.pow(1024,2);o=Math.floor(o/n)*n;const s=new E.WebGL3DRenderTarget(1024,1024,1,{magFilter:E.NearestFilter,minFilter:E.NearestFilter,type:E.UnsignedIntType,format:E.RGBAIntegerFormat,anisotropy:0,depthBuffer:!1,resolveDepthBuffer:!1});s.texture.type=E.UnsignedIntType,s.texture.format=E.RGBAIntegerFormat,s.texture.internalFormat="RGBA32UI",e.initRenderTarget(s);const A=new E.WebGL3DRenderTarget(1024,1024,1,{magFilter:E.NearestFilter,minFilter:E.NearestFilter,anisotropy:0,type:E.UnsignedIntType,format:E.RGBAIntegerFormat,depthBuffer:!1,resolveDepthBuffer:!1});A.texture.type=E.UnsignedIntType,A.texture.format=E.RGBAIntegerFormat,A.texture.internalFormat="RGBA32UI",e.initRenderTarget(A);const u=new E.ShaderMaterial({glslVersion:E.GLSL3,uniforms:{textureSize:{value:1024},numSlices:{value:1},covarianceTexture:{value:A.texture},positionColorTexture:{value:s.texture},zUpToYUpMatrix3x3:{value:qn},sizeMultiplier:{value:1},cropRadius:{value:Number.MAX_VALUE},cameraNear:{value:.01},cameraFar:{value:10},computeLinearDepth:{value:!0},viewportPixelSize:{value:new E.Vector2},k:{value:2},beta_k:{value:2},minSplatPixelSize:{value:0},minOpacity:{value:.01},culling:{value:!0},antialiasingFactor:{value:2}},vertexShader:Jn(),fragmentShader:a||Kn(),transparent:!0,side:E.FrontSide,depthTest:!1,depthWrite:!1}),c=new E.InstancedBufferGeometry,d=new Float32Array([-.5,.5,0,.5,.5,0,-.5,-.5,0,.5,-.5,0]);c.setIndex([0,2,1,2,3,1]),c.setAttribute("position",new E.BufferAttribute(d,3));const b=new Uint32Array(o),h=new E.InstancedBufferAttribute(b,1,!1);h.needsUpdate=!0,h.setUsage(E.DynamicDrawUsage),c.setAttribute("order",h),c.instanceCount=0,super(c,u),this.matrixAutoUpdate=!1,this.numBatches=0,this.numVisibleBatches=0,this.orderAttribute=h,this.textureSize=1024,this.numTextures=1,this.batchSize=n,this.maxSplats=o,this.numSplatsRendered=0,this.positionColorRenderTarget=s,this.covarianceRenderTarget=A,this.renderer=e,this.sortID=0,this.freeAddresses=new ta;for(let g=0;g<this.maxSplats;g+=n)this.freeAddresses.add(g);this.worker=new Gc({}),this.sortListeners=[],this.worker.onmessage=g=>{const f=new Uint32Array(g.data.order);if(this.numSplatsRendered=f.length,f.length>this.orderAttribute.count){const m=new E.InstancedBufferGeometry,p=new Float32Array([-.5,.5,0,.5,.5,0,-.5,-.5,0,.5,-.5,0]),C=[0,2,1,2,3,1];m.setIndex(C),m.setAttribute("position",new E.BufferAttribute(p,3));const I=new Uint32Array(this.maxSplats),x=new E.InstancedBufferAttribute(I,1,!1);x.needsUpdate=!0,x.setUsage(E.DynamicDrawUsage),m.setAttribute("order",x),m.instanceCount=0,this.geometry.dispose(),this.geometry=m,this.orderAttribute=x}this.orderAttribute.clearUpdateRanges(),this.orderAttribute.set(f),this.orderAttribute.addUpdateRange(0,f.length),this.orderAttribute.needsUpdate=!0,this.geometry.instanceCount=g.data.count,this.geometry.needsUpdate=!0;for(let m=this.sortListeners.length-1;m>=0;m--)this.sortListeners[m](g.data.id)&&this.sortListeners.splice(m,1)},this.cameraPosition=new E.Vector3(0,0,0),this.viewProjModel,this.rotateOnAxis(new E.Vector3(1,0,0),.5*Math.PI),this.frustumCulled=!1,this.copyMaterial2D=new E.ShaderMaterial({glslVersion:E.GLSL3,uniforms:{sourceTexture:{}},vertexShader:Ni(),fragmentShader:`
30
30
  precision highp float;
31
- layout(location = 0) out uvec4 fragColor;
31
+ precision highp int;
32
+ precision highp usampler3D;
33
+
34
+ layout(location = 0) out highp uvec4 fragColor;
32
35
  uniform highp usampler2D sourceTexture;
33
36
 
34
37
  in vec2 vUv;
@@ -37,7 +40,10 @@ void main() {
37
40
  fragColor = texture( sourceTexture, vUv );
38
41
  }`,transparent:!1,side:E.FrontSide,depthTest:!1,depthWrite:!1}),this.copyMaterial3D=new E.ShaderMaterial({glslVersion:E.GLSL3,uniforms:{sourceTexture:{},w:{value:0}},vertexShader:Ni(),fragmentShader:`
39
42
  precision highp float;
40
- layout(location = 0) out uvec4 fragColor;
43
+ precision highp int;
44
+ precision highp usampler3D;
45
+
46
+ layout(location = 0) out highp uvec4 fragColor;
41
47
  uniform highp usampler3D sourceTexture;
42
48
  uniform float w;
43
49
 
@@ -48,6 +54,7 @@ void main() {
48
54
  }`,transparent:!1,side:E.FrontSide,depthTest:!1,depthWrite:!1}),this.copyCamera=new E.OrthographicCamera(-.5,.5,.5,-.5,.1,10),this.copyCamera.position.z=1,this.copyScene=new E.Scene;const l=new E.PlaneGeometry(1,1);this.copyQuad=new E.Mesh(l,this.copyMaterial2D),this.copyScene.add(this.copyQuad),this.copyScene.matrixAutoUpdate=!1,this.copyQuad.matrixAutoUpdate=!1}setQuality(e){const t=2+2*(e=Math.max(0,Math.min(1,1-e)));this.material.uniforms.k.value=t,this.material.uniforms.beta_k.value=Math.pow(4*Uc(2/t)/t,t/2),this.material.uniforms.minSplatPixelSize.value=5*e,this.material.uniforms.minOpacity.value=.01}setSplatsCPUCulling(e){this.splatsCPUCuling=e,this.material.uniforms.culling.value=!e}updateShaderParams(e){e.projectionMatrix.elements,this.renderer.getSize(this.material.uniforms.viewportPixelSize.value);const t=this.renderer.getPixelRatio();this.material.uniforms.viewportPixelSize.value.multiplyScalar(t),this.material.uniforms.antialiasingFactor.value=2}dispose(){this.material.dispose(),this.copyMaterial2D.dispose(),this.copyMaterial3D.dispose(),this.covarianceRenderTarget.dispose(),this.positionColorRenderTarget.dispose(),this.worker.terminate(),this.worker=null,this.orderAttribute.array=void 0,this.geometry.dispose()}copyTex2D(e,t,a,i){this.copyMaterial2D.uniforms.sourceTexture.value=e;const n=this.renderer.autoClear,o=this.renderer.getRenderTarget();this.renderer.autoClear=!1;const s=a[2]-a[0],A=a[3]-a[1];t.viewport.set(a[0],a[1],s,A),this.renderer.setRenderTarget(t,i),this.renderer.render(this.copyScene,this.copyCamera),this.renderer.setRenderTarget(o),this.renderer.autoClear=n}copyTex3D(e,t,a){this.copyMaterial3D.uniforms.sourceTexture.value=e;const i=this.renderer.autoClear,n=this.renderer.getRenderTarget();this.renderer.autoClear=!1,this.copyQuad.material=this.copyMaterial3D;for(let o=0;o<a;o++)this.renderer.setRenderTarget(t,o),this.copyMaterial3D.uniforms.w.value=(o+.5)/a,this.renderer.render(this.copyScene,this.copyCamera);this.copyQuad.material=this.copyMaterial2D,this.renderer.setRenderTarget(n),this.renderer.autoClear=i}setSplatsSizeMultiplier(e){this.material.uniforms.sizeMultiplier.value=e}setSplatsCropRadius(e){this.material.uniforms.cropRadius.value=e}sort(e,t){this.worker&&(e?this.cameraPosition&&e.equals(this.cameraPosition)||(this.cameraPosition.copy(e),t?(this.viewProjModel||(this.viewProjModel=new E.Matrix4),this.viewProjModel.copy(t),this.viewProjModel.multiply(Hc)):this.viewProjModel=void 0,this.worker.postMessage({method:"sort",xyz:[this.cameraPosition.x,this.cameraPosition.z,-this.cameraPosition.y],vpm:this.viewProjModel&&this.splatsCPUCuling?this.viewProjModel.toArray():void 0,id:this.sortID++})):this.worker.postMessage({method:"sort",xyz:[this.cameraPosition.x,this.cameraPosition.z,-this.cameraPosition.y],vpm:this.viewProjModel&&this.splatsCPUCuling?this.viewProjModel.toArray():void 0,id:this.sortID++}))}raycast(e,t){}addSplatsTile(e,t,a,i){if(!this.worker)return;const n=this,o=e.data?e.data.array:e.array,s=e.data&&e.data.isInterleavedBuffer?e.data.stride:3,A=e.data&&e.data.isInterleavedBuffer?e.offset:0,u=Math.ceil(o.length/(this.batchSize*s)),c=[],d=[];let b=()=>{};const h=new Float32Array(o.length/s*3),l=new Uint32Array(h.buffer,h.byteOffset,h.length);for(let f=0;f<o.length/3;f++)h[3*f]=o[f*s+A],h[3*f+1]=o[f*s+A+1],h[3*f+2]=o[f*s+A+2];b=(f,m,p)=>{const C=p*p;for(let I=0;I<h.length;I+=3){ua.set(h[I],-h[I+2],h[I+1]);const x=_c.copy(ua).sub(f.origin).dot(f.direction);x>0&&f.distanceSqToPoint(ua)<C&&m.push({distance:x,point:ua.clone(),type:"splat"})}},u>this.freeAddresses.size&&this.growTextures();for(let f=0;f<u;f++){const m=this.freeAddresses.poll();isNaN(m)&&console.log("insuficient texture size to store splats info"),c.push(m),d.push(3*m);const p=f*this.batchSize;this.addSplatsBatch(p,m,l,t,a,i)}n.worker.postMessage({method:"addBatches",insertionIndexes:d,positions:o.buffer,offset:A,stride:s,batchSize:n.batchSize},[o.buffer]);let g=!1;return{hide:()=>{g==1&&n.worker&&(n.numVisibleBatches--,g=!1,n.worker.postMessage({method:"hideBatches",insertionIndexes:d,xyz:[n.cameraPosition.x,n.cameraPosition.z,-n.cameraPosition.y],vpm:this.viewProjModel&&this.splatsCPUCuling?this.viewProjModel.toArray():void 0,id:n.sortID++}))},show:f=>{if(g==0&&n.worker){n.numVisibleBatches--,g=!0;const m=n.sortID,p=C=>C>=m&&(f(),!0);n.sortListeners.push(p),n.worker.postMessage({method:"showBatches",insertionIndexes:d,xyz:[n.cameraPosition.x,n.cameraPosition.z,-n.cameraPosition.y],vpm:this.viewProjModel&&this.splatsCPUCuling?this.viewProjModel.toArray():void 0,id:n.sortID++})}},remove:()=>{n.worker&&(b=void 0,n.worker.postMessage({method:"removeBatches",insertionIndexes:d,xyz:[n.cameraPosition.x,n.cameraPosition.z,-n.cameraPosition.y],vpm:this.viewProjModel&&this.splatsCPUCuling?this.viewProjModel.toArray():void 0,id:n.sortID++}),c.forEach(f=>n.freeAddresses.add(f)))},sort:this.sort,raycast:b,isSplatsBatch:!0}}addSplatsBatch(e,t,a,i,n,o){const s=new Uint32Array(4*this.batchSize),A=new Uint32Array(4*this.batchSize);for(let l=t;l<t+this.batchSize;l++){const g=l-t,f=4*g,m=e+g,p=3*(e+g);if(m>=a.count)break;s[f]=a[p],s[f+1]=a[p+1],s[f+2]=a[p+2];const C=0|Math.floor(255*i.getX(m)+.5),I=0|Math.floor(255*i.getY(m)+.5),x=0|Math.floor(255*i.getZ(m)+.5),y=0|Math.floor(255*i.getW(m)+.5);s[f+3]=C|I<<8|x<<16|y<<24,A[f]=ar(n.getX(m),n.getY(m)),A[f+1]=ar(n.getZ(m),o.getX(m)),A[f+2]=ar(o.getY(m),o.getZ(m))}const u=Math.floor(t/Math.pow(this.textureSize,2)),c=Math.ceil(this.batchSize/this.textureSize),d=[0,t/this.textureSize-u*this.textureSize,this.textureSize];d.push(d[1]+c);const b=new E.DataTexture(s,this.textureSize,c,E.RGBAIntegerFormat,E.UnsignedIntType);b.internalFormat="RGBA32UI",b.generateMipmaps=!1,b.magFilter=E.NearestFilter,b.minFilter=E.NearestFilter,b.anisotropy=0,b.needsUpdate=!0,this.renderer.initTexture(b),this.copyTex2D(b,this.positionColorRenderTarget,d,u),b.dispose();const h=new E.DataTexture(A,this.textureSize,c,E.RGBAIntegerFormat,E.UnsignedIntType);h.internalFormat="RGBA32UI",h.generateMipmaps=!1,h.magFilter=E.NearestFilter,h.minFilter=E.NearestFilter,h.anisotropy=0,h.needsUpdate=!0,this.renderer.initTexture(h),this.copyTex2D(h,this.covarianceRenderTarget,d,u),h.dispose()}growTextures(){for(let i=this.maxSplats;i<this.maxSplats+this.textureSize*this.textureSize;i+=this.batchSize)this.freeAddresses.add(i);this.maxSplats+=this.textureSize*this.textureSize;const e=this.numTextures+1,t=new E.WebGL3DRenderTarget(this.textureSize,this.textureSize,e,{magFilter:E.NearestFilter,minFilter:E.NearestFilter,type:E.UnsignedIntType,format:E.RGBAIntegerFormat,anisotropy:0,depthBuffer:!1,resolveDepthBuffer:!1});t.texture.type=E.UnsignedIntType,t.texture.internalFormat="RGBA32UI",t.texture.format=E.RGBAIntegerFormat,this.renderer.initRenderTarget(t),this.copyTex3D(this.positionColorRenderTarget.texture,t,this.numTextures),this.positionColorRenderTarget.dispose(),this.positionColorRenderTarget=t,this.material.uniforms.positionColorTexture.value=this.positionColorRenderTarget.texture;const a=new E.WebGL3DRenderTarget(this.textureSize,this.textureSize,e,{magFilter:E.NearestFilter,minFilter:E.NearestFilter,anisotropy:0,type:E.UnsignedIntType,format:E.RGBAIntegerFormat,depthBuffer:!1,resolveDepthBuffer:!1});a.texture.type=E.UnsignedIntType,a.texture.internalFormat="RGBA32UI",a.texture.format=E.RGBAIntegerFormat,this.renderer.initRenderTarget(a),this.copyTex3D(this.covarianceRenderTarget.texture,a,this.numTextures),this.covarianceRenderTarget.dispose(),this.covarianceRenderTarget=a,this.material.uniforms.covarianceTexture.value=this.covarianceRenderTarget.texture,this.numTextures=e,this.material.uniforms.numSlices.value=this.numTextures}}function Jn(){return`
49
55
  precision highp float;
50
56
  precision highp int;
57
+ precision highp usampler3D;
51
58
 
52
59
  #include <common>
53
60
  #include <packing>
@@ -55,7 +62,7 @@ precision highp int;
55
62
  uniform float textureSize;
56
63
  uniform float numSlices;
57
64
  uniform float sizeMultiplier;
58
- in uint order;
65
+ in highp uint order;
59
66
  out vec4 color;
60
67
  out vec2 vUv;
61
68
  out vec3 splatPositionWorld;
@@ -93,22 +100,24 @@ void getVertexData(out vec3 position, out mat3 covariance) {
93
100
  int( (y + 0.5) ), // y pixel
94
101
  int( sliceIndex + 0.5 ) ); // z slice */
95
102
 
96
- float index = float(order)+0.1; // add small offset to avoid floating point errors with modulo
97
- float pixelsPerSlice = textureSize * textureSize;
98
- float sliceIndex = floor(index / pixelsPerSlice);
99
- float slicePixelIndex = mod(index,pixelsPerSlice);
103
+
104
+ highp uint uOrder = order; // Use a local uint copy
100
105
 
101
- float x = mod(slicePixelIndex,textureSize);
102
- float y = floor(slicePixelIndex / textureSize);
106
+ // It's good practice to ensure textureSize is treated as uint for these calcs
107
+ uint uTextureSize = uint(textureSize); // textureSize uniform is float
108
+ uint uPixelsPerSlice = uTextureSize * uTextureSize;
103
109
 
104
- //vec3 uvw = vec3((x + 0.5) / textureSize, (y + 0.5) / textureSize, (sliceIndex + 0.5) / numSlices);
105
- ivec3 coord = ivec3(
106
- int( (x + 0.5) ), // x pixel
107
- int( (y + 0.5) ), // y pixel
108
- int( sliceIndex + 0.5 ) ); // z slice
110
+ uint sliceIndexVal = uOrder / uPixelsPerSlice;
111
+ uint slicePixelIndex = uOrder % uPixelsPerSlice; // umod(uOrder, uPixelsPerSlice) also works
112
+
113
+ uint xVal = slicePixelIndex % uTextureSize; // umod(slicePixelIndex, uTextureSize)
114
+ uint yVal = slicePixelIndex / uTextureSize;
115
+
116
+ // texelFetch takes ivec3 for coordinates, no +0.5 needed as these are direct integer indices
117
+ ivec3 coord = ivec3(xVal, yVal, sliceIndexVal);
109
118
 
110
119
  // Position
111
- uvec4 positionColor = texelFetch(positionColorTexture, coord,0);
120
+ highp uvec4 positionColor = texelFetch(positionColorTexture, coord,0);
112
121
  position = vec3(uintBitsToFloat(positionColor.r),uintBitsToFloat(positionColor.g),uintBitsToFloat(positionColor.b));
113
122
 
114
123
  color = vec4( (positionColor.a & 255u),
@@ -117,7 +126,7 @@ void getVertexData(out vec3 position, out mat3 covariance) {
117
126
  (positionColor.a >> 24) ) / 255.0;
118
127
 
119
128
 
120
- uvec4 cov = texelFetch(covarianceTexture, coord, 0);
129
+ highp uvec4 cov = texelFetch(covarianceTexture, coord, 0);
121
130
  vec2 c0 = unpackHalf2x16(cov.r);
122
131
  vec2 c1 = unpackHalf2x16(cov.g);
123
132
  vec2 c2 = unpackHalf2x16(cov.b);
@@ -255,6 +264,7 @@ void main() {
255
264
  `}function Kn(){return`
256
265
  precision highp float;
257
266
  precision highp int;
267
+ precision highp usampler3D;
258
268
 
259
269
  in float stds;
260
270
  in vec4 color;
@@ -273,10 +283,6 @@ uniform float beta_k; // pow((4.0 * gamma(2.0/k)) /k, k/2)
273
283
  void main() {
274
284
  float l = dot(vUv, vUv);
275
285
  if (l > 0.25) discard; // early out unchanged
276
- /* if (l > 0.245){
277
- fragColor = vec4(pow(color.xyz, vec3(1.0/2.2)), 0.8);
278
- return;
279
- } */
280
286
  vec2 p = vUv * stds;
281
287
  float r2 = dot(p, p); // r²
282
288
  float rk = pow(r2, 0.5 * k); // r^{k}
@@ -288,6 +294,10 @@ void main() {
288
294
 
289
295
  }`}function Ni(){return`
290
296
 
297
+ precision highp float;
298
+ precision highp int;
299
+ precision highp usampler3D;
300
+
291
301
  out vec2 vUv;
292
302
 
293
303
  void main() {