Glossy materials in THREE.js - three.js

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

Related

Three JS - How do I change from Lambert to Phong on a material at runtime?

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/.

how do i convert all materials in a loaded gltf from mesh basic to mesh phong?

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.

Metal Material with MeshStandardMaterial in three.js

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

How do you set which side a decal displays on a THREE JS mesh?

I am trying to apply a decal to the outside of a mesh object using DecalGeometry. However, the decal appears on the inside of the mesh. I've tried rotation and position settings within the DecalGeometry, but can't seem to affect which side of the mesh the decal appears on. FWIW, the mesh is a custom OBJ model. My code is a bit extensive to post here, but you can view the issue here. I have red BoundingBoxHelpers to help visualize the placement.
The materials object has a parameter which allows you to designate the side(s) of the mesh on which it will display (thanks #j-t for posting this question Prevent decal from showing on inside of mesh. My working code looks like this...
var decalMaterial = new THREE.MeshPhongMaterial( {
map: decalNormal,
transparent: true,
depthTest: true,
depthWrite: false,
polygonOffset: true,
polygonOffsetFactor: - 4,
side: THREE.DoubleSide
});

Three.js - Is FlatShading implemented for BufferGeometry

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

Resources