PhotoTo3D DOCS
Appearance

Customizing materials

Override the generated PBR materials at runtime while keeping the contract intact.

What the factory generates

Each entry in the spec's materials array becomes a THREE.MeshStandardMaterial built from six fields: color, roughness, metalness, emissive and emissiveIntensity. Meshes reference a material by its materialIndex, so several parts can share one material instance.

MeshStandardMaterial is physically based, so it responds correctly to environment maps, lights and shadows in any standard Three.js or R3F scene. There is no custom shader to reverse-engineer.

Override at runtime

Because the values are plain material properties, you can retune the look without regenerating anything. Find the mesh through the runtime, then write to its material — color takes any THREE.Color-compatible value, roughness and metalness run 0 to 1, and emissive plus emissiveIntensity drive glow.

Remember that materials are shared by index. Editing one material property changes every part that points at it. If you need a part to differ, clone its material first and assign the clone back to that mesh.

const mat = model.userData.sculptRuntime.nodes.shell.material;
mat.color.set('#c8402d');
mat.roughness = 0.35;
mat.metalness = 0.1;

// Independent variant for one part:
const solo = mat.clone();
solo.emissive.set('#ff5500');
solo.emissiveIntensity = 1.5;
model.userData.sculptRuntime.nodes.core.material = solo;

Swap textures, keep the PBR contract

To go beyond flat colors, load a texture and assign it to the map slot the same way you would on any MeshStandardMaterial. The generated color acts as a tint over the map, so reset it to white when you want the texture unmodified.

Keep additions within the standard PBR channels — map, roughnessMap, metalnessMap, normalMap, emissiveMap. Set material.needsUpdate = true after changing map slots so Three.js recompiles the material.

const tex = await new THREE.TextureLoader().loadAsync('/wood.jpg');
tex.colorSpace = THREE.SRGBColorSpace;
const mat = model.userData.sculptRuntime.nodes.shell.material;
mat.map = tex;
mat.color.set('#ffffff');
mat.needsUpdate = true;