Skip to content

animu-sphere/hydra-merlin

Repository files navigation

hdMerlin

Core CI

hdMerlin is an OST-oriented, host-neutral Vulkan raster renderer. The current implementation provides a handle-based RenderWorld, deterministic extraction into an immutable resource-granular FrameSnapshot, a backend-neutral render contract, and a persistent Vulkan renderer with offscreen and GLFW-hosted swapchain presentation. Submission/completion lifetime and selectable color/depth/primId/instanceId CPU readback remain explicit. Its host-neutral MaterialIR supports revisioned texture/sampler bindings and basic directional-lit, textured, vertex-colored, opaque or alpha-masked shading.

The core library intentionally has no OpenUSD, Hydra, DCC, Qt, Vulkan, or Metal types in its public API. Hydra and host integrations remain thin adapters around that core.

OpenStrata project

The repository is an OpenStrata renderer project targeting cy2026. OST 0.19.0 or newer is required for atomic build evidence and the managed Hydra view loop. The default host-neutral lifecycle is:

ost runtime pull cy2026 --profile core
ost build --check
ost build --jobs auto
ost validate --json

The existing CMake targets remain project-owned renderer units; adopting OST does not split them into artificial packages or plugin bundles. Vulkan builds emit the renderer evidence consumed by ost validate. For Hydra inspection, materialize or adopt one real usd/lookdev OpenUSD runtime, then run ost renderer view --profile usd. With no --build-dir, OST requests the hydra2 build intent, incrementally configures/builds a fingerprinted tree, stages the install, discovers hdMerlin, and launches usdview. --build-dir is reserved for an already configured and built external CMake tree; OST installs and inspects that tree but does not rebuild it or claim managed-build evidence.

To build the Hydra-enabled standalone viewport and open a USD stage:

ost renderer viewport --intent viewport-usd --profile usd -- `
  --usd C:/path/to/scene.usd --frames 1 --hidden

The viewport-usd intent is declared in openstrata.toml; use a real usd runtime when the scene needs OpenUSD and its dependencies.

See the OpenStrata project layout for the composition mapping and adoption decisions.

Build

cmake -S . -B build -G "Visual Studio 17 2022" -A x64
cmake --build build --config Debug
ctest --test-dir build -C Debug --output-on-failure

Render the headless smoke image:

./build/adapters/merlin-headless/Debug/merlin-headless.exe --frames 6 --output merlin.ppm

Run the native Vulkan viewport. Hydra USD navigation follows usdview: Alt+left tumbles, Alt+middle tracks, Alt+right and the wheel dolly, and F frames the stage. Arrow keys pan, an unmodified left click reads picking IDs, and S writes a screenshot.

./build/adapters/merlin-viewport/Debug/merlin-viewport.exe --vsync off

Retain unchanged-frame expected/actual/diff evidence as PNG and OpenEXR:

./build/adapters/merlin-headless/Debug/merlin-headless.exe `
  --frames 6 --artifact-dir artifacts --output merlin.ppm

Capture the reference-path performance baselines as deterministic JSON:

./build/adapters/merlin-benchmark/Debug/merlin-benchmark.exe `
  --fixture reference --width 512 --height 512 --steady-frames 30 `
  --output benchmark.json

The v3 report records build/machine metadata, CPU/GPU stage distributions, hitches, AOV selection, transfer/allocation/descriptor work, and structural counters for first-frame, steady-state, camera, per-aspect edits, and AOV combinations. Fixed million-triangle, 10,000-mesh, 1,000-instance, and 4K fixtures are selectable explicitly. See the benchmark guide for the schema and comparison rules.

The renderer keeps three frame contexts by default and returns tightly packed top-left products under renderer-specific completion tokens. RenderRequest selects produced AOVs and CPU readback; Submit records and queues work without waiting, and timeout-aware Resolve transfers only the selected products. GPU geometry residency is resource-granular: per-mesh vertex/index ranges are suballocated from device-local arenas, staged through a persistently mapped upload ring, keyed by handle generation and revision, shared across instances, and retired deterministically after the last referencing frame completes. Static scenes perform zero upload, allocation, and pipeline work after warm-up, and transform-, visibility-, and material-only edits stage zero geometry bytes. Revisioned textures and samplers are cached independently, while material parameter edits reuse the existing shader/pipeline variant. On descriptor- indexing-capable devices, finite global sampled-image and deduplicated-sampler tables preserve unchanged slot identity, materialize the four reserved fallback images, update only dirty descriptor elements, and delay slot reuse and Vulkan object destruction until the last referencing completion. Conventional Forward remains the correctness fallback; negotiated devices automatically use the non-uniform-indexed bindless shader path with persistent per-frame material descriptors, so warmed static frames perform zero descriptor allocation or update.

Hydra 2 adapter

The OpenUSD adapter is opt-in so Hydra never becomes a transitive dependency of the normal Core/Vulkan build. Point CMAKE_PREFIX_PATH at an OpenUSD 26.05 SDK:

cmake -S . -B build-hydra2 -G "Visual Studio 17 2022" -A x64 `
  -DMERLIN_ENABLE_HYDRA2=ON `
  -DCMAKE_PREFIX_PATH=C:/path/to/openusd
cmake --build build-hydra2 --config Release
ctest --test-dir build-hydra2 -C Release --output-on-failure

The Hydra slice provides mesh topology/transform/visibility and camera sync, an adapter-owned USD path to Merlin handle map, color/depth CPU render buffers, and a Vulkan-backed render pass. The test suite separately verifies plugin discovery and delegate creation, RenderBuffer resize/map lifetime, and an install-tree testusdview first frame with rendered geometry.

The install-tree regression also emits a versioned Hydra performance report and raw OpenUSD Chrome trace. Together they separate delegate Sync, scene-index processing, RenderWorld/extraction, Vulkan CPU/GPU work, selected readback, RenderBuffer map/resolve, CPU-to-Hgi upload, host composite, and presentation; camera-only motion is gated against geometry/topology/primvar fetch or upload.

The current mesh path normalizes indexed and face-varying normals, display color/opacity, and UVs, robustly triangulates concave polygonal faces, preserves authored material binding identity, and supports native Hydra instancing. The adapter translates a basic UsdPreviewSurface subset (constant parameters, diffuse image texture, wrap mode, opacity mask) and distant lights into the same MaterialIR used by headless rendering. The optional graph-only MaterialXGenSlang compiler foundation is present, but Hydra MaterialX ingestion and Vulkan Forward execution of generated material modules remain v0.10.0 work. Subdivision refinement and zero-copy Vulkan/Hgi interop also remain future work; usdview presentation currently uses Hydra's CPU RenderBuffer-to-Hgi upload path.

Capability boundaries and roadmap

The current renderer intentionally does not yet provide:

  • Hydra MaterialX loading, Vulkan execution of generated MaterialX modules, or general graph coverage beyond the optional v0.10.0 compiler prototype and the existing UsdPreviewSurface subset;
  • the complete GPU Scene tables, GPU-driven indexed submission, an opaque Visibility Buffer path, meshlet rendering, or a Mesh Shader backend;
  • advanced viewport features such as alpha blending, dome lighting, shadows, selection, or production culling;
  • Vulkan/Hgi external-memory or other zero-copy GPU presentation; Hydra uses CPU RenderBuffer readback followed by the host's Hgi upload path.

These are roadmap boundaries, not implicit compatibility claims. See the support matrix for current platform and feature coverage.

v0.5.0 released the host-neutral MaterialIR and basic textured shading slice. v0.6.0 released the measurement foundation and incremental Hydra sync work, making changed-scene costs and host presentation separately observable. v0.7.0 released the persistent Mesh/future-Gaussian resource foundation, and v0.8.0 moved the Forward shader source of truth to Slang with reflected artifacts and a Metal compile gate. The completed v0.9.0 work adds the minimum backend-neutral render contract and dedicated cross-backend merlin-viewport with validated Vulkan swapchain presentation and Hydra USD loading. The active v0.10.0 milestone proves a MaterialXGenSlang material-function slice before native Metal and an HgiMetal host presentation bridge. The later path advances through Gaussian rendering, persistent draw identity, GPU-driven Mesh/Gaussian execution, experimental opaque Visibility, production MaterialX quality, static meshlets, and only then optional Mesh Shader/Hi-Z/LOD. Forward and Tier 0 CPU readback remain reference fallbacks. See the current milestone, ordered backlog, multi-backend shader and presentation strategy, and GPU-driven rendering policy for scope, dependencies, and exit criteria.

Gaussian support will consume the standard Gaussian representation exposed by OpenUSD through Hydra. hdMerlin will not define a renderer-specific USD schema or directly parse PLY/SPLAT files; conversion from external formats belongs to separate FileFormat plugins or importers. Mesh and Gaussian resources share the persistent RenderWorld, camera, transforms, visibility, allocation, lifetime, and profiling infrastructure while retaining separate rendering algorithms.

The Vulkan path requires a Vulkan 1.4-capable graphics queue and Slang 2026.8.x (slangc) from the Vulkan SDK at build time.

MaterialX prototype

The v0.10.0 work adds an optional compiler boundary that turns a deliberate MaterialX graph subset into a renderer-consumable Slang material function. It uses the official MaterialXGenSlang implementation pinned at 38368ee04da84ce1f8837ecba7322dd6d81291f8. A compatible prebuilt MaterialX 1.39.6 package is preferred; development builds can use an existing source tree or explicitly fetch the pin:

cmake -S . -B build-materialx -G "Visual Studio 17 2022" -A x64 `
  -DMERLIN_ENABLE_VULKAN=OFF `
  -DMERLIN_ENABLE_MATERIALX=ON `
  -DMERLIN_FETCH_MATERIALX=ON
cmake --build build-materialx --config Debug
ctest --test-dir build-materialx -C Debug -R merlin-materialx `
  --output-on-failure

Source fallback builds require CMake 3.26 or newer. The generated module owns only graph evaluation; geometry, lighting, alpha policy, render passes, resources, and AOV writes remain renderer-owned.

The current foundation deterministically generates renderer-owned material results for constants, image/UV0/world-normal, add/multiply/mix, and the minimum Standard Surface base, base_color, metalness, specular_roughness, and normal slice. Logical reflection, portable standard-library/include fingerprints, and a topology-only module key stay separate from typed parameter and resource state. Core carries the versioned logical module/layout contract and exact input-space requirements; the same generated sources compile for SPIR-V and Metal targets. v0.10.0 completion still requires the reusable target artifact identity, structured common fallback, Vulkan Forward execution, and image evidence. See the authoritative MaterialXGenSlang material boundary and current milestone.

Supported configurations

The host-neutral libraries require CMake 3.24 and a C++20 compiler. Vulkan and Hydra are optional dependency layers:

Configuration CMake options Required dependencies
Core-only MERLIN_ENABLE_VULKAN=OFF C++20 compiler
Headless Vulkan MERLIN_ENABLE_VULKAN=ON Vulkan 1.4 loader/headers/device and Slang 2026.8.x
Vulkan viewport MERLIN_BUILD_VIEWPORT=ON Vulkan requirements; GLFW 3.4 or the pinned fetched fallback
Hydra 2 MERLIN_ENABLE_HYDRA2=ON Vulkan requirements and a compatible OpenUSD SDK
MaterialX compiler MERLIN_ENABLE_MATERIALX=ON MaterialX 1.39.6 with MaterialXGenSlang; CMake 3.26+ for source fallback

Windows with Visual Studio 2022 is the currently validated development path. Core-only Debug and Release builds run on hosted Windows and Linux CI. GPU and Hydra tests remain capability jobs: missing validation/device capabilities are reported as skips where the test contract allows it, and OpenUSD build configuration and C++ runtime ABI must match the consumer.

The manually dispatched Vulkan and Hydra capability CI workflow has separate headless and Hydra jobs. Both require only a self-hosted Windows x64 runner with the vulkan-1.4 GPU/driver label. They download and checksum-verify LunarG Vulkan SDK 1.4.350.0 into a cached workspace prefix. Hydra also obtains the Animusphere OpenUSD 26.05/cy2026 runtime from its digest-pinned public GHCR package using pinned ost 0.19.0. No operator-managed SDK installation is required. The jobs run the 64-frame validation loop and install-tree usdview stable-update regression, retaining dependency/runtime provenance, images, regression logs, and CTest logs as evidence artifacts.

Install and consume

Install a configured build into a staging prefix:

cmake --install build --config Release --prefix C:/merlin

This installs the public headers, libraries, versioned CMake package files, and, when enabled, merlin-headless, merlin-benchmark, and merlin-viewport with their versioned SPIR-V, Metal compile-gate, reflection, and manifest artifacts. A downstream CMake project can consume the package without referring to the Merlin source tree:

find_package(Merlin 0.1 REQUIRED COMPONENTS RenderBackend)
target_link_libraries(my-renderer PRIVATE Merlin::RenderBackend)

Available package components and targets are RenderWorld (Merlin::RenderWorld), RenderExtraction (Merlin::RenderExtraction), RenderBackend (Merlin::RenderBackend), and, for Vulkan-enabled builds, Vulkan (Merlin::Vulkan). MaterialX-enabled builds also export MaterialX (Merlin::MaterialX). The install-consumer CTest installs to an isolated prefix and verifies downstream configure, build, link, and execution.

Architecture boundary

Dependencies flow from adapters into the host-neutral scene model, deterministic draw extraction, backend-neutral execution contract, and concrete backend. Public Core APIs do not expose OpenUSD, Hydra, Vulkan, GLFW, Qt, or DCC types. Hydra owns host path/dirty-bit translation; the GLFW adapter owns the window; and Vulkan owns execution, readback, surface, swapchain, and synchronization.

Project documentation

License

hdMerlin is licensed under the Apache License 2.0.

About

A lightweight Vulkan raster renderer for USD Hydra.

Topics

Resources

Contributing

Security policy

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages