I see in 6f5223951d1e08f9da08d81c6c5d56d0b2a4b8ea and a few related commits that MultiMaterial
is being removed (not exactly "deprecated"). There remains some code referencing MultiMaterial
throughout the repo, such as ColladaLoader
, which is now broken.
I don't see any documentation on this, either in the doc files or in an issue. Can someone please explain how MultiMaterial
's functionality is to be replaced? Is there a particular reason for the removal?
The change was proposed in https://github.com/mrdoob/three.js/issues/8924.
With the adopted API, both of these patterns are now acceptable:
var mesh = new THREE.Mesh( geometry, material ); // a single material
var mesh = new THREE.Mesh( geometry, materials ); // an array of materials
Thanks @WestLangley.
I'm sure others could still benefit from an update to the docs.
It looks like right now the Mesh
just blindly takes whatever you give it, which is going to break a lot of old code and make it a little trickier to inspect Meshes' materials. I quite like the pattern you proposed here.
which is going to break a lot of old code and make it a little trickier to inspect Meshes' materials.
How so?
It looks like right now the Mesh just blindly takes whatever you give it, which is going to break a lot of old code
Not at all (and it won't break anything).
Finally, the current approach is the right one.
Now you can perform the following task:
if ( object.material.length > 1 ) {
for (var m = 0; m < object.material.length; m++) {
object.material[m].color.set( 0xffffff );
}
} else {
object.material.color.set( 0xffffff );
}
I would use Array.isArray()
...
if ( Array.isArray( object.material ) ) {
for ( var m = 0; m < object.material.length; m ++ ) {
object.material[ m ].color.set( 0xffffff );
}
} else {
object.material.color.set( 0xffffff );
}
Okay, serialisation/deserialisation is done 鉁岋笍
So, from now on... this code:
var geometry = new THREE.BoxBufferGeometry( 1, 1, 1 );
var materials = [
new THREE.MeshDepthMaterial(),
new THREE.MeshNormalMaterial(),
new THREE.MeshBasicMaterial( { wireframe: true } ),
new THREE.MeshLambertMaterial( { color: 0xff0000 } ),
new THREE.MeshPhongMaterial( { color: 0x0000ff } ),
new THREE.MeshStandardMaterial( { color: 0x00ff00 } ),
];
var mesh = new THREE.Mesh( geometry, materials );
mesh.toJSON();
produces this:
{
"metadata": {
"version": 4.5,
"type": "Object",
"generator": "Object3D.toJSON"
},
"geometries": [
{
"uuid": "BC2110E2-3EA4-4C37-9041-DE1A49F5C06B",
"type": "BoxBufferGeometry",
"width": 1,
"height": 1,
"depth": 1
}
],
"materials": [
{
"uuid": "81EDCE16-A1EC-40B6-A4F3-D34374C6DF5A",
"type": "MeshDepthMaterial",
"depthFunc": 3,
"depthTest": true,
"depthWrite": true,
"skinning": false,
"morphTargets": false,
"dithering": false
},
{
"uuid": "8BBB3EE7-B8BD-4441-8CBF-B01A73DE1D9E",
"type": "MeshNormalMaterial",
"depthFunc": 3,
"depthTest": true,
"depthWrite": true,
"skinning": false,
"morphTargets": false,
"dithering": false
},
{
"uuid": "D3CD2958-6E36-42CE-B4C4-688B670CF8CD",
"type": "MeshBasicMaterial",
"color": 16777215,
"depthFunc": 3,
"depthTest": true,
"depthWrite": true,
"wireframe": true,
"skinning": false,
"morphTargets": false,
"dithering": false
},
{
"uuid": "22156F77-0963-4C68-99A7-BDE887313F2A",
"type": "MeshLambertMaterial",
"color": 16711680,
"emissive": 0,
"depthFunc": 3,
"depthTest": true,
"depthWrite": true,
"skinning": false,
"morphTargets": false,
"dithering": false
},
{
"uuid": "49C93E84-FD7F-49F4-AA55-9769194E25E8",
"type": "MeshPhongMaterial",
"color": 255,
"emissive": 0,
"specular": 1118481,
"shininess": 30,
"depthFunc": 3,
"depthTest": true,
"depthWrite": true,
"skinning": false,
"morphTargets": false,
"dithering": false
},
{
"uuid": "F8B0E57E-B25C-4A16-B917-4EE615B2B6D4",
"type": "MeshStandardMaterial",
"color": 65280,
"roughness": 0.5,
"metalness": 0.5,
"emissive": 0,
"depthFunc": 3,
"depthTest": true,
"depthWrite": true,
"skinning": false,
"morphTargets": false,
"dithering": false
}
],
"object": {
"uuid": "6E9A5918-B4C7-4D25-928D-4C283C8CE387",
"type": "Mesh",
"matrix": [1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],
"geometry": "BC2110E2-3EA4-4C37-9041-DE1A49F5C06B",
"material": [
"81EDCE16-A1EC-40B6-A4F3-D34374C6DF5A",
"8BBB3EE7-B8BD-4441-8CBF-B01A73DE1D9E",
"D3CD2958-6E36-42CE-B4C4-688B670CF8CD",
"22156F77-0963-4C68-99A7-BDE887313F2A",
"49C93E84-FD7F-49F4-AA55-9769194E25E8",
"F8B0E57E-B25C-4A16-B917-4EE615B2B6D4"
]
}
}
And THREE.ObjectLoader
loads that correctly.
The editor now also has minimal support (import, export but not edit).
@mrdoob @WestLangley does that mean THREE.Mesh.material can have both an array or an object? Also, will groups still work in Geometry and faces?
The new approach seems to be really nice, just i'm super scared of updating, 90% of our 3d related codebase is MultiMaterial. 馃槺
Yeah. Everything should still work. In fact, Multimaterial should still work, it would just display a warning in the console.
Closing since the removal of MultiMaterial
is now well documented and sufficiently discussed.
mrdoob: And THREE.ObjectLoader loads that correctly...
No, it is not: Using ObjectLoader I just see cube without any materials! And the warning appears:
THREE.ObjectLoader: Undefined material (6) ["81EDCE16-A1EC-40B6-A4F3-D34374C6DF5A", "8BBB3EE7-B8BD-4441-8CBF-B01A73DE1D9E", "D3CD2958-6E36-42CE-B4C4-688B670CF8CD", "22156F77-0963-4C68-99A7-BDE887313F2A", "49C93E84-FD7F-49F4-AA55-9769194E25E8", "F8B0E57E-B25C-4A16-B917-4EE615B2B6D4"]
In the same time, I am able to load it correctly into three.js/Editor
@alexforever82 please, if you found a bug, create a new issue and include a jsfiddle.
As of #11835, the editor now can edit multi-materials.
Most helpful comment
The editor now also has minimal support (import, export but not edit).