A material for ThreeJS that allows you to combine the baked lighting from a MeshBasicMaterial, with the specular highlights of MeshStandardMaterial. Check out the live example to see what this does for you. For more info, scroll down to About.
Baked Texture with Physically Based Rendering |
Install with npm via npm install mesh-baked-material
.
Use in your project like so:
import MeshBakedMaterial from 'mesh-baked-material';
const mat = new MeshBakedMaterial({map: bakedMap, roughness: 0.1, metalness: 0.3});
const mesh = new THREE.Mesh(new THREE.BoxGeometry(1), mat);
You can use all the same parameters as with MeshStandardMaterial, including roughnessMap
and metalnessMap
.
The classic approach to using a baked texture in Three.js is as a MeshBasicMaterial. This material is used because it will not interact with any lighting in your scene - we want it to be rendered without realtime lighting, since the lighting has been baked into the texture already. Here's how that looks in practice:
How it looks in Blender |
Baked Texture |
How it looks in Three.js |
However, if your scene as textures that should be a little glossy or metalic, you'll find that your textures look very flat in ThreeJS. This is because MeshBasicMaterial cannot render materials that interact with lights. In the above example, look how flat the floor texture looks -there's none of the specular/glossy reflections from the Blender scene.
You may attempt to fix this by using a MeshStandardMaterial instead - which will interact with lights in your scene. This means we have to add lighting to the Three.js scene to try to match our renders. You can add an AmbientLight to add some of the light back in, but in order to get the same reflections as in your render, you'll have to add the same lighting as in your bake. Here's an example of how this looks:
Three.js with MeshStandardMaterial |
This doesn't look too bad at first glance - we have our glossy reflections, and some soft shadows in there. But on closer looks there's some issues that make it looks worse than our initial render. For example:
- Lighting is way too saturated
- the pillars are too bright and too dark
- the shadows on the floor are washed out
- the monkey is too contrasty
The reason why this result looks much worse is because now we're "double-dipping" on our lighting. We baked the textures with lights in them, and now they're in a scene with the same lights again. The brighter parts will become brighter, and the darker parts will become darker.
This is where our MeshBakedMaterial comes in. It's the same as MeshStandardMaterial, but will not addition diffuse lighting to an texture, only specular lighting. This means you can add roughness/metalness maps to a baked texture, without it being over or underlit from the scene lights. Take a look:
Final Result with MeshBakedMaterial |
MeshBakedMaterial will enable you to have specular reflections on your baked textures, without double-dipping on your lighting. With this approach you can continue to use roughness/metalness values or maps, and get dramatic results, while still keeping those beautifully baked shadows.
Shout out to Bruno Simon and his ThreeJS Journey class, I highly recommend it!