6.2 Elements for mesh, instanced mesh and merged mesh
6.2.1 Various ways to represent <mesh/>
<mesh/> is a react element that represents a THREE.mesh object generated by three.js. The following codes show seven ways to create <mesh/>. Note that in the code, geometry is an instance of THREE.BufferGeometry, and material refers to an instance of a material belonging to THREE.Material.
<mesh>
<geometry type={'buffer'}>
<bufferAttribute attach={'attributes-position'}
args={[ geometry.attributes.position.array, 3 ]}/>
<bufferAttribute attach={'attributes-normal'}
args={[ geometry.attributes.normal.array, 3 ]}/>
<bufferAttribute attach={'attributes-uv'}
args={[ geometry.attributes.uv.array, 2 ]}/>
<bufferAttribute attach={'index'}
args={[ geometry.index.array, 1 ]}/>
</geometry>
<material type={'standard'} map={url}/>
</mesh>
<mesh>
<geometry type={'buffer'} copy={geometry}/>
<material type={'standard'} map={url}/>
</mesh>
<mesh>
<primitive object={geometry} attach={'geometry'}/>
<material type={'standard'} map={url}/>
</mesh>
<mesh>
<primitive object={geometry} attach={'geometry'}/>
<primitive object={material} attach={'material'}/>
</mesh>
<mesh
geometry={geometry}
material={material}
/>
<mesh geometry={geometry}>
<material type={'standard'} map={url}/>
</mesh>
<mesh material={material}>
<geometry type={'buffer'} copy={geometry}/>
</mesh>
6.2.2 Comparison of <instancedMesh/> and <batchedMesh/>
<instancedMesh/> is a react element that creates n mesh instances from 1 geometry and 1 material. On the other hand, <batchedMesh/> is a react element that creates n mesh instances from m geometries and 1 material. The following example code shows the difference between the two meshes.
const geom1 = new THREE.TorusGeometry( 9, 3, 16, 100 );
const geom2 = new THREE.BoxGeometry( 15, 15, 15 );
const geom3 = new THREE.SphereGeometry( 9, 32, 16 );
const geometry = mergeGeometries( [ geom1, geom2, geom3 ], false );
const count = 500;
const ref = useRefEffect( instMesh =>
{
for( let i = 0; i < count; i++ )
{
const m = randomMatrix(500,500,500,0.5,2);
instMesh.setMatrixAt( i, m );
}
});
return <instancedMesh ref={ref} count={count}>
<geometry type={'buffer'} copy={geometry}/>
<material type={'standard'} map={url}/>
</instancedMesh>;
const count = 500;
const ref = useRefEffect( batchMesh =>
{
// transform matrices
const matrices = [];
for( let i = 0; i < count; i++ )
{
matrices.push( randomMatrix( 500, 500, 500, 0.5, 2 ).clone() );
}
// geometries ==> instances
batchMesh.geometries.forEach( geometry =>
{
const geomId = batchMesh.addGeometry( geometry );
for( let i = 0; i < count; i++ )
{
const instId = batchMesh.addInstance( geomId );
batchMesh.setMatrixAt( instId, matrices[ i ] );
}
});
});
return <batchedMesh ref={ref} args={[ count*3, 6553600, 6553600*2 ]}>
<geometry type={'buffer'} copy={geom1} attach={'geometries-0'}/>
<geometry type={'buffer'} copy={geom2} attach={'geometries-1'}/>
<geometry type={'buffer'} copy={geom3} attach={'geometries-2'}/>
<material type={'standard'} map={url}/>
</batchedMesh>;
6.2.3 Comparison of <Mesh/> and <MergedMesh/>
<Mesh/> is a react element that creates a mesh instance from m geometries and 1 material. Here, m geometries are merged into 1 geometry. The following code shows an example of 8 geometries being merged.
<Mesh>
<geometry type={'buffer'} copy={new THREE.BoxGeometry(10,1,10)}/>
<geometry type={'box'} args={[5,5,5]}/>
<boxGeometry args={[1,10,1]}/>
<sphereGeometry args={[2,32,16]} translate={[0,7,0]}/>
<primitive object={new THREE.CylinderGeometry(1,1,5,32)} translate={[ 5, 0, 5]}/>
<primitive object={new THREE.CylinderGeometry(1,1,5,32)} translate={[ 5, 0,-5]}/>
<primitive object={new THREE.CylinderGeometry(1,1,5,32)} translate={[-5, 0, 5]}/>
<primitive object={new THREE.CylinderGeometry(1,1,5,32)} translate={[-5, 0,-5]}/>
<material type={'standard'} map={'images/texture.jpg'}/>
</Mesh>
<MergedMesh/> is a react element that merges n different mesh models to create a batchedMesh with n geometries and 1 material. <MergedMesh/> shows the same performance as rendering a single mesh due to a merging process. It has a built-in algorithm that merges the materials of individual models to show real-time rendering performance. The following example code shows an example of using <MergedMesh/>.
<MergedMesh type={'standard'}>
<box position={p1} type={'basic'} map={tex1.jpg}/>
<sphere position={p2} type={'lambert'} map={tex2.jpg}/>
<cone position={p3} type={'phong'} map={tex3.jpg}/>
...
<torus position={p4} type={'standard'} map={tex4.jpg}/>
</MergedMesh>
<MergedMesh>
<box position={[px,py,pz]} color={'red'} map={'images/texture1.jpg'}/>
<mesh position={[px,py,pz]}>
<sphereGeometry args={[r]}/>
<meshBasicMaterial color={'green'} map={'images/texture2.jpg'}/>
</mesh>
<Mesh>
<geometry type={'box'} args={[w,h,d]}/>
<geometry type={'cylinder'}/>
<material type={'standard'} map={'images/texture3.jpg'}/>
</Mesh>
</MergedMesh>
6.2.4 <InstancedModel/> creating multiple instances of a loaded model
<InstancedModel /> loads a specific model and uses it to create a total of count instance models. The position, size, and rotation of each created instance model is updated by the initTransform and updateTransform functions, and the color data is updated by the initColor and updateColor functions.
<InstancedModel
count={count} // number of instances
url={'models/model.glb'} // model url to be loaded
animIdx={2} // index of animations to be played (if available)
initTransform={initTransform} // set the initial transform of each instance
updateTransform={updateTransform} // update the transform of each instance
deltaTransform={deltaTransform} // apply the transform increment of each instance
initColor={initColor} // set the initial color of each instance
updateColor={updateColor} // update the color of each instance
/>
Last updated