Three.js: change material on mesh

Created on 8 Jan 2012  路  17Comments  路  Source: mrdoob/three.js

Is it possible to trigger an even that will change the material assignment of the mesh?

I want to swap a phong shader:

phongMaterial = [new THREE.MeshPhongMaterial( { ambient: 0x555555, color: 0x555555, specular: 0xffffff, shininess: 50, shading: THREE.SmoothShading }  )];

with this basic material:

basicMaterial = [new THREE.MeshBasicMaterial( { vertexColors: THREE.FaceColors } ),new THREE.MeshBasicMaterial({color: 0xffffff, opacity: 1, wireframe: true} ) ]

when a certain event is triggered I switch using this code:

myMesh.materials = basicMaterial

and switching back:

myMesh.materials = phongMaterial

however when I switch from the phong to the basic the mesh just disappears (it comes back when I switch back)

Question

Most helpful comment

Try this (there are no more multi-materials, also more complex material must be first one that gets rendered, if you use some vertex colors, they must be present / absent in both materials):

phongMaterial = new THREE.MeshPhongMaterial( { ambient: 0x555555, color: 0x555555, specular: 0xffffff, shininess: 50, shading: THREE.SmoothShading } );
basicMaterial = new THREE.MeshBasicMaterial( { color: 0xffffff, opacity: 1, wireframe: true } );

myMesh.material = phongMaterial;

myMesh.material = basicMaterial;

All 17 comments

Try this (there are no more multi-materials, also more complex material must be first one that gets rendered, if you use some vertex colors, they must be present / absent in both materials):

phongMaterial = new THREE.MeshPhongMaterial( { ambient: 0x555555, color: 0x555555, specular: 0xffffff, shininess: 50, shading: THREE.SmoothShading } );
basicMaterial = new THREE.MeshBasicMaterial( { color: 0xffffff, opacity: 1, wireframe: true } );

myMesh.material = phongMaterial;

myMesh.material = basicMaterial;

Thanks for the suggestion!

I tried that but it doesn't seem to work either, actually now the mesh just disappears and never gets visible again when I switch between the materials

Do you use current version of the library (r46 or r47dev)?

Code you posted in the issue shouldn't work at all with more recent versions of the library.

I was using one of the older versions with the code i posted.

But i tried your suggestion with version r45

r45 is too old, multimaterials were still there.

ok thanks! I will try it with r46

I tried it with r46 but same thing happen switching between basic to phong (or phong to basic) just causes the mesh to disappear, switching back makes it visible again.

When I print myMesh.material in the console it looks like it is correctly switching between the two but its just not displaying it

Try switching between exactly the same type of material, just change the color.

If this also doesn't work, problem is somewhere else.

If this works, problem is that one of your material needs different buffers than the other. If that's the case, you must render first with the more complex material (e.g. if one uses texture and other not, textured one must be rendered first).

Thanks! that worked, I didn't think about the order but setting phong first seems to solve the problem.

Now that multimaterials are gone is there an easy way to have wireframe on top of a shaded mesh?

Just by creating multiple objects, there is helper for this (THREE.SceneUtils.createMultiMaterialObject):

https://github.com/mrdoob/three.js/blob/master/examples/webgl_geometry_colors.html#L144

oh I see, looking at the code in SceneUtils it looks like its actually creating a mesh for each material, will it have a big impact on performance or is it ok since its using the same geometry?

It depends on a performance profile of your application. It'll be slower but if you don't have too many objects, it should be still quite ok. Try and see.

so thw code is working now with version r46 but I used to be able to change the color of a face on a mesh when there was a mouse click on it wit this code:

intersects[0].face.color.setHex( 0xFF0000 )

however this doesn't seem to work anymore after switching to r46 and moving to one material

If you want to use face colors, you need to enable them in materials (both of them should have vertexColors: THREE.FaceColors parameter in their constructors).

Also don't forget to set geometry.__dirtyColors = true flag after each change.

yes I do enable them:

phongMaterial = new THREE.MeshPhongMaterial( { vertexColors: THREE.FaceColors, ambient: 0x555555, color: 0x555555, specular: 0xffffff, shininess: 50, shading: THREE.SmoothShading } );

and I have the dirtyColors flag set to true but even without switching materials (just with the phong material) it doesn't seem to work anymore. Did anything else change in r46?

Do you also set geometry.dynamic = true (it used to be mesh.dynamic long ago)?

https://github.com/mrdoob/three.js/wiki/Updates

Thanks again! that fixed it ( I had the mesh.dynamic in there from the previous version)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Horray picture Horray  路  3Comments

zsitro picture zsitro  路  3Comments

filharvey picture filharvey  路  3Comments

danieljack picture danieljack  路  3Comments

seep picture seep  路  3Comments