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)
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)?
Thanks again! that fixed it ( I had the mesh.dynamic in there from the previous version)
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):