Key Differences Between FSD and OmniHydra#

This page explains the key differences between the two mutually exclusive Hydra scene delegates available in Omniverse: OmniHydra (the legacy scene delegate) and the Fabric Scene Delegate (FSD).

Both scene delegates are fully feature-complete implementations that support all USD constructs including point instancers, scene graph instancing (including nested instancing). They both support the full range of standard rendering features:

  • Geometry: Meshes, curves, geometric primitives (cubes, spheres, cylinders, capsules, cones), volumes, and point clouds

  • Materials and Shading: Material bindings, shader networks, MDL materials, texture coordinates

  • Primvars: Vertex colors, normals, UVs, and custom primvars with various interpolation modes

  • Lighting: All USD light types (dome, distant, sphere, rect, disk, cylinder) with full light linking support

  • Cameras: Camera parameters, depth of field, motion blur

  • Animation: Time-sampled attributes, skeletal animation (UsdSkel)

While both scene delegates provide complete rendering capabilities, they differ significantly in their architecture, data sources, and synchronization strategies.

Note: Development focus has shifted to FSD as the primary scene delegate going forward. OmniHydra remains available for backward compatibility and will continue to receive maintenance updates, but new features and optimizations are primarily being developed for FSD. OmniHydra may be deprecated in future Kit releases.

Quick Recap: OmniHydra Scene Delegate#

Prior to Fabric Scene Delegate, Omniverse used a dual-delegate system where OmniImagingDelegate extended Pixar’s UsdImagingDelegate and coordinated with OmniHydraDelegate as its proxy delegate. This architecture was designed to work around UsdImagingDelegate’s performance limitations for dynamic content, and also added custom support for instancing and skeleton meshes.

OmniHydraDelegate provided a fast cache layer and direct write API that bypassed USD’s attribute resolution. Crucially, it integrated with Fabric to pull data for specific use cases—primarily transforms and dynamic/procedural geometry data, and scene queries—while most rendering data was still read from USD through UsdImagingDelegate. This partial Fabric integration provided performance benefits for dynamic content but required maintaining both USD and Fabric data paths.

Fabric Scene Delegate represents a fundamental shift by using Fabric as the exclusive data source for all rendering operations, eliminating the USD bottleneck.

Note on Terminology: Throughout this documentation, “OmniHydra” refers to the entire dual-delegate system (OmniImagingDelegate + OmniHydraDelegate + UsdImagingDelegate), not just the OmniHydraDelegate component. Fabric Scene Delegate replaces this entire architecture.

Quick Comparison#

Aspect

OmniHydra

Fabric Scene Delegate (FSD)

Data Source

Primarily USD, partial Fabric support

Exclusively Fabric

Fabric Population

Minimal (selective)

Comprehensive (all rendering data)

USD→Fabric Sync Timing

Immediate (auto)

Delayed (explicit call required)

Memory Usage

Lower

Higher (with optimizations available)

Performance

Good for static content

Excellent for dynamic content

Transform Format

Legacy _localMatrix (default)

New omni:fabric:localMatrix

Default Since

Up to Kit 108

Kit 109+

Source of Data#

OmniHydra: Mixed USD and Fabric#

OmniHydra primarily reads rendering data from USD, with optional support for reading a subset of data from Fabric. This creates a mixed data workflow where some features can come from Fabric (such as mesh deformations and transform updates), but most rendering data is read directly from USD.

Fabric support in OmniHydra is limited to specific use cases, such as GPU-accelerated deformations and select attribute types.

Fabric Scene Delegate: Fabric-Only#

FSD reads all rendering data exclusively from Fabric. This provides a cleaner, more uniform workflow where the data source is always clear and predictable.

Reading all data from Fabric provides several significant benefits:

Much Better Performance

Fabric is optimized for high-throughput runtime operations. By using Fabric as the primary data source, FSD can handle significantly more changes per frame compared to USD-based approaches. This is particularly important for simulations, procedural generation, and other scenarios with heavy per-frame updates.

Central Runtime Stage

Fabric becomes the central runtime stage through which all data flows to the renderer. This architecture allows extensions and simulation systems to write data directly to Fabric without round-tripping through USD, dramatically improving performance for dynamic content.

Support for Transient Data

Not all simulated or runtime-generated data needs to persist in USD. FSD handles transient Fabric data naturally, allowing temporary simulation results, procedural geometry, or other ephemeral content to be rendered without USD authoring overhead.

Cleaner Data Workflow

It’s always clear where rendered data comes from — exclusively from Fabric. This enables a clean separation of Kit extension code into “authoring” components (working with USD) and “runtime” components (working with Fabric). See the Extension Development with FSD documentation for more details on best practices for extension development.

Data Formats#

While both scene delegates use Fabric for at least some data storage, they expect different data formats for certain attributes.

Transform Representation#

OmniHydra: Originally used a legacy transform format with attributes like _localMatrix, _worldMatrix, and related properties. This format is described in detail in the Working with OmniHydra Transforms documentation. OmniHydra now also supports the newer Fabric transform format (see below) for compatibility, but the legacy format remains the default.

FSD: Uses the standard Fabric transform format with attributes like omni:fabric:localMatrix, omni:fabric:worldMatrix, and related properties. This is the recommended format documented in Fabric Transforms with IFabricHierarchy. For backward compatibility, FSD can work with prims using the legacy format through the Fabric Hierarchy system, which automatically converts between formats. However, the Scene Delegate itself reads only the new format.

World Extents Storage#

OmniHydra: Follows USD’s extent format, storing extents as an array of two GfVec3f values (3-component float vectors representing the minimum and maximum corners of the bounding box). In Fabric, this is represented as an array of two 3-component float tuples.

FSD: Stores world extents as a single 6-component double-precision tuple (minX, minY, minZ, maxX, maxY, maxZ). This format was chosen for two reasons:

  1. Precision: Double precision provides better accuracy for world-space bounding boxes, especially in large scenes

  2. Memory Efficiency: Fabric’s bucket system packs 6-component tuples tightly in linear memory, whereas array storage requires separate pointer indirection, reducing memory efficiency and cache performance

USD to Fabric Synchronization#

While technically outside the scope of Hydra scene delegates themselves, the USD-to-Fabric synchronization strategy is highly relevant because FSD uses a fundamentally different approach compared to OmniHydra. There are two key differences: how USD changes are synchronized to Fabric, and what data is populated when the stage is opened.

Change Synchronization Strategy#

OmniHydra: Immediate Synchronization

When OmniHydra is enabled (FSD disabled), USD changes are pushed to Fabric immediately as they occur. This immediate synchronization has important benefits:

  • Data Consistency: Extension code doesn’t need to worry about whether data is in USD or Fabric—they always contain the same values. Extensions can freely choose to read from either source.

  • No Conflicts: No risk of accidentally overwriting someone else’s pending changes in Fabric, since changes are applied immediately.

The main drawback is performance. Fabric is highly optimized for batch processing, but propagating changes one-by-one can be very slow. This particularly impacts scenarios with many USD changes:

  • Bulk authoring operations (writing many attributes or prims)

  • Pre-composition changes that trigger extensive post-composition updates (variant switching, payload toggling, adding layers, etc.). Note that Fabric stores post-composition USD data, so a single pre-composition change can affect many prims

FSD: Explicit (Delayed) Synchronization via USDRT Population

To achieve much better synchronization performance, a new population plugin called USDRT Population was developed together with FSD. They are tightly coupled: USDRT Population is always enabled when FSD is active, and the old immediate synchronization code is disabled.

USDRT Population uses explicit (delayed) synchronization:

  • USD changes are buffered as they occur (tracking what changed, not the actual values)

  • Changes are synchronized to Fabric in batches when the synchronization API is explicitly called

  • During synchronization, current values are read from USD and written to Fabric in an optimized batch process

This approach is significantly more efficient, but represents a fundamental change in behavior: user code can no longer assume that USD and Fabric contain the same data at any given time.

Important: Implications for Extension Developers

  • Mixed USD/Fabric Code: If you make changes in USD and immediately try to query them via USDRT API (which reads from Fabric), you may receive outdated data unless you explicitly call synchronization first.

  • Time-Sampled Transforms: The USDRT Population synchronization also handles time-sampled transformations. If your code needs recent time samples to be available in Fabric, it must trigger synchronization.

  • Kit Applications: In Kit, synchronization is automatically called right before rendering, so users typically don’t need to worry about manual synchronization for rendering purposes. However, extension code that reads from Fabric at other times needs to be aware of this behavior.

More details, recommendations, and code examples for writing mixed USD/Fabric code will be provided in the Extension Development with FSD documentation.

Data Population Scope#

Currently, neither OmniHydra nor the Fabric Scene Delegate populates all contents of the USD stage to Fabric. This section summarizes the population scope for each scene delegate.

OmniHydra: Minimal Population

With OmniHydra, USD-to-Fabric population is minimal and mostly user-controlled. Only specific data that extensions explicitly request is written to Fabric. This keeps Fabric memory usage low.

FSD: Comprehensive Population via USDRT Population

Since FSD reads everything from Fabric, USDRT Population must populate all rendering-relevant data from USD to Fabric. This includes:

  • All geometry data (meshes, curves, primitives, etc.)

  • All materials and shaders

  • All transforms for all prims with the Xformable type

  • All primvars, lights, cameras, and other rendering attributes

This happens automatically when a stage is opened—users don’t need to manually populate data. A nice benefit is that transform data for all Xformable prims is immediately available in Fabric, properly initialized with USD values.

However, this comprehensive population strategy has important implications for memory usage.

Memory Trade-offs

This convenience comes with a cost: rendering data is now duplicated in memory. While USD uses memory-mapped I/O (MMIO, memory-mapped file access) for efficient storage, Fabric maintains its own copy of the data. This means FSD typically has higher peak and settled memory usage compared to OmniHydra.

Memory Optimization Techniques

FSD includes several optimizations to reduce memory overhead:

  • Renderer-Side Scene Graph Instancing (enableRendererInstancing): Performs instancing in the renderer instead of duplicating prototype data in Fabric

  • Selective Instance Proxy Population (enableIntermediateInstanceProxyPopulation): When disabled (default), intermediate instance proxy prims are not populated, saving significant memory. Enable only if your workflow specifically requires these prims in Fabric.

  • Material Merging (mergeMaterials): Deduplicates identical materials to save memory

These settings are documented in detail in the Configuration documentation.

Additionally, starting with Kit 109, large VtArray data (such as mesh points, indices, and primvars) is shared between USD and Fabric using a zero-copy mechanism. This can reduce FSD’s memory footprint by up to 50% in scenes with many large meshes, significantly reducing the memory duplication concern for geometry-heavy scenes.

With these optimizations enabled, particularly the Kit 109+ zero-copy mechanism for large geometry, the practical memory difference between FSD and OmniHydra is often minimal, especially in geometry-heavy scenes.

Summary#

Choosing between OmniHydra and FSD involves trade-offs:

OmniHydra is suitable for:

  • Workflows requiring strict USD/Fabric data consistency

  • Static or slowly-changing scenes

  • Extensions that need immediate visibility of USD changes in Fabric

  • Legacy workflows during transition period

FSD is recommended for:

  • Simulations with high per-frame update rates

  • Procedural content generation

  • Animation-heavy workflows

  • Large scenes with instancing (especially with Kit 109+ zero-copy arrays)

  • New development (future-proof choice)

For most workflows, especially those involving simulation, animation, or procedural content, FSD’s performance benefits and cleaner architecture make it the recommended choice. Starting with Kit 109, FSD is enabled by default in most applications.

While OmniHydra will remain available for backward compatibility, new projects should target FSD to benefit from ongoing performance improvements and new features.