• Materail’s initial setup
mesh = new THREE.Mesh( geometry, material );
Copy the code
  • The Material object returned by the Mesh is an object
material: MeshBasicMaterial
Copy the code
  • Initial setup for multimaterial
Geometry. AddGroup (0, +Infinity, 0
//mesh.geometry.addGroup(0, +Infinity, 1)
mesh.geometry.addGroup(0,mesh.geometry.index.count,0);
mesh.geometry.addGroup(0,mesh.geometry.index.count,1)
let boxMesh = new THREE.Mesh(mesh.geometry,  [material1,material2])
Copy the code
  • The Material object that Mesh returns is an array
geometry: Model
    groups: Array(2)
        0: {start: 0, count: xxxxx, materialIndex: 0} / / the most layer
        1: {start: 0, count: xxxxx, materialIndex: 1} / / the most outer layer
material: Array(2)
    0: MeshStandardSGMaterial
    1: MeshStandardSGMaterial
Copy the code
  • AddGroup source
addGroup: function (start, count, materialIndex) {
        this.groups.push({
                start: start,
                count: count,
                materialIndex: materialIndex ! = =undefined ? materialIndex : 0
        });
},
Copy the code
  • projectObject
/ * * *@desc The objects in the scene are classified and rendered <br /> * into light, flash, lens, normal, etc. *@param {THREE.Scene} Scene Scene object *@param {THREE.Object3D} Object 3D object */
function projectObject( object, camera, groupOrder, sortObjects ) {
        if ( object.visible === false ) return;
        const visible = object.layers.test( camera.layers );
        if ( visible ) {
                if ( object.isGroup ) {
                        groupOrder = object.renderOrder;
                } else if ( object.isLOD ) {
                        if ( object.autoUpdate === true ) object.update( camera );
                } else if ( object.isLight ) {// Lighting is placed separately in currentRenderState, unlike other Object3D.
                        currentRenderState.pushLight( object );
                        if( object.castShadow ) { currentRenderState.pushShadow( object ); }}else if ( object.isSprite ) {
                        if(! object.frustumCulled || _frustum.intersectsSprite( object ) ) {if ( sortObjects ) {
                                        _vector3
                                                .setFromMatrixPosition( object.matrixWorld )
                                                .applyMatrix4( _projScreenMatrix );
                                }
                                const geometry = objects.update( object );
                                const material = object.material;
                                if ( material.visible ) {
                                        currentRenderList.push(
                                                object,
                                                geometry,
                                                material,
                                                groupOrder,
                                                _vector3.z,
                                                null); }}}else if ( object.isImmediateRenderObject ) {
                        if ( sortObjects ) {
                                _vector3
                                        .setFromMatrixPosition( object.matrixWorld )
                                        .applyMatrix4( _projScreenMatrix );
                        }
                        currentRenderList.push(
                                object,
                                null,
                                object.material,
                                groupOrder,
                                _vector3.z,
                                null
                        );
                } else if ( object.isMesh || object.isLine || object.isPoints ) {
                        if ( object.isSkinnedMesh ) {
                                // update skeleton only once in a frame
                                if ( object.skeleton.frame !== info.render.frame ) {
                                        object.skeleton.update();
                                        object.skeleton.frame = info.render.frame;
                                }
                        }
                        if(! object.frustumCulled || _frustum.intersectsObject( object ) ) {if ( sortObjects ) {
                                        _vector3
                                                .setFromMatrixPosition( object.matrixWorld )
                                                .applyMatrix4( _projScreenMatrix );
                                }
                                const geometry = objects.update( object );
                                const material = object.material;
                                if ( Array.isArray( material ) ) {
                                        const groups = geometry.groups;
                                        for ( let i = 0, l = groups.length; i < l; i ++ ) {
                                                const group = groups[ i ];
                                                const groupMaterial = material[ group.materialIndex ];
                                                if( groupMaterial && groupMaterial.visible ) { currentRenderList.push( object, geometry, groupMaterial, groupOrder, _vector3.z, group ); }}}else if ( material.visible ) {
                                        currentRenderList.push(
                                                object,
                                                geometry,
                                                material,
                                                groupOrder,
                                                _vector3.z,
                                                null); }}}}// Iterate over the child object to build the render object
        const children = object.children;
        for ( let i = 0, l = children.length; i < l; i ++ ) { projectObject( children[ i ], camera, groupOrder, sortObjects ); }}Copy the code
  • renderObject
function renderObject( object, camera, shadowCamera, light, type ) {
        if ( object.visible === false ) return;
        const visible = object.layers.test( camera.layers );
        if ( visible && ( object.isMesh || object.isLine || object.isPoints ) ) {
                if (
                        ( object.castShadow ||
                                ( object.receiveShadow && type === VSMShadowMap ) ) &&
                        ( ! object.frustumCulled || _frustum.intersectsObject( object ) )
                ) {
                        object.modelViewMatrix.multiplyMatrices(
                                shadowCamera.matrixWorldInverse,
                                object.matrixWorld
                        );
                        const geometry = _objects.update( object );
                        const material = object.material;
                        if ( Array.isArray( material ) ) {
                                const groups = geometry.groups;
                                for ( let k = 0, kl = groups.length; k < kl; k ++ ) {
                                        const group = groups[ k ];
                                        const groupMaterial = material[ group.materialIndex ];
                                        if ( groupMaterial && groupMaterial.visible ) {
                                                const depthMaterial = getDepthMaterial(
                                                        object,
                                                        geometry,
                                                        groupMaterial,
                                                        light,
                                                        shadowCamera.near,
                                                        shadowCamera.far,
                                                        type
                                                );
                                                _renderer.renderBufferDirect(
                                                        shadowCamera,
                                                        null, geometry, depthMaterial, object, group ); }}}else if ( material.visible ) {
                                const depthMaterial = getDepthMaterial(
                                        object,
                                        geometry,
                                        material,
                                        light,
                                        shadowCamera.near,
                                        shadowCamera.far,
                                        type
                                );
                                _renderer.renderBufferDirect(
                                        shadowCamera,
                                        null,
                                        geometry,
                                        depthMaterial,
                                        object,
                                        null); }}}const children = object.children;
        for ( let i = 0, l = children.length; i < l; i ++ ) { renderObject( children[ i ], camera, shadowCamera, light, type ); }}Copy the code