How glTF Handles Depth Bias for Decal Rendering

The core glTF 2.0 specification does not natively include depth bias, polygon offset, or decal-specific pipeline parameters. Because glTF is designed as a portable, API-agnostic transmission format rather than a complete rendering engine state descriptor, hardware-level rasterization states are intentionally omitted. Consequently, handling depth bias and z-fighting for decals when using glTF requires a combination of custom metadata, engine-level configurations, or alternative geometry and shader techniques.

Why Core glTF Excludes Polygon Offset

The glTF standard intentionally abstracts away platform-dependent graphics states such as depth testing modes, stencil operations, and depth bias (glPolygonOffset in OpenGL/WebGL or depth bias in Direct3D and Vulkan). Including these parameters would tie the asset format directly to specific rasterization pipelines, creating inconsistencies across different rendering engines, deferred renderers, and ray tracing implementations. As a result, a standard glTF material definition cannot dictate whether a surface should be offset during the depth test pass.

Using the extras Field for Metadata

The most common way to carry depth bias parameters through glTF is by utilizing the standard extras object on materials or nodes. Digital content creation (DCC) tools and custom exporters can write pipeline hints directly into the glTF JSON:

"materials": [
  {
    "name": "Decal_Graffiti",
    "extras": {
      "depthBias": {
        "enabled": true,
        "factor": -1.0,
        "units": -4.0
      }
    },
    "pbrMetallicRoughness": { ... }
  }
]

When importing the model into an engine such as Three.js or Babylon.js, the loader script reads these properties and applies them directly to the active material instance (for example, setting material.polygonOffset = true, material.polygonOffsetFactor = -1, and material.polygonOffsetUnits = -4).

Geometric Offset in the Mesh

When relying on custom engine parsers is not an option, content creators often resolve decal z-fighting directly within the mesh geometry. In this workflow:

  • The decal mesh is modeled as a separate surface conforming closely to the base geometry.
  • The vertices of the decal mesh are physically displaced along their vertex normals by a small fraction of a unit (e.g., 0.1 mm to 1 mm).

While this method functions in any standard glTF viewer without custom code, it has notable trade-offs. The offset can introduce visible gaps when viewed from oblique angles, fail at steep grazing angles, or cause silhouette separation.

Screen-Space and Projected Decals

Modern real-time engines increasingly bypass mesh-level polygon offsets entirely in favor of screen-space decals or projected decal volumes. In this architecture:

  • The glTF file does not contain a pre-conformed surface mesh with depth bias.
  • Instead, glTF nodes can represent simple bounding box volumes or custom null objects marking decal positions, orientations, and scales.
  • The host rendering engine takes the decal textures from the glTF file and projects them onto the scene depth buffer during the deferred or forward-plus shading pass.

This approach completely eliminates z-fighting and the need for polygon offset parameters, though it requires support directly from the host engine's rendering architecture rather than the glTF file format itself.