Skip to main content

Key Concepts

A material in 3dverse defines the visual appearance of an entity. It is an asset, like scenes or meshes, and wraps a specific shader program along with its parameter bindings. More precisely, a material acts as a binding to a shader: it selects which shader to use and provides values for that shader’s inputs (uniforms and textures).

Materials provide the link between shaders and scene data: they declare which shader is used, and how its parameters are set.

Entities and Materials

To be visible in a scene, an entity must at least have:

Without these, the renderer cannot produce pixels for the entity.

Inline vs Asset Material Data

When using the material component, the shader inputs are stored inline on the entity. When using the material_ref component, they are stored in a dedicated material asset, outside of the scene.

Material vs Material Reference

There are two ways to assign materials to entities:

material

  • Declares a material inline on the entity.
  • References a shader directly and provides values for its attributes.
  • Changes affect only this entity.

Use this when you need a one-off instance (e.g., make a single cube bright red without touching other cubes).

material_ref

  • Points to a material asset stored in the project.
  • The asset itself references a shader and defines its attributes.
  • Multiple entities can share the same material_ref.
  • Updating the material asset propagates the changes to all entities referencing it.

This enables material reuse, allowing multiple entities to look consistent while being driven by a single shared asset.

Use this when you want consistent look across instances (e.g., all walls share a single “Concrete” material).

Diagram


Material Component vs Material Asset
  • material → inline, entity-local, changes affect only this entity.
  • material_ref → points to a material asset in the project, changes propagate to all referencing entities.

Both connect to shaders, but the key difference is scope: local vs shared, entity data vs asset data.

Shader Parameters

A material exposes a set of uniform parameters and textures defined by its shader:

  • Scalars & vectors (e.g., roughness, emissiveFactor).
  • Textures (e.g., albedoMap, normalMap).

When you edit a material in the editor:

  • For material_ref, you're editing the asset's parameters — changes apply to all references.
  • For material, you're editing local values stored directly on the entity.

Default PBR Shaders

3dverse ships with a default set of physically based rendering (PBR) shaders. They implement industry-standard workflows:

  • Metallic–Roughness model (albedo, metallic, roughness, normal, occlusion, emissive).
  • Energy conservation and Fresnel handling.
  • Compatible with both rasterization and ray tracing pipelines.

You can use them directly, or extend them with custom shaders.

Material Assignment Strategy

The split between material and material_ref components is designed for efficient scene authoring:

  • Use material_ref when many entities must share the same look, since the asset can be updated once and propagate everywhere.
  • Use material when the shader and parameters are defined directly on the entity itself, typically for unique or experimental cases.

This design enables you to balance consistency (centralized assets) and flexibility (per-entity definitions without asset duplication).

Example

Imagine a scene with 100 chairs:

  • Each chair entity has a mesh_refChairMesh.
  • All chairs share a material_refWoodVarnished.
  • One chair has an inline material where you set albedo = red.

Now:

  • Updating WoodVarnished in the asset browser will update 99 chairs.
  • The red chair stays red.
  • Use material assets (material_ref component) for anything repeated.
  • Use inline materials (material component) for special cases or quick testing, since the data lives only on that entity.
  • Extend the default PBR shaders with custom ones when you need advanced effects.

Materials and Render Graphs

Material Graph Compatibility

A material created for one render graph cannot be used in another with a different output contract. For example, a material targeting the Deferred PBR graph won’t be valid in a stylized forward graph.

A material is not universal — it only makes sense for the render graph it was created for.

The render graph defines the sequence of passes, attachments, and shader programs that produce the final frame. When you assign a material to an entity, you are effectively binding that entity’s attributes (uniforms, textures) into the shader inputs, while the render graph enforces a strict contract on the shader outputs.

The contract

  1. Shader outputs must conform

    • The number and semantics of the render targets a shader writes to are dictated by the render graph.
    • Example: “the first render target must be albedo, the second must be normals.”
    • Any shader used in materials for this render graph must write exactly those outputs, in that order.
    • Failure to conform will result in the material being rejected or rendering incorrectly.
  2. Inputs are flexible

    • The inputs of a shader (its uniforms, textures) are defined entirely by the shader itself.
    • A render graph may expose additional global resources (e.g. an SSAO buffer), but these are optional.
    • A material may choose to use them or ignore them — this does not affect validity, as long as the outputs remain correct.

Example

Consider two render graphs:

  • Deferred PBR graph

    • Output contract:
      • Render Target 0 → Albedo
      • Render Target 1 → Normals
      • Render Target 2 → Material properties (metallic, roughness, AO)
    • Optional inputs provided: SSAO texture, shadow mask, reflection probes.

    A PBR shader compiled for this graph must write values to all three render targets, in the specified order. It may use the SSAO or shadow mask if needed, but it can also ignore them — as long as the outputs are valid.

  • Stylized forward graph

    • Output contract:
      • Render Target 0 → Final shaded color
    • Optional inputs provided: None.

    A cel-shading shader for this graph only needs to write one output (color). It may define its own inputs such as tintColor, rampTexture, or outlineWidth. These inputs are completely under the shader’s control and are satisfied by the material.

Result: A material designed for the Deferred PBR graph cannot be reused in the Stylized graph because their output contracts differ. But within a given graph, different materials can define very different inputs — as long as their shaders write the expected outputs.

Key Takeaway

  • Inputs: Defined by the shader author. These include uniforms and textures like albedo, roughness, etc. Materials provide values for these.
  • Outputs: Dictated by the render graph. These define how the shader writes data to the pipeline (e.g. albedo, normals) and must be strictly matched.