AdvancedcolorThe colour space this material's shader works in; see ColorSpace
'display' takes effect only on an unlit material, in a view with toneMapping: 'none' and no
enabled 'beforeToneMapping' effect, on a mesh no fog or vertex colours reach. Anywhere else
the shader works in linear light. To change it after the material has rendered, see
BaseMaterial3D.
Bits on a 'display' material should read colours through these helpers, which exist in both
shader stages and return the colour in the shader's space:
decodeColor(c: vec3): a display colour, such as a texture sample.inputTint(linearTint: vec4, displayTint: vec4): pass material.baseColor and
material.displayBaseColor, which the material fills once a bit declares them in
bindings.material.decodeFrame(c: vec3): a colour from a frame this view drew, such as a render-texture feed.Multiplying colours read this way gives the same bytes in both spaces. Adding, blending or
scaling them by a number doesn't, so the result changes when fog moves the shader to linear
light. On the display path, a SceneOutput bit that reads albedo sees display colours.
The values the material's shader reads, one property per field its bits declare; see MaterialData for how they read and write
Whether destroy() has run
ReadonlydoubleWhether back faces are drawn too, lit with their normal flipped; set by the doubleSided option
Optional ReadonlyemissiveRuntime glow controls; present only when the material was built with an emissive group
Readonly AdvancedextraThe shader bits this material was built with on top of its own, from the extraBits option
Fixed for the material's lifetime. BaseMaterial3D#clone makes a copy with more.
ReadonlyflatWhether triangles are shaded with their face normal; set by the flatShading option
ReadonlyfogOptionallabelName for debugging and for finding the material, such as the glTF material name the loader gives it; a Model3DOptions#materials record matches it
Whether the material's shader does lighting
Set it to false for a shader that does none, as FlatMaterial does. That leaves out
calculateShadow, so a shader that calls it fails to compile. To change it after the material
has rendered, see BaseMaterial3D.
Render state (blending, depth, culling) for every draw with this material
alphaMode and doubleSided set parts of it. To change a field after the material has
rendered, see BaseMaterial3D. polygonOffset works on WebGL only; WebGPU ignores it.
The material's textures by slot name, the same names the textures option takes
Assigning swaps the slot, and a name the material doesn't have throws. A swap reuses the
compiled shader, except that a real map in the normal slot, or the default put back, switches
normal mapping on or off.
Wrap mode, filtering and anisotropy come from each texture's source.style, which clamps by
default. To tile a texture, set texture.source.style.addressMode = 'repeat', then call
style.update().
Optional ReadonlytopologyPrimitive topology for every pass that doesn't set its own; set by the topology option, and PassDescriptor lists what overrides it
AdvanceduidUnique id for this material instance
Whether a geometry's vertex colours (its colors) tint this material
Off by default, since exporters often fill the colour set with masks or weights; put data that
isn't colour in colors1 when you can. The glTF loader turns
it on, as glTF's COLOR_0 is a base colour multiplier in linear light; convert colours picked
in sRGB with srgbToLinear. To change it after the material has rendered, see
BaseMaterial3D.
Sets the base opacity
From 0 (transparent) to 1 (opaque)
Alpha below which fragments are discarded while BaseMaterial3D#alphaMode is 'mask'
Sets the alpha cutoff
Alpha below which fragments are discarded
How the material treats alpha; see AlphaMode
Setting it also sets the blending and depth writes of state. 'blend' turns depth writes
off, and its meshes cast no shadow. On a material built from a raw descriptor, 'mask'
discards only if the descriptor's bits include alphaMaskBit.
Base colour tint, read back as a hex number
Takes any ColorSource in display (sRGB) space, like Container.tint. The source's alpha is
ignored; BaseMaterial3D#alpha is the opacity.
Sets the base colour tint
Display colour; its alpha is ignored
Sets the strength of the normal map's bumps
Multiplier on the bumps
Sets the specular exponent
Specular exponent
Specular tint (rgb); takes any ColorSource and reads back a hex number, like
Container.tint
Sets the highlight scale
Scale; 0 removes the highlight
The UV transform you set, or undefined while the base colour texture's frame sets it
One transform, as glTF's KHR_texture_transform defines it, applies to every texture of the
material. Setting a matrix takes over from a framed (spritesheet) base colour texture, and a
framed texture assigned while it's set warns that its frame is ignored; setting undefined
hands it back. Either is a data write, never a shader rebuild. On a material whose bits lack
uvTransformBit, setting a matrix warns and does nothing.
A UV (u, v) becomes (a * u + b * v + tx, c * u + d * v + ty), transposed from pixi's
Matrix.apply, so new Matrix().rotate(rotation).scale(sx, sy).translate(x, y) gives the
KHR_texture_transform result for those values. The getter returns the material's own matrix;
changing it in place does nothing until you assign it again.
Sets the UV transform
The transform, or undefined to follow the base colour texture's frame
StaticEMPTYAdvanced
A shared material with no shader, which a Mesh3D holds until it's given a material
A mesh on it draws nothing and compiles no shader, though its skeleton and morph targets still
upload. Assign it to a mesh's material to stop the mesh drawing; to hide a mesh for a
while, visible = false is cheaper. Don't give it to a BatchedMesh3D slot that's in a
pass, even a hidden one: such a slot needs a real material.
Every waiting mesh shares it, so don't edit it. Its destroy does nothing, as with pixi's
Texture.EMPTY.
Makes a material of the same class that draws as this one does now, with the options you pass changed
options are the class's constructor options. clone reads this material's current values
back as those options, merges yours over them, and passes the result to the class's
constructor. An option left out, or set to undefined, keeps this material's value. One that
takes an object, such as a feature group or passes, is merged one level deep:
emissive: { strength: 2 } on a Material3D keeps its emissive colour. descriptor is
replaced whole. A group the material doesn't have, such as clearcoat, adds the feature.
extraBits adds to this material's BaseMaterial3D#extraBits, skipping a bit it already
has. Fields a new bit declares start at 0 and its texture slots hold Texture.WHITE, so set
them on the copy. The fields of the extra bits it already had keep their values.
A raw-descriptor material, or any class that inherits BaseMaterial3D's _toOptions
unchanged, keeps every field value and texture it has, except those an option you pass sets.
What isn't an option comes across too: colorSpace, lit, the passes joined with
BaseMaterial3D#enablePass, and state with any change made through it, except the
flags an option you pass sets, such as alphaMode's blending. Colour options read back as
8-bit hex, as their getters return them.
Textures are shared, not copied. Everything else belongs to the copy: assign it to meshes and
destroy() it when you're done, which leaves the shared textures alive. Materials with the same
bits share compiled shaders, so a copy compiles nothing new unless its bits are new.
Optionaloptions: PhongMaterialOptions
Constructor options to change on the copy; left out, it's a plain copy.
The copy, of the same class.
Frees the material for good, as BaseMaterial3D#destroy does
Optionaloptions: TypeOrBool<TextureDestroyOptions>
Whether to destroy the textures too
Removes this material from a custom render pass
Meshes using the material leave the pass on the next render, except one that joined it through
Mesh3D#enablePass. An override given for the pass in the passes option is kept, so
BaseMaterial3D#enablePass brings it back.
The pass's name, such as 'outline'.
Adds this material to a custom render pass, such as an OutlinePass, as naming it true
in the passes option does
Meshes using the material draw in the pass from the next render, except one that left it through Mesh3D#disablePass. BatchedMesh3D slots take their passes from BatchedMesh3D#setPassesAt instead. Overrides for the pass can only be given at construction, and the passes option has the limit on custom pass names.
The pass's name, such as 'outline'.
Advanced
The shader descriptor for a view, one per kind of environment
View whose environment picks the descriptor
Frees the GPU memory of this material's textures until a frame draws them again
The next frame that draws the material re-uploads them from their CPU copies, so it keeps
drawing the same. Texture sources are shared, so every other material using one re-uploads it
too, as with texture.source.unload(). The engine's default textures are skipped, and so are
render textures and ContainerTextures, whose pixels exist only on the GPU.
Call BatchedMesh3D#invalidate for each batch slot that draws the material. Does nothing once the material is destroyed.
view.root.removeChild(model);
material.unload(); // hand the texture memory back until the model is shown again
Model3D.unload For giving back a whole model's geometry and textures at once.
A Blinn-Phong material: diffuse shading plus a specular highlight
Cheaper than Material3D and easy to art-direct:
shininesssets the size of the highlight andspecularColorits tint. A Phong mesh and a PBR mesh read at the same brightness under the same lights.The view's
environmentadds diffuse fill only; highlights come from direct lights, so use Material3D for surfaces that should reflect their surroundings. The specular and emissive maps cost nothing unless you pass them at construction, and the normal map costs nothing until you assign one.extraBitsrun after the material's own maps and before lighting, so they see the texturedalbedoandalpha. Theirendcode runs after lighting and before tone mapping.Example