- 一Materail的初始设置
mesh = new THREE.Mesh( geometry, material );
- Mesh返回的Material对象是对象
material: MeshBasicMaterial
- 多Material的初始设置
//mesh.geometry.addGroup(0, +Infinity, 0) //一般不这么写,会触发BUG,射线选中的BUG
//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])
- Mesh返回的material对象是数组
geometry: Model
groups: Array(2)
0: {start: 0, count: xxxxx, materialIndex: 0} //最里层
1: {start: 0, count: xxxxx, materialIndex: 1} //最外层
material: Array(2)
0: MeshStandardSGMaterial
1: MeshStandardSGMaterial
- AddGroup 源码
addGroup: function (start, count, materialIndex) {
this.groups.push({
start: start,
count: count,
materialIndex: materialIndex !== undefined ? materialIndex : 0
});
},
- projectObject
/**
* @desc 场景内的对象分类并生成渲染对象<br />
* 分为光照,闪光,透镜,普通等几类
* @param {THREE.Scene} scene 场景对象
* @param {THREE.Object3D} object 3D对象
*/
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 ) {//光照与其他 Object3D 不一样,它是另外单独被放在 currentRenderState 中的。
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
);
}
}
}
}
// 遍历子对象,进行构建渲染对象
const children = object.children;
for ( let i = 0, l = children.length; i < l; i ++ ) {
projectObject( children[ i ], camera, groupOrder, sortObjects );
}
}
- 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 );
}
}