9.6 KiB
Three.js MaterialX Support and TinyUSDZ/Tydra Integration
Executive Summary
This document describes the current state of MaterialX support in Three.js and the requirements for Tydra to bridge USD MaterialX settings to Three.js rendering. Three.js has experimental MaterialX support through WebGPU renderer with a MaterialXLoader, while TinyUSDZ/Tydra provides comprehensive MaterialX material conversion capabilities.
Three.js MaterialX Support (2024-2025)
Current Implementation Status
WebGPU MaterialX Loader
- File:
examples/webgpu_loader_materialx.html - Status: Experimental/Example stage
- Renderer: WebGPU only (not WebGL/WebGL2)
- Features:
- Loads
.mtlxfiles directly - Supports material preview on shader ball models
- Dynamic material switching with GUI controls
- Loads
Supported MaterialX Features
-
Standard Surface Materials
- Brass, chrome, gold, and other metallic surfaces
- Procedural textures and patterns
- Material transformations
- Opacity and transmission effects
- Thin film rendering
- Sheen and roughness properties
-
Node Support (PR #31439 improvements)
- Mathematical nodes:
ln,transform,matrix,transpose,determinant,invert - Geometric nodes:
length,crossproduct,reflect,refract - Conditional nodes:
ifgreater,ifequal - Noise nodes:
uniformnoise2d,uniformnoise3d - Procedural nodes:
ramp4,place2d - Color transformations
- Screen-space derivative calculations
- Smoothstep and mixing operations
- Mathematical nodes:
-
Material Properties
- Standard Surface: Full support for opacity, specular intensity/color
- Advanced Properties: IOR, anisotropy, sheen, thin film
- Transmission: Color and thickness support
- Rendering Modes: Automatic transparency and double-sided rendering
Technical Implementation
Three.js Node Material System
- Uses TSL (Three Shading Language) for node-based material authoring
- Transpiles to GLSL or WGSL depending on renderer
- Goal: Compose any MaterialX node from <5 Three.js nodes
- Aligns with Blender's MaterialX exporter for compatibility
Limitations
- WebGPU-only support (experimental API, limited browser support)
- No WebGL/WebGL2 fallback currently
- Complex nodes like convolution ("blur", "heighttonormal") are challenging
- MaterialX WASM library integration still exploratory
TinyUSDZ MaterialX Implementation
Current Architecture
Core Components
-
MaterialXConfigAPI (
src/usdShade.hh)struct MaterialXConfigAPI { TypedAttributeWithFallback<std::string> mtlx_version{"1.38"}; TypedAttributeWithFallback<std::string> mtlx_namespace{""}; TypedAttributeWithFallback<std::string> mtlx_colorspace{""}; TypedAttributeWithFallback<std::string> mtlx_sourceUri{""}; }; -
Supported Shader Models
MtlxUsdPreviewSurface: MaterialX-extended UsdPreviewSurfaceMtlxAutodeskStandardSurface: Autodesk Standard Surface (v1.0.1)OpenPBRSurface: Academy Software Foundation OpenPBR model
-
File Format Support
- Direct
.mtlxfile loading - USD references to MaterialX files:
@myshader.mtlx@ - Embedded MaterialX in USD files
- Direct
Tydra Conversion Pipeline
Current Capabilities
-
Material Conversion Flow
USD Stage → Material with MaterialXConfigAPI → Tydra RenderMaterial -
Dual Material Support
class RenderMaterial { nonstd::optional<PreviewSurfaceShader> surfaceShader; // UsdPreviewSurface nonstd::optional<OpenPBRSurfaceShader> openPBRShader; // MaterialX OpenPBR }; -
OpenPBRSurfaceShader (
src/tydra/render-data.hh)- Base layer: weight, color, roughness, metalness
- Specular layer: weight, color, roughness, IOR, anisotropy
- Subsurface scattering parameters
- Coat layer properties
- Thin film effects
- Emission properties
- Geometry modifiers (normal, tangent, displacement)
Requirements for Tydra to Three.js Bridge
1. Material Export Module
Purpose: Convert Tydra's RenderMaterial to Three.js-compatible format
Requirements:
class ThreeJSMaterialExporter {
public:
// Export to Three.js MaterialX format
std::string ExportToMaterialX(const RenderMaterial& material);
// Export to Three.js JSON format with node graph
json ExportToNodeMaterial(const RenderMaterial& material);
// Map Tydra shader params to Three.js nodes
json ConvertShaderParams(const OpenPBRSurfaceShader& shader);
};
2. Node Graph Translation
Mapping Requirements:
| TinyUSDZ/Tydra | Three.js Node | Notes |
|---|---|---|
| OpenPBRSurface.base_color | standard_surface.base_color | Direct mapping |
| OpenPBRSurface.base_metalness | standard_surface.metalness | Direct mapping |
| OpenPBRSurface.specular_weight | standard_surface.specular | May need scaling |
| OpenPBRSurface.coat_weight | standard_surface.coat | Direct mapping |
| UsdUVTexture | texture2d + place2d | Combine nodes |
| Transform2d | place2d | UV transformations |
3. Texture Handling
Requirements:
- Convert Tydra's texture references to Three.js texture loader format
- Handle UV transformations (scale, rotate, offset)
- Support for MaterialX colorspace tags
- Texture channel packing (e.g., ORM textures)
4. WebGPU vs WebGL Compatibility
Dual Output Strategy:
- WebGPU Path: Direct MaterialX node graph export
- WebGL Fallback: Convert to standard Three.js materials
// WebGL fallback const material = new THREE.MeshPhysicalMaterial({ color: materialData.base_color, metalness: materialData.base_metalness, roughness: materialData.base_roughness, // ... mapped properties });
5. Implementation Phases
Phase 1: Basic Material Export
- Export OpenPBRSurface to Three.js MeshPhysicalMaterial
- Basic property mapping (color, metalness, roughness)
- Texture reference export
Phase 2: Advanced Features
- Full OpenPBR parameter support
- UV transformation handling
- Multi-layer material support (base + coat + sheen)
Phase 3: Node Graph Export
- Generate Three.js TSL node graphs
- Support procedural textures
- Custom node implementations
Phase 4: Optimization
- Texture atlas generation
- Material deduplication
- LOD material variants
API Design Proposal
Tydra Extension API
namespace tinyusdz {
namespace tydra {
class ThreeJSExporter {
public:
struct ExportOptions {
bool use_webgpu = true; // Target WebGPU renderer
bool generate_fallback = true; // Generate WebGL fallback
bool embed_textures = false; // Embed texture data in JSON
std::string texture_path = ""; // External texture directory
};
// Export entire RenderScene
bool ExportScene(const RenderScene& scene,
const ExportOptions& options,
std::string& json_output);
// Export single material
bool ExportMaterial(const RenderMaterial& material,
const ExportOptions& options,
std::string& json_output);
// Generate MaterialX document
bool ExportMaterialX(const RenderMaterial& material,
std::string& mtlx_output);
};
} // namespace tydra
} // namespace tinyusdz
Three.js Import API
// Three.js side import
import { TinyUSDZMaterialLoader } from 'three/addons/loaders/TinyUSDZMaterialLoader.js';
const loader = new TinyUSDZMaterialLoader();
// Load exported material
loader.load('exported_material.json', (material) => {
mesh.material = material;
});
// Or direct MaterialX
const mtlxLoader = new MaterialXLoader();
mtlxLoader.load('exported.mtlx', (material) => {
mesh.material = material;
});
Testing Strategy
Test Materials
- Basic PBR: Simple metallic/dielectric materials
- Layered: Materials with coat, sheen, subsurface
- Textured: Materials with multiple texture maps
- Procedural: Materials with noise and patterns
- Transmission: Glass and translucent materials
Validation Process
- Export material from USD/MaterialX via Tydra
- Import in Three.js WebGPU renderer
- Visual comparison with reference renders
- Performance profiling
Performance Considerations
Optimization Opportunities
- Material Batching: Combine similar materials
- Texture Atlasing: Pack multiple textures
- Shader Caching: Reuse compiled shaders
- LOD System: Simplified materials for distant objects
Memory Management
- Texture Compression: Use GPU-friendly formats
- On-demand Loading: Lazy load textures
- Resource Pooling: Share common resources
Conclusion
The integration of TinyUSDZ/Tydra MaterialX support with Three.js is feasible and valuable. The proposed implementation would:
- Enable full MaterialX material export from USD to Three.js
- Support both WebGPU (native) and WebGL (fallback) rendering
- Provide a production-ready pipeline for USD to web visualization
- Maintain compatibility with industry-standard tools
The phased approach allows incremental development while delivering value at each stage. The dual-path strategy (WebGPU/WebGL) ensures broad compatibility while leveraging modern capabilities where available.