How to Handle Alpha Channel Transparency in GLB Exports with TRELLIS.2

To enable alpha channel transparency in TRELLIS.2 GLB exports, detect non-opaque pixels in the texture baking process and set the alphaMode parameter to 'BLEND' instead of the hard-coded 'OPAQUE' in o-voxel/o_voxel/postprocess.py, ensuring 3D software renders semi-transparent materials correctly.

TRELLIS.2 generates textured 3D assets by baking learned attribute volumes into GLB files using the to_glb function. While the pipeline extracts alpha channel data during texture creation, the exported GLB defaults to opaque rendering, causing transparency to be ignored in external viewers. This guide shows you how to modify the source code to detect transparent pixels and configure the PBR material according to the GLTF 2.0 specification.

Understanding the Alpha Channel Issue in TRELLIS.2

The transparency problem originates in the material configuration within o-voxel/o_voxel/postprocess.py. During texture baking, the function correctly extracts the alpha channel from the learned attribute volume:

alpha = np.clip(attrs[..., attr_layout['alpha']].cpu().numpy() * 255,
                0, 255).astype(np.uint8)

However, when constructing the PBRMaterial via trimesh, the alphaMode is hard-coded:

material = trimesh.visual.material.PBRMaterial(
    baseColorTexture=Image.fromarray(np.concatenate([base_color, alpha], axis=-1)),
    alphaMode='OPAQUE',  # ← ignores the alpha data

    doubleSided=True if not remesh else False,
)

Because GLTF 2.0 specifies that OPAQUE mode discards alpha values, viewers render the mesh as fully solid even when the base-color texture contains valid transparency data in its alpha channel.

Locating the GLB Export Logic

The core conversion logic resides in o-voxel/o_voxel/postprocess.py inside the to_glb function. This module handles the conversion from internal voxel representations to export-ready GLB assets by baking attribute volumes into textures.

The function constructs a dictionary of material attributes and instantiates trimesh.visual.material.PBRMaterial with texture arrays for base color, metallic, and roughness. The alpha channel exists in the texture data but requires the correct alphaMode flag to activate transparency rendering in compliant viewers like Blender, Three.js, and Unity.

Implementing Alpha Transparency Support

To fix transparency handling, you must dynamically detect semi-transparent pixels and adjust both the alphaMode and doubleSided flags.

Detecting Non-Opaque Pixels

After extracting the alpha channel array, check if any pixel value is less than fully opaque (255):

has_transparency = (alpha < 255).any()
alpha_mode = 'BLEND' if has_transparency else 'OPAQUE'

This boolean flag determines whether the exported material should use alpha blending or remain opaque.

Configuring PBRMaterial with BLEND Mode

Update the material instantiation to use the dynamic alpha_mode variable and adjust the doubleSided flag to prevent back-face culling when transparency is active:

material = trimesh.visual.material.PBRMaterial(
    baseColorTexture=Image.fromarray(np.concatenate([base_color, alpha], axis=-1)),
    baseColorFactor=np.array([255, 255, 255, 255], dtype=np.uint8),
    metallicRoughnessTexture=Image.fromarray(
        np.concatenate([np.zeros_like(metallic), roughness, metallic], axis=-1)
    ),
    metallicFactor=1.0,
    roughnessFactor=1.0,
    alphaMode=alpha_mode,
    doubleSided=has_transparency or (not remesh),
)

Alternative: MASK Mode for Cut-Out Transparency

If your asset requires binary transparency (e.g., for leaves or grates) rather than gradual blending, use MASK mode with an alphaCutoff threshold:

alpha_mode = 'MASK'
material = trimesh.visual.material.PBRMaterial(
    ...
    alphaMode=alpha_mode,
    alphaCutoff=0.5,  # Pixels below 50% opacity are discarded

)

Enabling Transparency in Downstream 3D Software

Once the GLB contains the correct alphaMode property, modern 3D engines automatically respect the alpha channel without additional texture manipulation.

Blender

Import the GLB via File → Import → glTF 2.0. In the Material Properties panel, verify that Blend Mode is set to Alpha Blend. When alphaMode="BLEND" is present in the file, Blender automatically configures the EEVEE or Cycles material for transparency.

Three.js

When loading via GLTFLoader, the renderer automatically sets material.transparent = true based on the GLTF alphaMode flag:

const loader = new THREE.GLTFLoader();
loader.load('transparent_output.glb', (gltf) => {
  const model = gltf.scene;
  // Material.transparent is already true if alphaMode was BLEND
  scene.add(model);
});

Unity

The GLB importer creates a Standard shader material. If the alphaMode is not automatically detected, manually set the Rendering Mode to Transparent in the material inspector to enable alpha blending.

Complete Patching Example

Below is a minimal diff showing the required changes to o-voxel/o_voxel/postprocess.py:

--- a/o-voxel/o_voxel/postprocess.py
+++ b/o-voxel/o_voxel/postprocess.py
@@
-    alpha_mode = 'OPAQUE'
+    # Detect if the alpha channel contains any non-opaque pixel

+    has_transparency = (alpha < 255).any()
+    alpha_mode = 'BLEND' if has_transparency else 'OPAQUE'
@@
-        doubleSided=True if not remesh else False,
+        doubleSided=has_transparency or (not remesh),

After applying this patch, the to_glb function automatically exports GLB files with functional transparency whenever the alpha channel contains varied values.

Summary

  • TRELLIS.2 extracts alpha data but exports GLB files with alphaMode='OPAQUE', preventing transparency.
  • Modify o-voxel/o_voxel/postprocess.py to detect transparent pixels using (alpha < 255).any().
  • Set alphaMode='BLEND' for semi-transparent materials or 'MASK' for binary cut-outs.
  • Enable double-sided rendering when transparency is active to prevent missing back-faces.
  • Modern 3D software (Blender, Three.js, Unity) automatically respects the GLTF alphaMode property once correctly exported.

Frequently Asked Questions

Why does my exported GLB appear opaque in some viewers but transparent in others?

TRELLIS.2 currently hard-codes alphaMode to 'OPAQUE', which means strictly compliant viewers ignore the alpha channel entirely. Some viewers (particularly older versions or custom implementations) may incorrectly assume transparency from the presence of an RGBA texture, while standards-compliant engines like Three.js and Blender follow the GLTF specification and require alphaMode='BLEND' or 'MASK' to enable transparency rendering.

Can I use MASK mode instead of BLEND for better performance?

Yes. For materials requiring binary transparency (hard edges with no semi-transparency), set alphaMode='MASK' and provide an alphaCutoff value between 0 and 1. This enables alpha testing rather than alpha blending, which reduces overdraw and improves rendering performance in real-time engines like Unity or WebGL applications, though it produces jagged edges without anti-aliasing.

Does enabling alpha transparency affect the GLB file size?

No. The alpha channel is already baked into the base-color texture as an RGBA image regardless of the alphaMode setting. Changing the mode only modifies a single string property in the GLTF JSON header and potentially the boolean doubleSided flag, resulting in negligible file size differences (typically less than 10 bytes).

Where does TRELLIS.2 store the alpha data before GLB export?

The alpha values originate from the learned attribute volume passed to to_glb. The function extracts them via attrs[..., attr_layout['alpha']] in o-voxel/o_voxel/postprocess.py, scales them to the 0-255 range, and concatenates them into the final texture array alongside the RGB color channels.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →