Skip to content

Instantly share code, notes, and snippets.

@lukeschaefer
Last active June 13, 2024 13:21
Show Gist options
  • Select an option

  • Save lukeschaefer/e7def89153923881ac0a44756b800246 to your computer and use it in GitHub Desktop.

Select an option

Save lukeschaefer/e7def89153923881ac0a44756b800246 to your computer and use it in GitHub Desktop.
How to mix Baked Textures and Physically Based Rendering in ThreeJS

How to mix Baked Textures and Physically Based Rendering in ThreeJS

When baking a texture in Blender (or other 3D editing software) and using it in ThreeJS as a MeshBasicMaterial - it will not interact with any lighting in your scene. If you try to use a material that will (EG MeshStandardMaterial) you'll find that your baked textures don't look right - because they're being lit both during the baking and the real-time-rendering.

Using this material will allow you to have specular reflections (EG glossy or shiny textures) while still maintaining baked lighting. Here's an example of what I'm talking about:

Bake Technique Comparison

Here's the code that enables this. Simply copy-and-paste it into your project. Remove the typescript typings if you're on vanilla JS.

import * as THREE from 'three';

const before = `totalDiffuse + totalSpecular + totalEmissiveRadiance`;
const after = `sampledDiffuseColor.rgb + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance`

export class MeshBakedMaterial extends THREE.MeshStandardMaterial {
  constructor(parameters?: THREE.MeshStandardMaterialParameters) {
    super(parameters);    

    this.onBeforeCompile = (shader) => {
      shader.fragmentShader = shader.fragmentShader.replace(before, after)
    };
  }
}

With this approach you can continue to use roughness/metalness values or maps, and get dramatic results, while still saving on performance by baking nice shadows. Use like so:

const mat = new MeshBakedMaterial({map: bakedMap, roughness: 0.1, metalness: 0.3});

Shout out to Bruno Simon and his ThreeJS Journey class, without which I'd be completely lost.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment