Appearance
Materials
A Material is what a surface looks like – color, texture, reflectivity, shader. Use the Material builder to construct one inline, reference an existing library material by id, or clone a library material and tweak it.
Kinds
Six factories. Pick the one that matches the look you need.
| Factory | Use for |
|---|---|
Material.unlit({...}) | Flat-shaded surfaces – UI, billboards, vertex-colored point clouds. Renders the same regardless of scene lighting. |
Material.pbr({...}) | Realistic surfaces – metal, plastic, fabric. Responds to scene lighting. |
Material.occlusion({...}) | Invisible itself but hides geometry behind it – holdouts, portals. |
Material.customShader({...}) | Author-supplied Metal shader functions from a compiled .metal library. |
Material.materialX({...}) | ShaderGraph material authored in Reality Composer Pro / .usda. |
Material.video({...}) | Video texture playback. |
Inline construction
Factory + options object reads naturally:
javascript
// Unlit – single flat color
const red = Material.unlit({ color: '#FF0000' });
// PBR – color + metalness + roughness, no textures
const gold = Material.pbr({
color: '#FFD700',
metalness: 1.0,
roughness: 0.2
});
// PBR – textured
const brick = Material.pbr({
color: '#FFFFFF', // tints the texture
map: 'brick-albedo.png',
normalMap: 'brick-normal.png',
roughnessMap: 'brick-rough.png'
});Same chained, if you prefer:
javascript
const gold = new Material('pbr')
.color('#FFD700')
.metalness(1.0)
.roughness(0.2);Input shapes
Colors – color, emissive, sheenColor, specularColor:
'#RRGGBB'or'#RRGGBBAA'{ r, g, b, a }with values in 0..1{ colorSpace: 'p3', hex: 'FF6600' }
Textures – map, emissiveMap, normalMap, etc.:
- URL string:
'https://.../texture.png' - Asset id string:
'libraryTextureId' - With a scale:
{ texture: 'urlOrId', scale: 0.5 }
Scalars – roughness, metalness, clearcoat, opacity, emissiveIntensity: plain numbers.
Library reference
Materials authored in the experience editor are referenced by id directly – no inline construction needed:
javascript
// Apply a library material to a mesh
await scene.createEntity(createMesh({
...,
materials: ['myLibraryMaterialId']
}));Or fetch one with scene.getMaterial(id) to inspect:
javascript
const mat = scene.getMaterial('myLibraryMaterialId');
console.log(mat); // → Material(pbr 'My Material' id=..., color=#FFAA00, roughness=0.3)Clone → tweak → apply
To override a library material for a single entity (without mutating the library entry), clone it first:
javascript
const base = scene.getMaterial('redMatId');
const brighter = base.clone()
.emissive('#FF0000')
.emissiveIntensity(2);
await entity.representation.setMaterial(brighter);.clone() deep-copies the material with a fresh id. The original library material is untouched.
ShaderGraph (MaterialX) parameters
ShaderGraph materials authored in Reality Composer Pro expose promoted inputs. Set constant values via setParameter(name, value, typeHint?):
javascript
const mat = scene.getMaterial('myShaderGraphMatId').clone()
.setParameter('intensity', 0.6)
.setParameter('tintColor', '#FF00FF', { type: 'color' })
.setParameter('offset', [0.1, 0.2, 0], { type: 'vector3' });The same setParameter works on customShader materials too – the Material auto-routes to the right options blob based on its kind.
Type hints override inferred types: { type: "float" | "int" | "vector2" | "vector3" | "vector4" | "color" | "boolean" | "string" }
For runtime variable bindings (slider drives a parameter), use entity.representation.bindMaterialParameter(parameterName, variableId) – different path, lives on the entity, ties into the variable system.
Runtime swap
Replace an entity's material at runtime:
javascript
// Cycle materials every 2 seconds
const palette = [
Material.unlit({ color: '#4287F5' }),
Material.pbr({ color: '#42F578', metalness: 0.5, roughness: 0.3 }),
Material.unlit({ color: '#F54242' })
];
let i = 0;
scene.on('schedule', { interval: 2 }, async function() {
i = (i + 1) % palette.length;
await entity.representation.setMaterial(palette[i]);
});setMaterial accepts a Material instance, a library ref-id string, or { id, target? }. setMaterials([...]) for multiple at once.
Introspection
javascript
console.log(material); // → Material(pbr id=..., color=#FF6600, roughness=0.3)
console.log(JSON.stringify(material, null, 2)); // → full Codable JSON
material.kind; // → 'pbr'
material.id; // → 'AB12CD34'
material.baseColor; // → { color: { colorSpace: 'p3', hex: 'FF6600' } }
material.materialXOptions?.parameters; // → { intensity: { ... } } for materialXFor setter names that conflict with property names (roughness, opacity, clearcoat, emissiveIntensity), read via material.data.<field> – e.g. material.data.roughness?.scale.
Target
By default a material applies to all models on an entity. Override for multi-model entities:
javascript
Material.pbr({ color: '#FF0000' })
.target({ type: 'firstModel' });
Material.pbr({ color: '#0000FF' })
.target({ type: 'selectedModels', models: ['windshield'], materialSlots: [0] });