Set env.timecode to startTimeCode (if authored) when converting Stage to
RenderScene. This ensures xformOps with TimeSamples are evaluated at the
initial pose for static viewers like materialx.js that don't support
animation playback.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add reset() and getMemoryStats() to TinyUSDZLoaderNative (binding.cc)
- reset() clears render scene, layers, assets, and all cached data
- getMemoryStats() returns memory usage statistics for debugging
- Update clearScene() in materialx.js to properly free memory on reload
- Dispose Three.js geometries, materials, and textures
- Call nativeLoader.reset() to free WASM memory
- Reset GUI state for normal display mode
- Add command line argument support to load-test-node.js
- Add new options to test-stream-load.js:
- --load-only: Load USD as Layer only (no scene conversion)
- --compare-modes: Compare load-only vs full load performance
- Fix --compare to clear memory between tests with reset() and GC
- Add memory usage reporting to all examples
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix implicit conversion warning in timesamples.hh (uint64_t to size_t)
- Fix WGSL shader error: sample all textures unconditionally to satisfy
uniform control flow requirement for textureSample
- Add IBL (Image-Based Lighting) shader with PBR support
- Add BRDF LUT generation using compute shader (rgba16float format)
- Add HDR environment map loading with robust parser
- Add fallback environment when HDR loading fails
- Fix environment map paths to use actual assets
- Add float-to-half conversion for HDR textures
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add --yaml and --json command-line options to tydra_to_renderscene
- Implement YAML format (human-readable, now default) with metadata header
- Implement JSON format (machine-readable) with metadata header
- Both formats include: format_version, generator, source_file, scene settings
(upAxis, metersPerUnit, framesPerSecond, etc.), and summary counts
- Add configuration info output as comments (YAML: #, JSON: //)
- Config info includes: loading_method, input_file, triangulate,
triangulation_method, build_vertex_indices, asset_resolver, timecode, etc.
- Keep original KDL format available via API with format="kdl"
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add _value_array_storage and _value_array_refs offset table for dedup
- Add add_value_array_sample() with move semantics (no copy)
- Update add_dedup_sample() to use offset table when _use_value_array
- Convert all array type handlers to use unified approach:
- int32[], uint32[], int64[], uint64[]
- half[], half2[], half3[], half4[]
- float[], float2[], float3[], float4[]
- double[], double2[], double3[], double4[]
- quatf[], quath[], quatd[]
- matrix2d[], matrix3d[], matrix4d[]
- bool[]
Benefits:
- Dedup samples only store time + reference index (no data copy)
- New samples use move semantics (no copy)
- Unified handling for all array types (removes POD-specific paths)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix set_timesamples move overloads in prim-types.hh to use std::move()
- Add std::move() at call sites in ascii-parser.cc and scene-access.cc
- Add _dedup_bool_array cache in crate-reader.hh for bool array dedup
- Add add_dedup_bool_array_sample_pod() method in timesamples.hh
- Update UnpackTimeSampleValue_BOOL to use dedup cache for bool arrays
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Performance optimizations for path traversal and prim lookup:
Stage (stage.cc):
- Replace recursive GetPrimAtPathRec with iterative GetPrimAtPathIterative
- Avoid string concatenation by using compare() with indices
- Direct path component parsing without intermediate allocations
Scene Access (scene-access.cc):
- Replace recursive TraverseRec with iterative TraverseIterative
- Use explicit stack with StackVector to avoid recursion overhead
- Reuse path buffer across traversal to minimize string allocations
- Reserve capacity for path buffer (256) and stack (64)
Additional optimizations:
- layer.cc: Improved path handling
- prim-types.cc: Optimized type operations
- usd-to-json.cc: Better JSON serialization
- usdGeom.cc, usdMtlx.cc: Enhanced prim reconstruction
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Memory optimizations to reduce allocation overhead and eliminate redundant copies:
USDC Reading:
- Add reusable decompression buffers (_decomp_comp_buffer, _decomp_working_buffer)
to CrateReader class to avoid repeated allocation across ReadCompressedInts,
ReadCompressedPaths, ReadFieldSets, and ReadSpecs calls
- Original implementations preserved with #if 0 for comparison
Move Semantics for Attribute Parsing:
- Add move overloads to Animatable::set() and set_default()
- Add move overloads to TypedAttribute::set_value() and operator=
- Add move overload to TypedAttributeWithFallback::set_value()
- Update ParseTypedAttribute call sites in prim-reconstruct.cc to use
std::move() for large array assignments (faceVertexIndices, points, normals)
Zero-Copy RoleTypeCast:
- Add unsafe_reinterpret_as<T>() to linb::any for vtable-only type changes
- Add get_raw_mutable() accessor to value::Value
- Rewrite ROLE_TYPE_CAST macro to swap vtable pointers instead of copying
- Add VALIDATE_ROLE_TYPE_CAST macro with static_asserts for all 22 role
type combinations (float2->texcoord2f, float3->normal3f/point3f/etc.)
- Add comprehensive unit tests for RoleTypeCast in unit-value-types.cc
Tydra Render Conversion:
- Add _tmp_points_buffer to RenderSceneConverter for BuildVertexIndicesFastImpl
- Add reserve() to TriangulatePolygon output vectors
- Add reserve() to ConvertMesh usdFaceVertexIndices and usdFaceVertexCounts
- Fix VertexAttribute copies to use const references and std::move()
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Performance optimizations:
DumpNode (src/tydra/render-scene-dump.cc):
- Refactor recursive DumpNode to reuse single stringstream
- Pass stringstream by reference to avoid allocation per node
- ~22% reduction in ostream operations
Property parsing (src/usdc-reader.cc):
- Add std::move() for AttrMeta assignments to avoid deep copies
- Add std::move() for Relationship and Property construction
- Add std::move() for PrimSpec storage in variant maps
- ~10% reduction in memory allocations
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Performance optimizations based on profiling:
TimeSamples (src/timesamples.cc):
- Add std::is_sorted() fast path for already-sorted data
- Implement adaptive insertion sort for nearly-sorted data (O(n) vs O(n log n))
- Pre-compute source offsets in sort_with_compact_values (O(n) vs O(n²))
- Use memcpy instead of std::copy for POD types
Vertex attribute conversion (src/tydra/render-data.cc):
- Pre-allocate buffers with exact size using resize()
- Use direct memcpy instead of vector::insert() loops
- Eliminate intermediate buffer allocations in TriangulateVertexAttribute
- Optimize VertexToFaceVarying with pre-allocated destination
Profiling results show elimination of sorting overhead (~6% of runtime)
and 63% reduction in triangulation/conversion function time.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Rewrite ReconstructPrimRecursively to use iterative stack-based traversal
to avoid stack overflow for deeply nested prim hierarchies
- Change ReconstructPrimNode output parameter from nonstd::optional<Prim>
to std::unique_ptr<Prim> for move-friendly semantics (no Prim copies)
- Use std::move when emplacing variantPrim to _variantPrims map
- Add switchable macro TINYUSDZ_USE_ITERATIVE_RECONSTRUCT_PRIM (default on)
- Rewrite StackVector in tiny-container.hh with proper small vector optimization
- Add comprehensive unit tests for StackVector
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implement high-performance USD viewer using native WebGPU:
- OpenPBR uber shader in WGSL with full material model support
- UBO/Storage buffer based material parameters (256 materials)
- Bindless texture arrays for efficient texture access
- Instance-based rendering with per-instance material index
- PBR lighting with GGX, Smith geometry, Fresnel-Schlick
- Multiple tone mapping options (ACES, Reinhard, AgX, Linear)
- Orbit camera controls with drag & drop USD file loading
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Reorder triangles by material in WASM binding to create contiguous
submesh groups (e.g., 3 groups instead of 383 for a 3-material mesh)
- Fix float-to-double promotion warnings in TransformPoint/TransformNormal
- Fix sign-conversion warnings in MergeMeshesImpl
- Add dump-geomsubset.js CLI tool for debugging geometry/material grouping
This significantly reduces draw calls in Three.js for meshes with
GeomSubsets by ensuring each material has exactly one contiguous
draw group instead of many fragmented ranges.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Performance optimizations for Tydra RenderScene converter:
1. Mesh Merging (merge_meshes option):
- Merge static meshes with the same material into single mesh
- Reduces draw calls in Three.js/WebGL/Vulkan renderers
- Configurable via RenderSceneConverterConfig::merge_meshes
- Optional transform baking (merge_meshes_bake_transform)
- Skips meshes with skeletal animation, blend shapes, or per-face materials
2. Texture Image Caching:
- Cache loaded texture images by asset path in imageMap
- Reuse existing images when same texture file is used by multiple materials
- Avoids redundant disk I/O and reduces memory usage
- Addresses TODO comment about sharing image data
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Improve rendering performance for meshes with per-face materials (GeomSubsets)
by pre-computing optimized submesh groups in C++ instead of JavaScript.
Changes:
- WASM: Pre-compute contiguous face ranges per material in binding.cc
Export minimal submesh data: {start, count, materialId}
- JS: Use pre-computed submeshes directly, eliminating expensive sorting/grouping
- Fix stack overflow with large arrays by removing spread operator usage
Performance: 100x-1000x faster for large meshes with multiple materials
Before: JS processing thousands of face indices (browser hang)
After: C++ pre-computation, JS just creates geometry groups
Tydra improvements:
- Change texture nullptr errors to warnings with debug info (Prim path)
- Change normals conversion errors to warnings, clear invalid normals
- Allow mesh conversion to continue with missing textures/normals
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
C++ (render-data.cc):
- Load envmap texture from DomeLight inputs:file asset
- Use DefaultTextureImageLoaderFunction for HDR/EXR loading
- Store loaded image in images array and set envmap_texture_id
- Support both decoded texture loading and raw asset storage modes
JavaScript (usdlux.js):
- Add createTextureFromImageData() to convert loaded image to Three.js texture
- Support both HDR (float32) and LDR (uint8) image formats
- Configure texture for equirectangular environment mapping
- Update loadLightsFromUSD() to load envmap texture for dome lights
- Update convertUSDLightToThreeJS() to apply envmap using PMREMGenerator
- Set scene.environment for PBR environment lighting
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add nodeKind field to buildNodeRec in binding.cc for WASM node output
- Add --show-nodes option to dump-usdlux-cli.js to display node hierarchy
- Add formatNodeRec and formatNodeHierarchy functions for node display
- Support node hierarchy in JSON and YAML output formats with --show-nodes
- Update help text with examples for node hierarchy dumping
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add NodeKind enum to categorize USD Prim types (Group, Geom, Light, Camera, Material, Skeleton)
- Add 'kind' member to Node struct for high-level categorization
- Add new NodeType values: RectLight, DiskLight, CylinderLight, GeometryLight
- Fix missing RegisterReconstructCallback for RectLight and GeometryLight in usda-reader.cc
- Update dump output to show both kind and type for each node
- Update threejs-exporter.cc to handle new NodeType values
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implements zero-copy streaming buffer mechanism to transfer USD data from
JS to WASM memory with minimal memory overhead. Key features:
- Pre-allocate WASM buffer upfront, write chunks directly via HEAPU8.set()
- Use UUID as buffer key, asset_name stored for cache lookup on finalize
- Support ReadableStreamBYOBReader when available for better performance
- Fallback to default reader when BYOB is unavailable
- AbortController support for cancellation
- Progress callback for transfer monitoring
New JS methods:
- streamFetchToWasm() - Stream fetch data directly to WASM
- streamFileToWasm() - Stream Node.js file to WASM (fs.createReadStream)
- streamFetchMultipleToWasm() - Parallel streaming with concurrency control
- loadWithStreaming() - High-level method combining streaming + parsing
C++ changes:
- ZeroCopyStreamingBuffer struct with UUID-based buffer management
- allocateZeroCopyBuffer/finalizeZeroCopyBuffer/cancelZeroCopyBuffer
- loadFromCachedAsset/loadAsLayerFromCachedAsset methods
- Export HEAPU8 for direct WASM heap access
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implement polling-based progress reporting for USD parsing in the web/WASM
environment. Since C++ cannot call async JS functions without Asyncify,
this uses a state-based approach where JS polls progress and can request
cancellation.
C++ changes (binding.cc):
- Add ParsingProgress struct with stage tracking and atomic cancellation
- Add getProgress(), cancelParsing(), wasCancelled(), isParsingInProgress()
- Add loadFromBinaryWithProgress() and loadAsLayerFromBinaryWithProgress()
- Wire up native progress_callback to update ParsingProgress state
- Export new methods via Emscripten bindings
JavaScript changes (TinyUSDZLoader.js):
- Add parseWithProgress() with AbortController support
- Add loadWithProgress() combining fetch and parse progress
- Add static getProgress() and cancelParsing() helpers
- Progress includes: stage, percentage, bytesProcessed, currentOperation
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Adds a new inspection feature similar to pxrUSD's sdfdump, providing
YAML-like tree output of USD Layer structure. New files:
- src/usd-dump.hh/cc: InspectLayer/InspectStage implementation
- GlobMatch/GlobMatchPath functions in str-util for pattern matching
New CLI options:
- --inspect: YAML-like Layer inspection output
- --inspect-json: JSON output (placeholder, not yet implemented)
- --value=MODE: Value printing mode (none/snip/full)
- --snip=N: Number of items to show in snip mode
- --path=PATTERN: Filter prims by path glob pattern (supports **)
- --attr=PATTERN: Filter attributes by name glob pattern
- --time=T or --time=S:E: TimeSamples time query
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add progress_callback and progress_userptr to USDLoadOptions
- Add SetProgressCallback to USDAReader to forward to AsciiParser
- Integrate progress callback in LoadUSDCFromMemory and LoadUSDAFromMemory
- Implement ASCII progress bar [=====> ] with percentage display
- Only show progress bar if loading takes > 3 seconds
- Reformat tusdcat help message to 80 character lines
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit adds a workaround for a Blender export bug where UsdUVTexture
shaders are created without the required `asset:file` attribute.
**Problem:**
When Blender exports USD materials, it sometimes creates UsdUVTexture nodes
that are missing the `asset:file` attribute, causing conversion to fail with:
"`asset:file` is not authored. Path = /root/_materials/..."
Example from mtlx-test.usdz:
```
def Shader "Image_Texture"
{
uniform token info:id = "UsdUVTexture"
texCoord2f inputs:st.connect = </root/_materials/.../UV_Map.outputs:result>
token inputs:wrapT = "repeat"
token inputs:wrapS = "repeat"
float3 outputs:rgb
# Missing: asset inputs:file = @texture.png@
}
```
**Solution:**
- Allow UsdUVTexture nodes without `asset:file` to be processed
- Create placeholder textures with empty asset paths
- Issue clear warning messages identifying this as likely Blender export bug
- Prevent crashes when accessing file.metas() by checking has_file first
**Changes:**
- Modified ConvertUVTexture() in render-data.cc (line 5810-5833)
- Added has_file check before accessing texture.file.metas()
- Changed error to warning with informative message
**Testing:**
- Tested with web/js/assets/mtlx-test.usdz
- Successfully converts 22 materials and 47 textures (including placeholders)
- Clear warnings issued for 4 missing texture files in T_ChasisPanels_3
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit addresses three issues with NodeGraph handling:
1. **NodeGraph Pretty Printing**: Added NodeGraph to the type system
to enable proper pretty printing instead of showing "VALUE_PPRINT:
TODO: (type: NodeGraph)" error. Added NodeGraph to CASE_GPRIM_LIST
macro in value-pprint.cc and implemented to_string() function in
pprinter.cc.
2. **Duplicate Attribute Printing**: Fixed connection-only attributes
being printed twice in NodeGraph and Shader prims. Added
is_connection_only check in print_prop() to skip printing attribute
declaration when it only has a connection and no value.
3. **NodeGraph Connection Traversal**: Fixed GetConnectedUVTexture() in
render-data.cc to properly traverse through NodeGraph prims instead
of treating their outputs as UsdUVTexture alpha channel (outputs:a).
Key improvements:
- Detect NodeGraph prims and extract their output connections
- Fall back to Material children lookup when Stage indexing fails
- Support matching prims by type when element names are empty
- Continue traversal to find actual UsdUVTexture nodes
This fixes the error: "connection Path's property part must be
outputs:rgb/r/g/b for UsdUVTexture, but got outputs:a (prim_part:
outputs:bnode_1_Separate_Color_Red_out)"
Tested with:
- test_nodegraph_float_output.usda (simplified test case)
- web/js/assets/mtlx-test.usdz (original error case)
Note: Full MaterialX shader chain traversal (through ND_extract_color3,
ND_convert_* nodes) is not yet implemented and will be addressed in
future work.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Rename "Sheen" to "Fuzz" throughout UI and texture maps for clearer terminology
- Add normal visualization mode using MeshNormalMaterial with smooth shading
- Add "Diffuse Roughness" parameter for OpenPBR base_diffuse_roughness (Oren-Nayar)
- Disable Iridescence parameter (commented out)
- Add UI toggle for normal display in Scene folder
Material parameter changes:
- Diffuse Roughness checks multiple data structure locations (flat, grouped, shader formats)
- Stores value in customParams for easier GUI binding
- Updates all possible data locations when modified
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit adds comprehensive camera control improvements, Z-up to Y-up axis
conversion with USD metadata reading, and proper sRGB/linear color space
handling for MaterialX compatibility.
Camera Control Improvements:
- Enable pan controls (screenSpacePanning = true)
- Configure mouse buttons: Left=Rotate, Middle=Pan, Right=Dolly(zoom)
- Add keyboard pan support with arrow keys (speed: 20.0)
- Extend zoom range: minDistance 0.1, maxDistance 500 (10x increase)
- Improve fitCameraToScene() with proper bounding sphere calculation
- Calculate FOV-aware camera distance for both horizontal/vertical fit
- Position camera at 45-degree viewing angle for better composition
- Dynamically adjust near/far clipping planes based on scene size
- Add 20% padding for comfortable scene framing
UpAxis Conversion:
- Read upAxis metadata from USD Stage/Layer via getSceneMetadata()
- Store scene metadata (upAxis, metersPerUnit, timeCodesPerSecond)
- Apply automatic Z-up to Y-up conversion (-90° X-axis rotation)
- Add UI toggle "Z-up to Y-up Fix" in Scene settings
- Reset upAxis state when clearing scene
- Log detected upAxis and conversion status to console
Color Space Handling:
- Add sRGBToLinear() and linearToSRGB() conversion functions
- MaterialX assumes linear Rec.709 as working colorspace
- Color pickers display in sRGB for user-friendly editing
- Convert picker values to/from linear for material storage
- Update Base Color picker with proper conversion
- Update Emissive Color picker with proper conversion
- Label pickers as "(sRGB)" to indicate display color space
Default Scene:
- Load fancy-teapot-mtlx.usdz at initialization
- Fallback to embedded golden sphere if teapot file missing
- Update status messages to show upAxis in load status
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add RGBELoader for HDR environment map loading
- Add PMREM generator and PBR renderer initialization
- Add environment map presets (goegap_1k, env_sunsky_sunset, studio)
- Add materialSettings for material type and environment control
- Add functions: initializePBRRenderer, loadEnvironment, createStudioEnvironment,
applyEnvironment, updateEnvBackground, updateEnvIntensity, updateToneMapping,
reloadMaterials
- Update loadUSDModel and loadUSDFromArrayBuffer to use MeshPhysicalMaterial
with environment map and preferredMaterialType option
- Add Material & Environment GUI folder with controls for:
- Material type (auto/openpbr/usdpreviewsurface)
- Environment preset selection
- Environment intensity, exposure, tone mapping
- Show environment as background toggle
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Rename materialx.js/html to mtlx-debug.js/html for advanced debug features
- Create new simple materialx.js/html with clean Three.js + TinyUSDZ demo
- New demo features: drag-and-drop USD loading, material parameter UI,
texture preview, material type switching (OpenPBR/UsdPreviewSurface),
HDR environment presets, tone mapping controls
- Update README.md with demo pages documentation
- Update MATERIALX-DEMO-README.md with both demo URLs
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Document the MaterialX/OpenPBR material conversion APIs:
- getMaterialType() for checking available material types
- getMaterialTypeString() for human-readable type names
- convertMaterial() smart converter with preference options
- convertOpenPBRMaterialToMeshPhysicalMaterial() for OpenPBR
- convertUsdMaterialToMeshPhysicalMaterial() for UsdPreviewSurface
- TinyUSDZOpenPBR class for manual material creation
Include OpenPBR to Three.js parameter mapping table covering
base, specular, transmission, coat, sheen/fuzz, thin film,
emission, and geometry layers.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
TinyUSDZMaterialX.js:
- Complete rewrite with comprehensive OpenPBR to MeshPhysicalMaterial conversion
- Add OPENPBR_TO_THREEJS_MAP for parameter mapping
- Add OPENPBR_TEXTURE_MAP for texture map name mapping
- Add loadTextureFromUSD() with caching support
- Support all OpenPBR layers: base, specular, transmission, coat,
sheen, fuzz, thin_film, emission, geometry
- Handle both flat and grouped JSON formats from material serialization
TinyUSDZLoaderUtils.js:
- Add getMaterialType() to detect available material types
(OpenPBR, UsdPreviewSurface, Both, or None)
- Add getMaterialTypeString() for human-readable type names
- Add convertOpenPBRMaterialToMeshPhysicalMaterial() for OpenPBR conversion
- Add convertMaterial() smart converter that auto-selects material type
- Prefer OpenPBR when both material types are available (auto mode)
- Support preferredMaterialType option: 'auto', 'openpbr', 'usdpreviewsurface'
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Support parsing and serialization of additional MaterialX OpenPBR parameters:
- fuzz_weight, fuzz_color, fuzz_roughness (velvet/fabric-like appearance)
- thin_film_weight, thin_film_thickness, thin_film_ior (iridescence)
- base_diffuse_roughness (Oren-Nayar diffuse roughness)
- geometry_opacity (maps to alpha in Three.js, reuses opacity field)
Changes include:
- OpenPBRSurface struct in usdShade.hh
- OpenPBRSurfaceShader class in render-data.hh
- Tydra conversion in render-data.cc (both OpenPBR and MtlxOpenPBR paths)
- JSON/XML serialization in material-serializer.cc
- USD parser support in prim-reconstruct.cc for both OpenPBRSurface and
MtlxOpenPBRSurface (Blender v4.5+ MaterialX export)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add numLights(), getLight(), getAllLights() functions
- Export all RenderLight properties: type, color, intensity, transform, etc.
- Include LTE SpectralAPI spectral emission data when available
- Support all light types: point, sphere, disk, rect, cylinder, distant, dome
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add spectralEmission attribute to BoundableLight and NonboundableLight
- Expand RenderLight struct with full light properties and spd_emission
- Support illuminantPreset, interpolation, and wavelength unit metadata
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>