UNPKG

@lume/three-instanced-mesh

Version:

Scene graph level abstraction for three.js InstancedBufferGeometry

1 lines 8.1 kB
(()=>{"use strict";globalThis.InstancedMesh=function(t){const n=parseInt(t.REVISION)>=96;!function(t){/InstancedMesh/.test(t.REVISION)||(function(t){Object.assign(t.ShaderChunk,{begin_vertex:"\n#ifndef INSTANCE_TRANSFORM\n\nvec3 transformed = vec3( position );\n\n#else\n\n#ifndef INSTANCE_MATRIX\n\n\tmat4 _instanceMatrix = getInstanceMatrix();\n\n\t#define INSTANCE_MATRIX\n\n#endif\n\nvec3 transformed = ( _instanceMatrix * vec4( position , 1. )).xyz;\n\n#endif\n",color_fragment:"\n#ifdef USE_COLOR\n\n\tdiffuseColor.rgb *= vColor;\n\n#endif\n\n#if defined(INSTANCE_COLOR)\n\t\t\n\tdiffuseColor.rgb *= vInstanceColor;\n\tdiffuseColor.a = vInstanceOpacity * opacity;\n\t\t\n#endif\n",color_pars_fragment:"\n\n#ifdef USE_COLOR\n\n\tvarying vec3 vColor;\n\n#endif\n\n#if defined( INSTANCE_COLOR )\n\t\t\n\tvarying vec3 vInstanceColor;\n\tvarying float vInstanceOpacity;\n\t\t\n#endif\n",color_vertex:"\n#ifdef USE_COLOR\n\n\tvColor.xyz = color.xyz;\n\n#endif\n\n#if defined( INSTANCE_COLOR ) && defined( INSTANCE_TRANSFORM )\n\t\t\n\tvInstanceColor = instanceColor;\n\tvInstanceOpacity = instanceOpacity;\n\t\t\n#endif\n",defaultnormal_vertex:"\n#ifdef FLIP_SIDED\n\n\tobjectNormal = -objectNormal;\n\n#endif\n\n#ifndef INSTANCE_TRANSFORM\n\n\tvec3 transformedNormal = normalMatrix * objectNormal;\n\n#else\n\n\t#ifndef INSTANCE_MATRIX \n\n\t\tmat4 _instanceMatrix = getInstanceMatrix();\n\n\t\t#define INSTANCE_MATRIX\n\n\t#endif\n\n\t#ifndef INSTANCE_UNIFORM\n\t\n\t\tvec3 transformedNormal = transposeMat3( inverse( mat3( modelViewMatrix * _instanceMatrix ) ) ) * objectNormal ;\n\n\t#else\n\n\t\tvec3 transformedNormal = ( modelViewMatrix * _instanceMatrix * vec4( objectNormal , 0.0 ) ).xyz;\n\n\t#endif\n\n#endif\n",uv_pars_vertex:"\n#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\n \n varying vec2 vUv;\n \n uniform mat3 uvTransform;\n\n#endif\n\n#ifdef INSTANCE_TRANSFORM\n\nmat3 inverse(mat3 m) {\n\n float a00 = m[0][0], a01 = m[0][1], a02 = m[0][2];\n\n float a10 = m[1][0], a11 = m[1][1], a12 = m[1][2];\n\n float a20 = m[2][0], a21 = m[2][1], a22 = m[2][2];\n\n float b01 = a22 * a11 - a12 * a21;\n\n float b11 = -a22 * a10 + a12 * a20;\n\n float b21 = a21 * a10 - a11 * a20;\n\n float det = a00 * b01 + a01 * b11 + a02 * b21;\n\n return mat3(b01, (-a22 * a01 + a02 * a21), ( a12 * a01 - a02 * a11),\n b11, ( a22 * a00 - a02 * a20), (-a12 * a00 + a02 * a10),\n b21, (-a21 * a00 + a01 * a20), ( a11 * a00 - a01 * a10)) / det;\n}\n\n//for dynamic, avoid computing the matrices on the cpu\nattribute vec3 instancePosition;\nattribute vec4 instanceQuaternion;\nattribute vec3 instanceScale;\n\n#if defined( INSTANCE_COLOR )\n attribute vec3 instanceColor;\n varying vec3 vInstanceColor;\n attribute float instanceOpacity;\n varying float vInstanceOpacity;\n#endif\n\nmat4 getInstanceMatrix(){\n\n vec4 q = instanceQuaternion;\n vec3 s = instanceScale;\n vec3 v = instancePosition;\n\n vec3 q2 = q.xyz + q.xyz;\n vec3 a = q.xxx * q2.xyz;\n vec3 b = q.yyz * q2.yzz;\n vec3 c = q.www * q2.xyz;\n\n vec3 r0 = vec3( 1.0 - (b.x + b.z) , a.y + c.z , a.z - c.y ) * s.xxx;\n vec3 r1 = vec3( a.y - c.z , 1.0 - (a.x + b.z) , b.y + c.x ) * s.yyy;\n vec3 r2 = vec3( a.z + c.y , b.y - c.x , 1.0 - (a.x + b.x) ) * s.zzz;\n\n return mat4(\n\n r0 , 0.0,\n r1 , 0.0,\n r2 , 0.0,\n v , 1.0\n\n );\n\n}\n\n#endif\n"})}(t),t.REVISION+="_InstancedMesh")}(t);var e=new t.MeshDepthMaterial;e.depthPacking=t.RGBADepthPacking,e.clipping=!0,e.defines={INSTANCE_TRANSFORM:""};var a,i=t.ShaderLib.distanceRGBA,s=t.UniformsUtils.clone(i.uniforms),r=new t.ShaderMaterial({defines:{USE_SHADOWMAP:"",INSTANCE_TRANSFORM:""},uniforms:s,vertexShader:i.vertexShader,fragmentShader:i.fragmentShader,clipping:!0});function o(n,a,i,s,o,c){t.Mesh.call(this,(new t.InstancedBufferGeometry).copy(n)),this._dynamic=!!s,this._uniformScale=!!c,this._colors=!!o,this.numInstances=i,this._setAttributes(),this.material=a.clone(),this.frustumCulled=!1,this.customDepthMaterial=e,this.customDistanceMaterial=r}return o.prototype=Object.create(t.Mesh.prototype),o.constructor=o,Object.defineProperties(o.prototype,{material:{set:function(t){(t=t.clone()).defines?(t.defines.INSTANCE_TRANSFORM="",this._uniformScale?t.defines.INSTANCE_UNIFORM="":delete t.defines.INSTANCE_UNIFORM,this._colors?t.defines.INSTANCE_COLOR="":delete t.defines.INSTANCE_COLOR):(t.defines={INSTANCE_TRANSFORM:""},this._uniformScale&&(t.defines.INSTANCE_UNIFORM=""),this._colors&&(t.defines.INSTANCE_COLOR="")),this._material=t},get:function(){return this._material}},numInstances:{set:function(t){this._numInstances=t,this._setAttributes()},get:function(){return this._numInstances}},geometry:{set:function(n){n.attributes.instancePosition?(this._geometry=new t.InstancedBufferGeometry,this._setAttributes()):this._geometry=n},get:function(){return this._geometry}}}),o.prototype.setPositionAt=function(t,n){this.geometry.attributes.instancePosition.setXYZ(t,n.x,n.y,n.z)},o.prototype.setQuaternionAt=function(t,n){this.geometry.attributes.instanceQuaternion.setXYZW(t,n.x,n.y,n.z,n.w)},o.prototype.setScaleAt=function(t,n){this.geometry.attributes.instanceScale.setXYZ(t,n.x,n.y,n.z)},o.prototype.setColorAt=function(t,n){this._colors?this.geometry.attributes.instanceColor.setXYZ(t,Math.floor(255*n.r),Math.floor(255*n.g),Math.floor(255*n.b)):console.warn("InstancedMesh: color not enabled")},o.prototype.setOpacityAt=function(t,n){this._colors?this.geometry.attributes.instanceOpacity.setX(t,n):console.warn("InstancedMesh: color not enabled")},o.prototype.getPositionAt=function(n,e){var a=this.geometry.attributes.instancePosition.array;return n*=3,e?e.set(a[n++],a[n++],a[n]):new t.Vector3(a[n++],a[n++],a[n])},o.prototype.getQuaternionAt=function(n,e){var a=this.geometry.attributes.instanceQuaternion.array;return n<<=2,e?e.set(a[n++],a[n++],a[n++],a[n]):new t.Quaternion(a[n++],a[n++],a[n++],a[n])},o.prototype.getScaleAt=function(n,e){var a=this.geometry.attributes.instanceScale.array;return n*=3,e?e.set(a[n++],a[n++],a[n]):new t.Vector3(a[n++],a[n++],a[n])},o.prototype.getColorAt=(a=1/255,function(n,e){if(!this._colors)return console.warn("InstancedMesh: color not enabled"),!1;var i=this.geometry.attributes.instanceColor.array;return n*=3,e?e.setRGB(i[n++]*a,i[n++]*a,i[n]*a):new t.Vector3(i[n++],i[n++],i[n]).multiplyScalar(a)}),o.prototype.getOpacityAt=function(t){return this._colors?this.geometry.attributes.instanceOpacity.getX(t):(console.warn("InstancedMesh: color not enabled"),!1)},o.prototype.needsUpdate=function(t){switch(t){case"position":this.geometry.attributes.instancePosition.needsUpdate=!0;break;case"quaternion":this.geometry.attributes.instanceQuaternion.needsUpdate=!0;break;case"scale":this.geometry.attributes.instanceScale.needsUpdate=!0;break;case"colors":this.geometry.attributes.instanceColor.needsUpdate=!0;break;case"opacity":this.geometry.attributes.instanceOpacity.needsUpdate=!0;break;default:this.geometry.attributes.instancePosition.needsUpdate=!0,this.geometry.attributes.instanceQuaternion.needsUpdate=!0,this.geometry.attributes.instanceScale.needsUpdate=!0,this._colors&&(this.geometry.attributes.instanceColor.needsUpdate=!0,this.geometry.attributes.instanceOpacity.needsUpdate=!0)}},o.prototype._setAttributes=function(){var e={instancePosition:[new Float32Array(3*this.numInstances),3,!1,1],instanceQuaternion:[new Float32Array(4*this.numInstances),4,!1,1],instanceScale:[new Float32Array(3*this.numInstances),3,!1,1]};this._colors&&(e.instanceColor=[new Uint8Array(3*this.numInstances),3,true,1],e.instanceOpacity=[new Float32Array(this.numInstances).fill(1),1,true,1]),Object.keys(e).forEach((a=>{const i=e[a];let s;n?s=new t.InstancedBufferAttribute(...i):(s=new t.InstancedBufferAttribute(i[0],i[1],i[3]),s.normalized=i[2]),s.dynamic=this._dynamic,t.REVISION>=110?this.geometry.setAttribute(a,s):this.geometry.addAttribute(a,s)}))},o}(THREE)})();