@three.ez/batched-mesh-extensions
Version:
Utility extension methods for BatchedMesh
32 lines (31 loc) • 18.6 kB
JavaScript
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const U=require("bvh.js"),h=require("three"),It=require("three/addons/utils/SortUtils.js");class k{constructor(t,e,n=0,s=!0){this.nodesMap=new Map,this._origin=new Float32Array(3),this._dir=new Float32Array(3),this._cameraPos=new Float32Array(3),this._boxArray=new Float32Array(6),this.target=t,this.accurateCulling=s,this._margin=n,this.bvh=new U.BVH(new U.HybridBuilder,e===2e3?U.WebGLCoordinateSystem:U.WebGPUCoordinateSystem)}create(){const t=this.target.instanceCount,e=this.target._instanceInfo.length,n=this.target._instanceInfo,s=new Array(t),o=new Uint32Array(t);let i=0;this.clear();for(let a=0;a<e;a++)n[a].active&&(s[i]=this.getBox(a,new Float32Array(6)),o[i]=a,i++);this.bvh.createFromArray(o,s,a=>{this.nodesMap.set(a.object,a)},this._margin)}insert(t){const e=this.bvh.insert(t,this.getBox(t,new Float32Array(6)),this._margin);this.nodesMap.set(t,e)}insertRange(t){const e=t.length,n=new Array(e);for(let s=0;s<e;s++)n[s]=this.getBox(t[s],new Float32Array(6));this.bvh.insertRange(t,n,this._margin,s=>{this.nodesMap.set(s.object,s)})}move(t){const e=this.nodesMap.get(t);e&&(this.getBox(t,e.box),this.bvh.move(e,this._margin))}delete(t){const e=this.nodesMap.get(t);e&&(this.bvh.delete(e),this.nodesMap.delete(t))}clear(){this.bvh.clear(),this.nodesMap.clear()}frustumCulling(t,e){this._margin>0&&this.accurateCulling?this.bvh.frustumCulling(t.elements,(n,s,o)=>{s.isIntersectedMargin(n.box,o,this._margin)&&e(n)}):this.bvh.frustumCulling(t.elements,e)}raycast(t,e){const n=t.ray,s=this._origin,o=this._dir;U.vec3ToArray(n.origin,s),U.vec3ToArray(n.direction,o),this.bvh.rayIntersections(o,s,e,t.near,t.far)}intersectBox(t,e){const n=this._boxArray;return U.box3ToArray(t,n),this.bvh.intersectsBox(n,e)}getBox(t,e){const n=this.target,s=n._instanceInfo[t].geometryIndex;return n.getBoundingBoxAt(s,V).applyMatrix4(n.getMatrixAt(t,St)),U.box3ToArray(V,e),e}}const V=new h.Box3,St=new h.Matrix4;class H{constructor(){this.array=[],this.pool=[]}push(t,e,n,s){const o=this.pool,i=this.array,a=i.length;a>=o.length&&o.push({start:null,count:null,z:null,zSort:null,index:null});const c=o[a];c.index=t,c.start=n,c.count=s,c.z=e,i.push(c)}reset(){this.array.length=0}}function $(r,t){return Math.max(t,Math.ceil(Math.sqrt(r/t))*t)}function Y(r,t,e,n){t===3&&(console.warn('"channels" cannot be 3. Set to 4. More info: https://github.com/mrdoob/three.js/pull/23228'),t=4);const s=$(n,e),o=new r(s*s*t),i=r.name.includes("Float"),a=r.name.includes("Uint"),c=i?h.FloatType:a?h.UnsignedIntType:h.IntType;let m;switch(t){case 1:m=i?h.RedFormat:h.RedIntegerFormat;break;case 2:m=i?h.RGFormat:h.RGIntegerFormat;break;case 4:m=i?h.RGBAFormat:h.RGBAIntegerFormat;break}return{array:o,size:s,type:c,format:m}}class N extends h.DataTexture{constructor(t,e,n,s,o,i){e===3&&(e=4);const{array:a,format:c,size:m,type:u}=Y(t,e,n,s);super(a,m,m,c,u),this.partialUpdate=!0,this.maxUpdateCalls=1/0,this._utils=null,this._needsUpdate=!1,this._lastWidth=null,this._data=a,this._channels=e,this._pixelsPerInstance=n,this._stride=n*e,this._rowToUpdate=new Array(m),this._uniformMap=o,this._fetchUniformsInFragmentShader=i,this.needsUpdate=!0}resize(t){const e=$(t,this._pixelsPerInstance);if(e===this.image.width)return;const n=this._data,s=this._channels;this._rowToUpdate.length=e;const o=n.constructor,i=new o(e*e*s),a=Math.min(n.length,i.length);i.set(new o(n.buffer,0,a)),this.dispose(),this.image={data:i,height:e,width:e},this._data=i}enqueueUpdate(t){if(this._needsUpdate=!0,!this.partialUpdate)return;const e=this.image.width/this._pixelsPerInstance,n=Math.floor(t/e);this._rowToUpdate[n]=!0}update(t){const e=t.properties.get(this),n=this.version>0&&e.__version!==this.version,s=this._lastWidth!==null&&this._lastWidth!==this.image.width;if(!this._needsUpdate||!e.__webglTexture||n||s){this._lastWidth=this.image.width,this._needsUpdate=!1;return}if(this._needsUpdate=!1,!this.partialUpdate){this.needsUpdate=!0;return}const o=this.getUpdateRowsInfo();o.length!==0&&(o.length>this.maxUpdateCalls?this.needsUpdate=!0:this.updateRows(e,t,o),this._rowToUpdate.fill(!1))}getUpdateRowsInfo(){const t=this._rowToUpdate,e=[];for(let n=0,s=t.length;n<s;n++)if(t[n]){const o=n;for(;n<s&&t[n];n++);e.push({row:o,count:n-o})}return e}updateRows(t,e,n){const s=e.state,o=e.getContext();this._utils??(this._utils=new h.WebGLUtils(o,e.extensions,e.capabilities));const i=this._utils.convert(this.format),a=this._utils.convert(this.type),{data:c,width:m}=this.image,u=this._channels;s.bindTexture(o.TEXTURE_2D,t.__webglTexture);const f=h.ColorManagement.getPrimaries(h.ColorManagement.workingColorSpace),l=this.colorSpace===h.NoColorSpace?null:h.ColorManagement.getPrimaries(this.colorSpace),d=this.colorSpace===h.NoColorSpace||f===l?o.NONE:o.BROWSER_DEFAULT_WEBGL;o.pixelStorei(o.UNPACK_FLIP_Y_WEBGL,this.flipY),o.pixelStorei(o.UNPACK_PREMULTIPLY_ALPHA_WEBGL,this.premultiplyAlpha),o.pixelStorei(o.UNPACK_ALIGNMENT,this.unpackAlignment),o.pixelStorei(o.UNPACK_COLORSPACE_CONVERSION_WEBGL,d);for(const{count:g,row:p}of n)o.texSubImage2D(o.TEXTURE_2D,0,0,p,m,g,i,a,c,p*m*u);this.onUpdate&&this.onUpdate(this)}setUniformAt(t,e,n){const{offset:s,size:o}=this._uniformMap.get(e),i=this._stride;o===1?this._data[t*i+s]=n:n.toArray(this._data,t*i+s)}getUniformAt(t,e,n){const{offset:s,size:o}=this._uniformMap.get(e),i=this._stride;return o===1?this._data[t*i+s]:n.fromArray(this._data,t*i+s)}getUniformsGLSL(t,e,n){const s=this.getUniformsVertexGLSL(t,e,n),o=this.getUniformsFragmentGLSL(t,e,n);return{vertex:s,fragment:o}}getUniformsVertexGLSL(t,e,n){if(this._fetchUniformsInFragmentShader)return`
flat varying ${n} ez_v${e};
void main() {
ez_v${e} = ${e};`;const s=this.texelsFetchGLSL(t,e),o=this.getFromTexelsGLSL(),{assignVarying:i,declareVarying:a}=this.getVarying();return`
uniform highp sampler2D ${t};
${a}
void main() {
${s}
${o}
${i}`}getUniformsFragmentGLSL(t,e,n){if(!this._fetchUniformsInFragmentShader){const{declareVarying:i,getVarying:a}=this.getVarying();return`
${i}
void main() {
${a}`}const s=this.texelsFetchGLSL(t,`ez_v${e}`),o=this.getFromTexelsGLSL();return`
uniform highp sampler2D ${t};
flat varying ${n} ez_v${e};
void main() {
${s}
${o}`}texelsFetchGLSL(t,e){const n=this._pixelsPerInstance;let s=`
int size = textureSize(${t}, 0).x;
int j = int(${e}) * ${n};
int x = j % size;
int y = j / size;
`;for(let o=0;o<n;o++)s+=`vec4 ez_texel${o} = texelFetch(${t}, ivec2(x + ${o}, y), 0);
`;return s}getFromTexelsGLSL(){const t=this._uniformMap;let e="";for(const[n,{type:s,offset:o,size:i}]of t){const a=Math.floor(o/this._channels);if(s==="mat3")e+=`mat3 ${n} = mat3(ez_texel${a}.rgb, vec3(ez_texel${a}.a, ez_texel${a+1}.rg), vec3(ez_texel${a+1}.ba, ez_texel${a+2}.r));
`;else if(s==="mat4")e+=`mat4 ${n} = mat4(ez_texel${a}, ez_texel${a+1}, ez_texel${a+2}, ez_texel${a+3});
`;else{const c=this.getUniformComponents(o,i);e+=`${s} ${n} = ez_texel${a}.${c};
`}}return e}getVarying(){const t=this._uniformMap;let e="",n="",s="";for(const[o,{type:i}]of t)e+=`flat varying ${i} ez_v${o};
`,n+=`ez_v${o} = ${o};
`,s+=`${i} ${o} = ez_v${o};
`;return{declareVarying:e,assignVarying:n,getVarying:s}}getUniformComponents(t,e){const n=t%this._channels;let s="";for(let o=0;o<e;o++)s+=wt[n+o];return s}copy(t){return super.copy(t),this.partialUpdate=t.partialUpdate,this.maxUpdateCalls=t.maxUpdateCalls,this._channels=t._channels,this._pixelsPerInstance=t._pixelsPerInstance,this._stride=t._stride,this._rowToUpdate=t._rowToUpdate,this._uniformMap=t._uniformMap,this._fetchUniformsInFragmentShader=t._fetchUniformsInFragmentShader,this}}const wt=["r","g","b","a"];function K(r,t={}){this.bvh=new k(this,r,t.margin,t.accurateCulling),this.bvh.create()}function Mt(r){const t={get:e=>e.zSort,aux:new Array(r.maxInstanceCount),reversed:null};return function(n){t.reversed=r.material.transparent,r.maxInstanceCount>t.aux.length&&(t.aux.length=r.maxInstanceCount);let s=1/0,o=-1/0;for(const{z:c}of n)c>o&&(o=c),c<s&&(s=c);const i=o-s,a=(2**32-1)/i;for(const c of n)c.zSort=(c.z-s)*a;It.radixSort(n,t)}}function X(r,t){return r.z-t.z}function Z(r,t){return t.z-r.z}const G=new h.Frustum,M=new H,R=new h.Matrix4,L=new h.Matrix4,D=new h.Vector3,F=new h.Vector3,O=new h.Vector3,bt=new h.Vector3,B=new h.Sphere;function J(r,t,e,n,s,o){this.frustumCulling(e)}function Q(r,t=r){if(!this._visibilityChanged&&!this.perObjectFrustumCulled&&!this.sortObjects)return;this._indirectTexture.needsUpdate=!0,this._visibilityChanged=!1;const e=this.sortObjects,n=this.perObjectFrustumCulled;if(!n&&!e){this.updateIndexArray();return}if(L.copy(this.matrixWorld).invert(),F.setFromMatrixPosition(r.matrixWorld).applyMatrix4(L),O.setFromMatrixPosition(t.matrixWorld).applyMatrix4(L),D.set(0,0,-1).transformDirection(r.matrixWorld).transformDirection(L),n?(R.multiplyMatrices(r.projectionMatrix,r.matrixWorldInverse).multiply(this.matrixWorld),this.bvh?this.BVHCulling(r,t):this.linearCulling(r,t)):this.updateRenderList(),e){const s=this.geometry.getIndex(),o=s===null?1:s.array.BYTES_PER_ELEMENT,i=this._multiDrawStarts,a=this._multiDrawCounts,c=this._indirectTexture.image.data,m=this.customSort;m===null?M.array.sort(this.material.transparent?Z:X):m(M.array);const u=M.array,f=u.length;for(let l=0;l<f;l++){const d=u[l];i[l]=d.start*o,a[l]=d.count,c[l]=d.index}M.reset()}}function tt(){if(!this._visibilityChanged)return;const r=this.geometry.getIndex(),t=r===null?1:r.array.BYTES_PER_ELEMENT,e=this._instanceInfo,n=this._geometryInfo,s=this._multiDrawStarts,o=this._multiDrawCounts,i=this._indirectTexture.image.data;let a=0;for(let c=0,m=e.length;c<m;c++){const u=e[c];if(u.visible&&u.active){const f=u.geometryIndex,l=n[f];s[a]=l.start*t,o[a]=l.count,i[a]=c,a++}}this._multiDrawCount=a}function et(){const r=this._instanceInfo,t=this._geometryInfo;for(let e=0,n=r.length;e<n;e++){const s=r[e];if(s.visible&&s.active){const o=s.geometryIndex,i=t[o],a=this.getPositionAt(e).sub(F).dot(D);M.push(e,a,i.start,i.count)}}this._multiDrawCount=M.array.length}function nt(r,t){const e=this.geometry.getIndex(),n=e===null?1:e.array.BYTES_PER_ELEMENT,s=this._instanceInfo,o=this._geometryInfo,i=this.sortObjects,a=this._multiDrawStarts,c=this._multiDrawCounts,m=this._indirectTexture.image.data,u=this.onFrustumEnter;let f=0;this.bvh.frustumCulling(R,l=>{const d=l.object,g=s[d];if(!g.visible)return;const p=g.geometryIndex,x=o[p],y=x.LOD;let _,I;if(y){const b=this.getPositionAt(d).distanceToSquared(O),v=this.getLODIndex(y,b);if(u&&!u(d,r,t,v))return;_=y[v].start,I=y[v].count}else{if(u&&!u(d,r))return;_=x.start,I=x.count}if(i){const b=this.getPositionAt(d).sub(F).dot(D);M.push(d,b,_,I)}else a[f]=_*n,c[f]=I,m[f]=d,f++}),this._multiDrawCount=i?M.array.length:f}function st(r,t){const e=this.geometry.getIndex(),n=e===null?1:e.array.BYTES_PER_ELEMENT,s=this._instanceInfo,o=this._geometryInfo,i=this.sortObjects,a=this._multiDrawStarts,c=this._multiDrawCounts,m=this._indirectTexture.image.data,u=this.onFrustumEnter;let f=0;G.setFromProjectionMatrix(R);for(let l=0,d=s.length;l<d;l++){const g=s[l];if(!g.visible||!g.active)continue;const p=g.geometryIndex,x=o[p],y=x.LOD;let _,I;const b=x.boundingSphere,v=b.radius,C=b.center;if(C.x===0&&C.y===0&&C.z===0){const w=this.getPositionAndMaxScaleOnAxisAt(l,B.center);B.radius=v*w}else this.applyMatrixAtToSphere(l,B,C,v);if(G.intersectsSphere(B)){if(y){const w=B.center.distanceToSquared(O),A=this.getLODIndex(y,w);if(u&&!u(l,r,t,A))continue;_=y[A].start,I=y[A].count}else{if(u&&!u(l,r))continue;_=x.start,I=x.count}if(i){const w=bt.subVectors(B.center,F).dot(D);M.push(l,w,_,I)}else a[f]=_*n,c[f]=I,m[f]=l,f++}}this._multiDrawCount=i?M.array.length:f}const vt=new h.Vector3;function ot(r,t=vt){const e=r*16,n=this._matricesTexture.image.data;return t.x=n[e+12],t.y=n[e+13],t.z=n[e+14],t}function rt(r,t){const e=r*16,n=this._matricesTexture.image.data,s=n[e+0],o=n[e+1],i=n[e+2],a=s*s+o*o+i*i,c=n[e+4],m=n[e+5],u=n[e+6],f=c*c+m*m+u*u,l=n[e+8],d=n[e+9],g=n[e+10],p=l*l+d*d+g*g;return t.x=n[e+12],t.y=n[e+13],t.z=n[e+14],Math.sqrt(Math.max(a,f,p))}function it(r,t,e,n){const s=r*16,o=this._matricesTexture.image.data,i=o[s+0],a=o[s+1],c=o[s+2],m=o[s+3],u=o[s+4],f=o[s+5],l=o[s+6],d=o[s+7],g=o[s+8],p=o[s+9],x=o[s+10],y=o[s+11],_=o[s+12],I=o[s+13],b=o[s+14],v=o[s+15],C=t.center,T=e.x,w=e.y,A=e.z,P=1/(m*T+d*w+y*A+v);C.x=(i*T+u*w+g*A+_)*P,C.y=(a*T+f*w+p*A+I)*P,C.z=(c*T+l*w+x*A+b)*P;const xt=i*i+a*a+c*c,yt=u*u+f*f+l*l,_t=g*g+p*p+x*x;t.radius=n*Math.sqrt(Math.max(xt,yt,_t))}function at(r,t,e,n=0){const s=this._geometryInfo[r],o=t.isBufferGeometry?t.index.array:t;e=e**2,s.LOD??(s.LOD=[{start:s.start,count:s.count,distance:0,hysteresis:0}]);const i=s.LOD,a=i[i.length-1],c=a.start+a.count,m=o.length;if(c-s.start+m>s.reservedIndexCount)throw new Error("BatchedMesh LOD: Reserved space request exceeds the maximum buffer size.");i.push({start:c,count:m,distance:e,hysteresis:n});const u=this.geometry.getIndex(),f=u.array,l=s.vertexStart;for(let d=0;d<m;d++)f[c+d]=o[d]+l;u.needsUpdate=!0}function ct(r,t){for(let e=r.length-1;e>0;e--){const n=r[e],s=n.distance-n.distance*n.hysteresis;if(t>=s)return e}return 0}const z=[],S=new h.Mesh,Ct=new h.Ray,q=new h.Vector3,j=new h.Vector3,W=new h.Matrix4;function ht(r,t){var i,a;if(!this.material||this.instanceCount===0)return;S.geometry=this.geometry,S.material=this.material,(i=S.geometry).boundingBox??(i.boundingBox=new h.Box3),(a=S.geometry).boundingSphere??(a.boundingSphere=new h.Sphere);const e=r.ray,n=r.near,s=r.far;W.copy(this.matrixWorld).invert(),j.setFromMatrixScale(this.matrixWorld),q.copy(r.ray.direction).multiply(j);const o=q.length();if(r.ray=Ct.copy(r.ray).applyMatrix4(W),r.near/=o,r.far/=o,this.bvh)this.bvh.raycast(r,c=>this.checkInstanceIntersection(r,c,t));else if(this.boundingSphere===null&&this.computeBoundingSphere(),r.ray.intersectsSphere(this.boundingSphere))for(let c=0,m=this._instanceInfo.length;c<m;c++)this.checkInstanceIntersection(r,c,t);r.ray=e,r.near=n,r.far=s}function ut(r,t,e){const n=this._instanceInfo[t];if(!n.active||!n.visible)return;const s=n.geometryIndex,o=this._geometryInfo[s];this.getMatrixAt(t,S.matrixWorld),S.geometry.boundsTree=this.boundsTrees?this.boundsTrees[s]:void 0,S.geometry.boundsTree||(this.getBoundingBoxAt(s,S.geometry.boundingBox),this.getBoundingSphereAt(s,S.geometry.boundingSphere),S.geometry.setDrawRange(o.start,o.count)),S.raycast(r,z);for(const i of z)i.batchId=t,i.object=this,e.push(i);z.length=0}function lt(r){const t=r.material,e=t.onBeforeCompile.bind(t);t.onBeforeCompile=(n,s)=>{if(r.uniformsTexture){n.uniforms.uniformsTexture={value:r.uniformsTexture};const{vertex:o,fragment:i}=r.uniformsTexture.getUniformsGLSL("uniformsTexture","batchIndex","float");n.vertexShader=n.vertexShader.replace("void main() {",o),n.fragmentShader=n.fragmentShader.replace("void main() {",i),n.vertexShader=n.vertexShader.replace("void main() {","void main() { float batchIndex = getIndirectIndex( gl_DrawID );")}e(n,s)}}function ft(r,t,e){if(!this.uniformsTexture)throw new Error(`Before get/set uniform, it's necessary to use "initUniformsPerInstance".`);return this.uniformsTexture.getUniformAt(r,t,e)}function mt(r,t,e){if(!this.uniformsTexture)throw new Error(`Before get/set uniform, it's necessary to use "initUniformsPerInstance".`);this.uniformsTexture.setUniformAt(r,t,e),this.uniformsTexture.enqueueUpdate(r)}function dt(r){if(this.uniformsTexture)throw new Error('"initUniformsPerInstance" must be called only once.');const{channels:t,pixelsPerInstance:e,uniformMap:n,fetchInFragmentShader:s}=gt(r);this.uniformsTexture=new N(Float32Array,t,e,this.maxInstanceCount,n,s),lt(this)}function gt(r){let t=0;const e=new Map,n=[],s=r.vertex??{},o=r.fragment??{};let i=!0;for(const u in s){const f=s[u],l=E(f);t+=l,n.push({name:u,type:f,size:l}),i=!1}for(const u in o)if(!s[u]){const f=o[u],l=E(f);t+=l,n.push({name:u,type:f,size:l})}n.sort((u,f)=>f.size-u.size);const a=[];for(const{name:u,size:f,type:l}of n){const d=pt(f,a);e.set(u,{offset:d,size:f,type:l})}const c=Math.ceil(t/4);return{channels:Math.min(t,4),pixelsPerInstance:c,uniformMap:e,fetchInFragmentShader:i}}function pt(r,t){if(r<4){for(let n=0;n<t.length;n++)if(t[n]+r<=4){const s=n*4+t[n];return t[n]+=r,s}}const e=t.length*4;for(;r>0;r-=4)t.push(r);return e}function E(r){switch(r){case"float":return 1;case"vec2":return 2;case"vec3":return 3;case"vec4":return 4;case"mat3":return 9;case"mat4":return 16;default:throw new Error(`Invalid uniform type: ${r}`)}}function At(){h.BatchedMesh.prototype.computeBVH=K,h.BatchedMesh.prototype.onBeforeRender=J,h.BatchedMesh.prototype.frustumCulling=Q,h.BatchedMesh.prototype.updateIndexArray=tt,h.BatchedMesh.prototype.updateRenderList=et,h.BatchedMesh.prototype.BVHCulling=nt,h.BatchedMesh.prototype.linearCulling=st,h.BatchedMesh.prototype.getPositionAt=ot,h.BatchedMesh.prototype.getPositionAndMaxScaleOnAxisAt=rt,h.BatchedMesh.prototype.applyMatrixAtToSphere=it,h.BatchedMesh.prototype.addGeometryLOD=at,h.BatchedMesh.prototype.getLODIndex=ct,h.BatchedMesh.prototype.raycast=ht,h.BatchedMesh.prototype.checkInstanceIntersection=ut}function Ut(){At(),h.BatchedMesh.prototype.getUniformAt=ft,h.BatchedMesh.prototype.setUniformAt=mt,h.BatchedMesh.prototype.initUniformsPerInstance=dt}function Bt(r){let t=0,e=0;for(const n of r)t+=n.attributes.position.count,e+=n.index.count;return{vertexCount:t,indexCount:e}}function Tt(r){const t=[];let e=0,n=0;for(const s of r){let o=0;for(const i of s){const a=i.index.count;n+=a,o+=a,e+=i.attributes.position.count}t.push(o)}return{vertexCount:e,indexCount:n,LODIndexCount:t}}exports.BVHCulling=nt;exports.BatchedMeshBVH=k;exports.MultiDrawRenderList=H;exports.SquareDataTexture=N;exports.addGeometryLOD=at;exports.applyMatrixAtToSphere=it;exports.checkInstanceIntersection=ut;exports.computeBVH=K;exports.createRadixSort=Mt;exports.extendBatchedMeshPrototype=Ut;exports.frustumCulling=Q;exports.getBatchedMeshCount=Bt;exports.getBatchedMeshLODCount=Tt;exports.getLODIndex=ct;exports.getPositionAndMaxScaleOnAxisAt=rt;exports.getPositionAt=ot;exports.getSquareTextureInfo=Y;exports.getSquareTextureSize=$;exports.getUniformAt=ft;exports.getUniformOffset=pt;exports.getUniformSchemaResult=gt;exports.getUniformSize=E;exports.initUniformsPerInstance=dt;exports.linearCulling=st;exports.onBeforeRender=J;exports.patchBatchedMeshMaterial=lt;exports.raycast=ht;exports.setUniformAt=mt;exports.sortOpaque=X;exports.sortTransparent=Z;exports.updateIndexArray=tt;exports.updateRenderList=et;
//# sourceMappingURL=webgl.cjs.map