It seems that setting THREE.FlatShading for a material doesn't work for BufferGeometry. Is it implemented?
I'm creating BufferGeometry with CTMLoader (useBuffers = true) and applying either MeshLambertMaterial or MeshNormalMaterial with shading: THREE.FlatShading.
Three.js still renders everything as SmoothShading.
If I switch to ClassicGeometry (useBuffers = false), everything works as expected. Unfortunately, that would not work for us since our models are huge and that was exactly the reason to use BufferGeometry.
Is it just not implemented or is it very difficult/time-consuming/not-possible to implement?
Thank you in advance for any hints or suggestions. I'm using the latest r58 version.
P.S.
I found a recent Ryan Rix' post on the same topic http://rix.si/2013/04/15/threejs-ctm-and-you/ where he had to switch to ClassicGeometry to make it work.
In three.js r73 flat shading is working with THREE.MeshPhongMaterial for sure. You can use it like this:
geometry = new THREE.BufferGeometry();
//... make your geometry
material = new THREE.MeshPhongMaterial({
color: 0xff0000,
shading: THREE.FlatShading
});
mesh = new THREE.Mesh( geometry, material );
This doesn't work for THREE.MeshLambertMaterial yet. But they are working on it. Check the related issue here on GitHUB.
flatShading does work in MeshPhongMaterial or any other, the property for
flatShading is boolean
flatShading : Boolean
Define whether the material is rendered with flat shading. Default is false.
const PlaneMaterial = new THREE.MeshPhongMaterial({color:'blue',
side:THREE.DoubleSide,
flatShading:true})
Code Snipet
Related
I tried setting "type" and then setting "needsUpdate", but it didn't change the type. I know I could make a new material, and then change every mesh that uses that material to use the new material, but I was hoping there was a way I could do it without iterating through every mesh.
You need to create a new material and have the mesh point to it.
mesh.material = new THREE.MeshPhongMaterial({ color: 0xffffff });
Check this fiddle: https://jsfiddle.net/29Lqeadx/.
I am loading a GLTF model into threejs. All the materials used on the object (and there a quite a few of them), use a mesh basic material, and we want them to be a material that can be affected by lights. Is there a way to convert all materials from a basic material to one that can receive lights, like Phong (including their existing properties?).
I can currently add a new material as follows:
glb.scene.traverse(child => {
if (child.isMesh) {
//child.material = new THREE.MeshPhongMaterial({ flatShading: true });
}
});
but everything just looks a solid gray color and doesn't contain any of the properties of the mesh basic material it replaced.
The default material in glTF is usually mapped to MeshStandardMaterial in three.js — your model must have the "unlit" glTF extension (KHR_materials_unlit) enabled if it's creating MeshBasicMaterial. Short of changing that in a modeling tool like Blender, which might be easiest, you can also convert it in three.js...
model.traverse((child) => {
if ( ! child.isMesh ) return;
var prevMaterial = child.material;
child.material = new MeshPhongMaterial();
MeshBasicMaterial.prototype.copy.call( child.material, prevMaterial );
});
Note that the reverse does not necessarily work — calling a complex material's copy() method on a simpler material (like MeshBasicMaterial) will cause it to look for properties that do not exist.
From what I know it should be possible to use MeshStandardMaterial to define metal-like-materials in Three.js which should follow a pbr-roughness-metalness-workflow but I cannot find any good examples on how to accomplish that.
I cannot use Phong-Shader, I have to stick to MeshStandardMaterial.
I want to achieve something like this:
Yes, you can use MeshStandardMaterial to represent a metal-like material. Be sure to specify an environment map -- especially for metals.
material = new THREE.MeshStandardMaterial( {
color: 0xffffff,
roughness: roughness,
metalness: metalness,
roughnessMap: roughnessMap,
metalnessMap: metalnessMap,
envMap: envMap, // important -- especially for metals!
envMapIntensity: envMapIntensity
} );
See the three.js example.
three.js r.84
I'm attempting to get a basic THREE.js example to work and modify it from there on out but it just keeps outputting a torus, no matter what I change.
I've copied the exact code from the docs page into a JSFiddle and again I get a torus.
Here is the docs page example:
CylinderGeometry
And here is the jsfiddle with the torus: https://jsfiddle.net/ded9grxn/
I've tried adding the code from the docs page to the example like so:
var geometry = new THREE.CylinderGeometry( 5, 5, 20, 32 );
var material = new THREE.MeshPhongMaterial(
{
color: 0x156289,
emissive: 0x072534,
side: THREE.DoubleSide,
shading: THREE.FlatShading
});
mesh.add(
new THREE.Mesh(
geometry,
material
)
);
But to no avail. Any help is appreciated!
The reason you fiddle does not work is that the script you invoke (https://threejs.org/docs/scenes/js/geometry.js) looks at the hash in the URL of the window to select the object.
If you go to
https://threejs.org/docs/scenes/geometry-browser.html#CylinderGeometry
you get the cylinder.
If you go to
https://threejs.org/docs/scenes/geometry-browser.html
you get the default, which is a torus.
For the reason why your modification does not work, we need more information about how you performed the modif (what did you remove, where did you add).
(Edit) in the fiddle, after doing your modification, do not forget to remove the line
var options = chooseFromHash( mesh );
this is where your script invokes the function in geometry.js that will set the mesh according to the hash in the URL
How can we create glossy effects on materials with three.js like the one on this link?
I am not interested in path tracing (yet :) )
WebGL Path Tracing
Glossy refers to the ability of a material to reflect light in the specular direction.
In three.js, you can use THREE.MeshPhongMaterial to do that. For example:
new THREE.MeshPhongMaterial( {
color: 0x996633,
envMap: envMap, // optional environment map
specular: 0x050505,
shininess: 100
} )
You can also use MeshStandardMaterial with an environment map.
three.js r.97