Skip to main content

<pc-material>

The <pc-material> tag is used to define a material that can be applied to <pc-render> components via their material attribute.

Usage
  • It must be a direct child of <pc-app>.

The element wraps the engine's StandardMaterial and is metal/rough by default: unlike a bare StandardMaterial, the metalness workflow is enabled (use-metalness defaults to "true"), which is what the metalness-* attributes assume and what glTF and other PBR tools mean by PBR. As a companion to that default, metalness starts at 0 (dielectric) rather than the engine's 1, so a material with just a diffuse color renders as that color rather than as a fully metallic surface. Set metalness="1" for a metal.

Gloss vs roughness

The roughness and roughness-map attributes are aliases for gloss and gloss-map that additionally invert the gloss channel. Use one family or the other on a given material — mixing them logs a console warning, because the two families disagree about inversion. The gloss-map-* modifiers carry no inversion of their own, so they are the supported way to configure a roughness-map.

Attributes

AttributeTypeDefaultDescription
alpha-testNumber"0"Alpha test reference value. Fragments with an opacity below this value are discarded
alpha-to-coverageBoolean"false"Whether to use alpha-to-coverage, which resolves transparency using multisampling
ao-intensityNumber"1"Strength of the ambient occlusion map, from 0 to 1
ao-mapString-id of a texture <pc-asset> used as the ambient occlusion map
blend-typeEnum"none"How the material is blended with the scene behind it: "none" | "normal" | "additive" | "additive-alpha" | "premultiplied" | "multiplicative" | "multiplicative-2x" | "screen" | "min" | "max" | "subtractive"
bumpinessNumber"1"Strength of the normal map, where 0 is flat and 1 is the map's full effect
cullEnum"back"Which faces of a mesh are culled: "none" | "back" | "front" | "front-and-back"
depth-biasNumber"0"Offset applied to the depth of a fragment, used to resolve z-fighting
depth-testBoolean"true"Whether fragments are tested against the depth buffer
depth-writeBoolean"true"Whether fragments write to the depth buffer
diffuseColor"1 1 1"Diffuse color of the material
diffuse-mapString-id of a texture <pc-asset> used as the diffuse map
emissiveColor"0 0 0"Emissive color of the material
emissive-intensityNumber"1"Multiplier applied to the emissive color and map
emissive-mapString-id of a texture <pc-asset> used as the emissive map
enable-ggx-specularBoolean"false"Whether to use the GGX specular model, which supports anisotropy
fresnel-modelEnum"schlick"Fresnel model used for specular reflections at grazing angles: "none" | "schlick"
glossNumber"0.25"Glossiness of the material, from 0 (rough) to 1 (shiny). See roughness
gloss-invertBoolean"false"Whether the gloss value and map are inverted, making the material treat them as roughness. Setting roughness or roughness-map enables this automatically
gloss-mapString-id of a texture <pc-asset> used as the gloss map
height-mapString-id of a texture <pc-asset> used as the height map
height-map-factorNumber"1"Strength of the parallax effect driven by the height map
idString-Unique identifier used by other tags to reference this material
metalnessNumber"0"How metallic the surface is, from 0 (dielectric) to 1 (metal)
metalness-mapString-id of a texture <pc-asset> used as the metalness map
nameString"Untitled"Name of the material. A label, not a reference: other tags always address the material by id
normal-mapString-id of a texture <pc-asset> used as the normal map
occlude-directBoolean"false"Whether ambient occlusion also attenuates direct lighting
occlude-specularEnum"ao"How specular reflections are occluded: "none" | "ao" | "gloss-dependent"
opacityNumber"1"Opacity of the material, from 0 (transparent) to 1 (opaque). Requires a blend-type other than "none" to have a visible effect
opacity-ditherEnum"none"Dithering used to render opacity, which approximates transparency without blending: "none" | "bayer8" | "bluenoise" | "ignnoise"
opacity-fades-specularBoolean"true"Whether specular highlights fade out as the material becomes transparent
opacity-mapString-id of a texture <pc-asset> used as the opacity map
roughnessNumber-Roughness of the material, from 0 (shiny) to 1 (rough). An alias for gloss that also sets gloss-invert, so do not combine it with the gloss attributes
roughness-mapString-id of a texture <pc-asset> used as the roughness map. An alias for gloss-map that also sets gloss-invert, so do not combine it with the gloss attributes
slope-depth-biasNumber"0"Depth offset applied in proportion to a surface's slope, used to resolve z-fighting
specularColor"0 0 0"Specular color of the material. Applies only when the metalness workflow is disabled or use-metalness-specular-color is enabled
specularity-factorNumber"1"Strength of specular reflections at direct angles, from 0 to 1. Applies only when use-metalness-specular-color is enabled
two-sided-lightingBoolean"false"Whether back faces are lit as though their normals were flipped
use-fogBoolean"true"Whether the material is affected by scene fog
use-lightingBoolean"true"Whether the material is affected by scene lights. When disabled, the material renders unlit using the diffuse color and map alone
use-metalnessBoolean"true"Whether to use the metalness workflow rather than the older specular workflow
use-metalness-specular-colorBoolean"false"Whether the specular color tints reflections while the metalness workflow is in use
use-skyboxBoolean"true"Whether the material is lit by the scene's skybox
use-tonemapBoolean"true"Whether the camera's tone mapping is applied to the material

Texture Map Modifiers

Every *-map attribute above defines a texture slot, and each slot accepts a set of companion modifiers that configure how its texture is sampled. Replace <slot> with one of ao, diffuse, emissive, gloss, height, metalness, normal or opacity:

AttributeTypeDefaultDescription
<slot>-map-channelEnumvariesTexture channel(s) to read the map from
<slot>-map-offsetVector2"0 0"UV offset of the map
<slot>-map-rotationNumber"0"Rotation of the map in degrees
<slot>-map-tilingVector2"1 1"Tiling (repeat) of the map across the surface
<slot>-map-uvNumber"0"Index of the UV set used to sample the map

The -map-channel modifier varies by slot:

  • The color maps (diffuse, emissive) accept "r" | "g" | "b" | "a" | "rgb" and default to "rgb".
  • The scalar maps (ao, gloss, height, metalness) accept "r" | "g" | "b" | "a" and default to "g".
  • The opacity map accepts "r" | "g" | "b" | "a" and defaults to "a".
  • The normal map has no channel modifier — it always reads all three channels.

Example

Four materials: a plain color, a metal, a transparent "glass" and a tiled texture map. The sky's lighting gives the metal something to reflect. Try editing diffuse colors, metalness, roughness, opacity or the diffuse-map-tiling:

Live Example
<pc-app>
<pc-asset src="https://developer.playcanvas.com/assets/dark-tiles.png" id="dark-tiles"></pc-asset>
<pc-asset src="https://developer.playcanvas.com/assets/sepulchral-chapel-rotunda-4k.webp" id="skybox"></pc-asset>
<pc-material id="crimson" diffuse="crimson"></pc-material>
<pc-material id="gold" diffuse="#ffd700" metalness="1" roughness="0.3"></pc-material>
<pc-material id="glass" blend-type="normal" opacity="0.4"></pc-material>
<pc-material id="ground" diffuse-map="dark-tiles" diffuse-map-tiling="4 4"></pc-material>
<pc-scene>
<pc-sky asset="skybox" lighting></pc-sky>
<pc-entity name="camera" position="0 1.5 5" rotation="-12 0 0">
<pc-camera clear-color="#1d1f2b" tonemap="aces"></pc-camera>
</pc-entity>
<pc-entity name="light" rotation="45 30 0">
<pc-light cast-shadows intensity="1.5"></pc-light>
</pc-entity>
<pc-entity name="box" position="-2 0.5 0">
<pc-render type="box" material="crimson"></pc-render>
</pc-entity>
<pc-entity name="sphere" position="0 0.5 0">
<pc-render type="sphere" material="gold"></pc-render>
</pc-entity>
<pc-entity name="capsule" position="2 1 0">
<pc-render type="capsule" material="glass"></pc-render>
</pc-entity>
<pc-entity name="ground" scale="10 1 10">
<pc-render type="plane" material="ground"></pc-render>
</pc-entity>
</pc-scene>
</pc-app>

A <pc-material> inserted at runtime (after the application has started) creates its material on insertion, so materials can be added dynamically from JavaScript. Attribute changes made at runtime also take effect immediately — a burst of changes is coalesced into a single material update — and removing a *-map attribute clears that texture slot.

The name attribute is worth setting on any material you expect to identify later. It reaches the engine material, so it is the label that shows up wherever materials surface by name: profilers, GPU captures, and the assignments <pc-model>'s hierarchy() reports — including on a material swapped in by <pc-node>'s material-overrides, which otherwise reads as Untitled there. It has no bearing on how the material is referenced, which is always by id.

JavaScript Interface

You can programmatically create and manipulate <pc-material> elements using the MaterialElement API.