# PBR Material Attributes in TRELLIS.2: Encoding and Rendering Guide

> Learn how TRELLIS.2 encodes Physically-Based Rendering PBR material attributes like base color and roughness using texture objects or voxel tensors for efficient rendering.

- Repository: [Microsoft/TRELLIS.2](https://github.com/microsoft/TRELLIS.2)
- Tags: how-to-guide
- Published: 2026-08-03

---

**TRELLIS.2 encodes Physically-Based Rendering (PBR) material attributes—base color, metallic, roughness, and alpha—as either `trimesh.visual.material.PBRMaterial` texture objects or sparse voxel attribute tensors that are sampled during rendering using trilinear interpolation.**

TRELLIS.2 leverages PBR material attributes to model realistic surface appearance under varying lighting conditions. Understanding how these attributes are encoded—from texture packing conventions to voxel grid layouts—is essential for working with the framework's mesh and voxel representations. The implementation spans material creation in `o-voxel`, attribute sampling in the rendering pipeline, and texture export utilities in the data toolkit.

## What Are PBR Material Attributes?

PBR material attributes in TRELLIS.2 follow the metallic-roughness workflow, providing physically accurate parameters for light interaction. The framework supports four core channels that define a material's visual properties.

### Core Material Channels

- **Base Color**: The diffuse reflectance (albedo) of the surface, represented as RGB values across three channels.
- **Metallic**: A scalar value (0–1) indicating how metal-like the surface appears, where 0 represents dielectric materials and 1 represents pure metals. In TRELLIS.2, this is typically packed into the **Blue channel** of a texture.
- **Roughness**: A scalar controlling micro-facet surface roughness and glossiness. This is typically packed into the **Green channel** of a texture.
- **Alpha (Opacity)**: A single scalar representing surface transparency, stored as an additional dedicated channel.
- **Emissive** (Optional): RGB values for self-illumination, included when materials require glow effects.

## How TRELLIS.2 Encodes PBR Material Attributes

The framework encodes these attributes in two primary contexts depending on the representation stage: traditional texture-based materials for meshes and attribute tensors for sparse voxel grids.

### Texture-Based Encoding with Trimesh PBRMaterial

When loading mesh geometry, TRELLIS.2 wraps material properties in `trimesh.visual.material.PBRMaterial` instances. In [`o-voxel/o_voxel/postprocess.py`](https://github.com/microsoft/TRELLIS.2/blob/main/o-voxel/o_voxel/postprocess.py) (lines 294-296), the constructor receives texture paths or arrays for each PBR channel:

```python
mesh.visual.material = PBRMaterial(
    baseColorTexture=base_color,
    metallicTexture=metallic,    # Packed in B channel

    roughnessTexture=roughness,  # Packed in G channel

    opacityTexture=opacity,
)

```

This approach stores PBR data as standard image textures that can be directly rendered by compatible engines or processed by the framework's voxelization pipeline.

### Voxel Grid Encoding for Sparse Representations

For the O-Voxel sparse representation, PBR attributes are stored as a **voxel attribute tensor** (`mesh.attrs`) with an accompanying layout dictionary (`mesh.layout`). According to the source in [`trellis2/renderers/pbr_mesh_renderer.py`](https://github.com/microsoft/TRELLIS.2/blob/main/trellis2/renderers/pbr_mesh_renderer.py) (lines 23-43), the layout maps attribute names to specific channel indices within the tensor:

- **Base Color**: Occupies three consecutive channels (R, G, B)
- **Metallic**: Single channel storage
- **Roughness**: Single channel storage  
- **Alpha**: Single channel storage

During rendering, the `PbrMeshRenderer` samples this tensor using `grid_sample_3d` with trilinear interpolation to obtain per-pixel material values.

## Rendering Pipeline Implementation

The `PbrMeshRenderer` class in [`trellis2/renderers/pbr_mesh_renderer.py`](https://github.com/microsoft/TRELLIS.2/blob/main/trellis2/renderers/pbr_mesh_renderer.py) handles the extraction of PBR attributes during the rendering pass. The renderer performs trilinear sampling on the voxel attribute tensor and unpacks the channels into the output dictionary.

### Channel Extraction and Output

As implemented in lines 38-42 of [`pbr_mesh_renderer.py`](https://github.com/microsoft/TRELLIS.2/blob/main/pbr_mesh_renderer.py), the renderer populates the G-buffer with specific keys:

```python

# From the sampled voxel attributes

output = {
    'gb_basecolor': sampled_rgb,
    'gb_metallic': metallic_channel,
    'gb_roughness': roughness_channel,
    'gb_alpha': alpha_channel,
}

```

These outputs feed into the `nvdiffrast` PBR pipeline for final shading and composition.

## Working with PBR Materials in Code

### Creating a Mesh with PBR Textures

When preparing data for TRELLIS.2 pipelines, you can attach PBR materials to meshes using the following pattern from the O-Voxel post-processing utilities:

```python
import trimesh
from trimesh.visual.material import PBRMaterial

# Load geometry

mesh = trimesh.load('my_object.obj')

# Define PBR textures (paths or numpy arrays)

base_color = 'textures/basecolor.png'
metallic   = 'textures/metallic.png'   # Stored in B channel

roughness  = 'textures/roughness.png'  # Stored in G channel

opacity    = 'textures/opacity.png'

# Attach PBR material

mesh.visual.material = PBRMaterial(
    baseColorTexture=base_color,
    metallicTexture=metallic,
    roughnessTexture=roughness,
    opacityTexture=opacity,
)

```

### Rendering Voxelized Meshes

To render a mesh with voxel-based PBR attributes, use the `PbrMeshRenderer` as shown in the rendering pipeline:

```python
from trellis2.renderers.pbr_mesh_renderer import PbrMeshRenderer

# Initialize renderer with camera parameters

renderer = PbrMeshRenderer(
    rendering_options={"resolution": 512, "near": 0.1, "far": 10.0},
    device='cuda'
)

# Render with environment mapping

output = renderer.render(
    mesh=voxel_mesh,           # MeshWithVoxel containing attrs and layout

    extrinsics=cam_extr,
    intrinsics=cam_int,
    envmap=env_map,
    use_envmap_bg=True
)

# Access PBR outputs

base_color = output['gb_basecolor']
metallic = output['gb_metallic']

```

### Extracting PBR Textures from Datasets

The data toolkit provides utilities for dumping PBR textures from processed instances. In [`data_toolkit/dump_pbr.py`](https://github.com/microsoft/TRELLIS.2/blob/main/data_toolkit/dump_pbr.py) (lines 51-53), the extraction works as follows:

```python
from data_toolkit.utils import foreach_instance

def dump_pbr(instance, root):
    material = instance.mesh.visual.material
    # Save each channel as an image file

    material.baseColorTexture.save(f'{root}/basecolor.png')
    material.metallicTexture.save(f'{root}/metallic.png')
    material.roughnessTexture.save(f'{root}/roughness.png')
    material.opacityTexture.save(f'{root}/opacity.png')

```

## Summary

- **PBR material attributes** in TRELLIS.2 include base color (RGB), metallic (scalar), roughness (scalar), and alpha (scalar), following the standard metallic-roughness workflow.
- **Texture encoding** uses `trimesh.visual.material.PBRMaterial` instances created in [`o-voxel/o_voxel/postprocess.py`](https://github.com/microsoft/TRELLIS.2/blob/main/o-voxel/o_voxel/postprocess.py), with metallic packed in the Blue channel and roughness in the Green channel.
- **Voxel encoding** stores attributes as a sparse tensor (`mesh.attrs`) with a layout dictionary mapping channels, sampled during rendering via `grid_sample_3d` in `PbrMeshRenderer`.
- **Rendering output** produces G-buffer channels named `gb_basecolor`, `gb_metallic`, `gb_roughness`, and `gb_alpha` for shading with `nvdiffrast`.

## Frequently Asked Questions

### What channels does TRELLIS.2 use for metallic and roughness textures?

TRELLIS.2 follows the common convention of packing **metallic into the Blue channel** and **roughness into the Green channel** of texture maps. This packing strategy is implemented in [`o-voxel/o_voxel/postprocess.py`](https://github.com/microsoft/TRELLIS.2/blob/main/o-voxel/o_voxel/postprocess.py) when creating `PBRMaterial` objects from processed voxel data.

### How are PBR attributes stored in TRELLIS.2 voxel grids?

For sparse voxel representations (O-Voxel), PBR attributes are stored as a multi-channel tensor (`mesh.attrs`) alongside a layout dictionary that specifies which channels correspond to which attributes. The `PbrMeshRenderer` samples this tensor using trilinear interpolation to retrieve per-pixel material values during rendering.

### What is the role of PBRMaterial in the TRELLIS.2 pipeline?

`PBRMaterial` is a `trimesh.visual.material` class instance that encapsulates texture references for base color, metallic, roughness, and opacity. It serves as the bridge between raw texture data and the TRELLIS.2 processing pipeline, used in voxelization, texturing generation ([`trellis2/pipelines/trellis2_texturing.py`](https://github.com/microsoft/TRELLIS.2/blob/main/trellis2/pipelines/trellis2_texturing.py)), and data export utilities.

### Which component handles PBR attribute sampling during rendering?

The **`PbrMeshRenderer`** class in [`trellis2/renderers/pbr_mesh_renderer.py`](https://github.com/microsoft/TRELLIS.2/blob/main/trellis2/renderers/pbr_mesh_renderer.py) handles sampling. It uses `grid_sample_3d` to trilinearly interpolate voxel attributes and extracts individual channels for base color, metallic, roughness, and alpha, writing them to the output dictionary for the `nvdiffrast` shading pipeline.