Omniverse Realtime Viewer
NVIDIAOfficialCreated by NVIDIA Omniverse
- Skill
- Tool integration
- Software development
- Apache-2.0
- Medium risk
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
The Omniverse Realtime Viewer skill acts as a central routing and architectural framework for developing USD-based 3D viewer applications. It provides a structured approach to composing rendering, scene state, and delivery mechanisms, ensuring that developers can integrate OVRTX rendering, OVStage scene management, and various UI or streaming adapters effectively. The skill emphasizes a modular architecture where the viewer runtime, UI/input adapters, and delivery systems are decoupled, allowing for consistent behavior across local and streamed environments.
What it does
- Provides a routing architecture for USD viewer apps, XR delivery, and GPU-accelerated rendering.
- Defines the separation of concerns between viewer runtime, UI adapters, and delivery systems.
- Offers guidance on integrating OVRTX for high-fidelity 3D rendering.
- Establishes conventions for camera interaction, scene state management, and input handling.
- Supports the implementation of specialized features like stylized rendering and CAE/CFD visualization.
- Provides protocols for agent-to-UI communication and scene control.
When to use it
- When starting the development of a new USD-based realtime viewer application.
- When integrating advanced rendering features like stylized visualization or AOV switching.
- When building XR or spatial editing capabilities into an existing Omniverse application.
- When you need to standardize the architecture for local and streamed viewer deployments.
- When implementing chat-driven scene control or agent-based inspection of a 3D scene.
Advantages
- Promotes a clean, modular architecture that separates rendering logic from UI and transport.
- Ensures consistent behavior across different delivery methods, such as local windows or WebRTC streaming.
- Provides clear paths for extending functionality without disrupting the core viewer runtime.
- Facilitates the integration of complex simulation and visualization data into the viewer.
- Standardizes conventions for scene state, selection, and camera control.
Usage examples
- “How do I set up a basic USD viewer application using the Omniverse Realtime Viewer architecture?”
- The agent will guide you to start with the viewer app reference, resolve dependencies, and implement the core runtime owner to manage the OVStage and OVRTX renderer.
- “I need to add stylized rendering to my existing viewer. Where should I start?”
- The agent will direct you to the stylized visualization references to implement the required USD/Lua/CUDA nodes within your existing runtime owner.
- “How can I enable an AI agent to control the viewer scene?”
- The agent will point to the A2UI Scene Copilot reference to implement an operation interface that allows the agent to send commands through the existing runtime owner.
- “How do I switch between different render outputs like beauty and depth in my viewer?”
- The agent will explain how to use the AOV switching reference to map RenderVars and update the RenderProduct's orderedVars through the runtime owner.
Install
Download the skill as a ZIP:
https://autogineer.com/agent-skills/nvidia/omniverse-realtime-viewer/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip omniverse-realtime-viewer.zip -d .agents/skills
Documentation by NVIDIA Omniverse
<!-- SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -->
<!-- SPDX-License-Identifier: Apache-2.0 -->
Omniverse Realtime Viewer
Build responsive USD viewers by composing OVRTX rendering, OVStage scene state, and the delivery/UI libraries appropriate to the app. Use this package for viewer architecture and interaction; use each selected SDK's upstream guidance for installation and exact release-specific APIs.
Start With The App
When delivery is explicit, select its recipe through
references/routing.mdand follow its current phase. Otherwise start withreferences/usd-viewer-app/README.md. For an existing app, keep its architecture and read only the references for the requested change. Broad app, conventions and UI catalogs are lookups as needed.Resolve the selected libraries through
references/dependencies/README.md. Preserve the project's manifest unless an upgrade is requested.Build a working frame and camera interaction in the chosen shell, then add the requested capabilities. Read
references/conventions.mdfor shared input, camera, selection, and protocol conventions.Use
references/viewer-ux-workflow/README.mdfor broader interface design. Loading, selection feedback, errors, and input responsiveness belong in the first working app, alongside rendering.Validate the actual delivery path with
references/validation.md. A browser screenshot does not validate a native window or a different transport.
Architecture
| Owner | Responsibility |
|---|---|
| Viewer runtime | Own the live OVStage, publication clock, OVRTX renderer, scene changes, and render stepping. |
| UI and input adapter | Display frames and copied app state; send user intent to the runtime owner. |
| Storage/query/simulation workers | Perform their assigned work and return results through the selected integration boundary. |
| Delivery adapter | Present locally or stream through ovstream; respect frame ownership and backpressure. |
Use OVRTX for USD/3D rendering. Browser apps display its WebRTC video; local apps present its output through their native shell. A missing GPU means rendering is unverified, not a reason to substitute a browser 3D renderer.
Keep viewer cameras, settings, effects, and transient edits in app-owned session
or runtime state so the source USD stays intact. Serialize scene mutation and
render stepping through the runtime owner. Read
references/ovstage-ovrtx-integration/README.md for that loop, then the population
or data-plane references when implementing scene loading or attribute writes.
Keep expensive loading and metadata work off the UI and render threads. Keep transport details behind a delivery adapter so camera, selection, properties, and loading state can be reused across local and streamed shells.
Add Capabilities As Needed
Use references/routing.md to select camera/picking, scene management, render
settings, cloud assets, simulation, editor tools, deployment, or CAE/CFD
visualization. Read the selected capability's implementation flow and its linked
contract; the full reference catalog is not a prerequisite for a first frame.
For simulation, use the routing reference's Simulation Ecosystem section plus
references/realtime-sim-integration/README.md. For UI-driven forces or control,
add references/interaction-round-trip/README.md.
For example scenes, use references/usd-sample-data/README.md. When a runtime
failure needs diagnosis, use references/troubleshooting/README.md and the
selected SDK's matching release guidance before changing the architecture.
Solid Modeling: Upstream First
For usd-brep, exact BRep, solid modeling, kernel failures, CAD topology, or
BrepArray questions, first read references/dependencies/README.md → USD BRep. Follow the
owning repository's current agent guidance, skills, operation docs, and package
API before selecting local integration references. Discover the upstream router
rather than assuming skill names or directory layouts remain fixed. Upstream
owns modeling semantics, schema rules, tuning, and diagnostics; this package
owns OVRTX display, worker handoff, selection mapping, and publication timing.
GPU Processing And Stylized Viewers
For custom GPU processing, chained outputs and lens sampling, read
references/spg-processing/README.md. For toon, ink, technical/X-Ray styles,
geometry strokes or full wireframe, continue to
references/stylized-visualization/implementation.md. Its USD/Lua/CUDA starting
node and geometry/depth/composite build sequence work with the selected viewer
recipe; use references/stylized-visualization/style-recipes.md for the preset
math and references/stylized-visualization/README.md for supporting contracts.
Implement the result inside the existing OVRTX/runtime owner and deliver the
published processed output. These instructions do not require a sample checkout
or a prior stylized-rendering implementation.
For an optional usd-brep geometry source, first read
references/dependencies/README.md → USD BRep and the owning repository's
current agent guidance, skills, and operation docs; then read
references/stylized-visualization/usd-brep-source.md for the display boundary.
XR Viewers
For headsets, immersive viewers, or spatial editors, start with
references/xr-viewer-recipe/README.md. Resolve SDK setup and contracts through
references/dependencies/ovxr.md; the library owns OpenXR lifecycle and frame
submission. For controllers, hands, navigation, or scene tools, add
references/xr-spatial-input/README.md and
references/ovxr-python-interactions/README.md. For projection-integrated UI,
read references/ovxr-composition-ui/README.md and
references/ovxr-composition-ui-validation/README.md.
Files
- ATTRIBUTION.mdAdded by AutoGineer943 B
- BENCHMARK.md13.4 KiB
- LICENSELicence file added by AutoGineer11.2 KiB
- SKILL.md6.4 KiB
- evals/evals.json7.0 KiB
- references/a2ui-scene-copilot/README.md10.9 KiB
- references/aov-switching/README.md10.5 KiB
- references/cae-cfd-visualization/README.md10.1 KiB
- references/cae-cfd-visualization/cae-data-ingestion.md5.6 KiB
- references/cae-cfd-visualization/coordinate-systems-and-up-axis.md11.0 KiB
- references/cae-cfd-visualization/data-and-operators.md11.7 KiB
- references/cae-cfd-visualization/driving-cae-viz-via-ovstage.md6.4 KiB
- references/cae-cfd-visualization/emitter-and-seed-sources.md16.3 KiB
- references/cae-cfd-visualization/glyphs.md7.1 KiB
- references/cae-cfd-visualization/ovstage-render-and-camera.md11.0 KiB
- references/cae-cfd-visualization/ovui-controls.md13.2 KiB
- references/cae-cfd-visualization/rtwt-blueprint-recreation.md11.9 KiB
- references/cae-cfd-visualization/streaming-cae-viewer.md25.9 KiB
- references/cae-cfd-visualization/temporal-playback.md9.2 KiB
- references/cae-cfd-visualization/usd-authoring-and-materials.md21.5 KiB
- references/cae-cfd-visualization/volume-rendering.md2.5 KiB
- references/camera-auto-select/README.md9.0 KiB
- references/camera-controls/README.md20.9 KiB
- references/camera-picker/README.md9.5 KiB
- references/cloud-assets/README.md4.5 KiB
- references/cloud-deployment/README.md19.6 KiB
- references/cloud-deployment/container-image-build.md2.2 KiB
- references/cloud-deployment/gpu-container-runtime.md2.8 KiB
- references/cloud-deployment/nvcf-self-hosted.md8.4 KiB
- references/cloud-deployment/nvcf-viewer-container-contract.md4.8 KiB
- references/cloud-deployment/webrtc-network-diagnostics.md3.9 KiB
- references/cloudxr-opaque-data-channel/README.md1.1 KiB
- references/conventions.md7.4 KiB
- references/cpp-native-viewer/README.md4.9 KiB
- references/cpp-native-viewer/build-details.md5.2 KiB
- references/cpp-native-viewer/interaction-features.md11.3 KiB
- references/cpp-native-viewer/presentation-loop.md8.0 KiB
- references/cpp-native-viewer/project-build.md3.4 KiB
- references/cpp-native-viewer/renderer-session.md7.1 KiB
- references/cpp-native-viewer/validation.md3.4 KiB
- references/dependencies/README.md6.8 KiB
- references/dependencies/electron-shm.md1.5 KiB
- references/dependencies/environment-validation.md6.6 KiB
- references/dependencies/frontend.md2.3 KiB
- references/dependencies/local-openusd-gpu.md8.7 KiB
- references/dependencies/nvidia-runtime.md14.8 KiB
- references/dependencies/ovrtx.md3.1 KiB
- references/dependencies/ovstream.md3.3 KiB
- references/dependencies/ovxr.md2.3 KiB
- references/dependencies/quick-setup.md2.6 KiB
- references/dependencies/skia-yoga.md936 B
- references/electron-shm-viewer/README.md2.5 KiB
- references/electron-shm-viewer/architecture-project.md6.3 KiB
- references/electron-shm-viewer/electron-client.md6.5 KiB
- references/electron-shm-viewer/protocol-interaction-lifecycle.md7.9 KiB
- references/electron-shm-viewer/python-shm-server.md5.5 KiB
- references/electron-shm-viewer/validation.md2.8 KiB
- references/exact-brep-in-usd/README.md2.5 KiB
- references/gl-viewport-overlay/README.md8.0 KiB
- references/gl-viewport-overlay/architecture.md4.1 KiB
- references/gl-viewport-overlay/example-gizmo.md5.5 KiB
- references/gl-viewport-overlay/interaction-pattern.md4.0 KiB
- references/gl-viewport-overlay/projection-alignment.md4.3 KiB
- references/headless-shm-cli/README.md12.3 KiB
- references/huggingface-usd/README.md7.7 KiB
- references/interaction-round-trip/README.md40.1 KiB
- references/local-viewer/README.md17.8 KiB
- references/native-picking-selection/README.md13.1 KiB
- references/navigation-presets/README.md4.6 KiB
- references/navigation-presets/preset-camera-ops.md5.1 KiB
- references/newton-physics/README.md8.8 KiB
- references/object-selection/README.md11.1 KiB
- references/ovrtx-rendering/README.md23.0 KiB
- references/ovstage-data-plane/README.md3.5 KiB
- references/ovstage-live-geometry/README.md3.3 KiB
- references/ovstage-ovrtx-integration/README.md5.0 KiB
- references/ovstage-population/README.md3.7 KiB
- references/ovstage-runtime/README.md3.1 KiB
- references/ovui-library/README.md3.3 KiB
- references/ovui-library/api-reference.md4.3 KiB
- references/ovui-library/extending.md4.8 KiB
- references/ovui-local-viewer-recipe/README.md4.7 KiB
- references/ovui-local-viewer-recipe/interaction-features.md16.9 KiB
- references/ovui-local-viewer-recipe/project-structure.md6.2 KiB
- references/ovui-local-viewer-recipe/setup-shell-renderer.md16.4 KiB
- references/ovui-local-viewer-recipe/validation-build-order.md6.1 KiB
- references/ovwidgets-editor-shell/README.md5.4 KiB
- references/ovxr-composition-ui-validation/README.md7.1 KiB
- references/ovxr-composition-ui-validation/evidence-gates.md3.5 KiB
- references/ovxr-composition-ui-validation/frustum-placement.md2.4 KiB
- references/ovxr-composition-ui-validation/library-only-validation.md8.1 KiB
- references/ovxr-composition-ui-validation/owned-orchestration.md5.3 KiB
- references/ovxr-composition-ui-validation/viewer-evidence.md4.0 KiB
- references/ovxr-composition-ui/README.md8.5 KiB
- references/ovxr-composition-ui/async-raster-pipeline.md5.0 KiB
- references/ovxr-composition-ui/compositor-passes-and-sync.md6.4 KiB
- references/ovxr-composition-ui/depth-tools.md5.0 KiB
- references/ovxr-composition-ui/editor-document-model.md4.8 KiB
- references/ovxr-composition-ui/experience-quality.md8.5 KiB
- references/ovxr-composition-ui/foveation-and-edge-math.md3.5 KiB
- references/ovxr-composition-ui/library-only-compositor.md10.4 KiB
- references/ovxr-composition-ui/native-build-and-discovery.md4.6 KiB
- references/ovxr-composition-ui/performance-and-telemetry.md7.9 KiB
- references/ovxr-composition-ui/primary-projection-compositor.md3.5 KiB
- references/ovxr-composition-ui/primary-projection.md4.1 KiB
- references/ovxr-composition-ui/projection-and-depth.md5.3 KiB
- references/ovxr-composition-ui/raster-abi.md3.0 KiB
- references/ovxr-composition-ui/sdk-frame-backend.md1.6 KiB
- references/ovxr-composition-ui/skia-yoga.md2.8 KiB
- references/ovxr-composition-ui/spatial-interaction.md5.6 KiB
- references/ovxr-composition-ui/spatial-surfaces-and-interaction.md10.4 KiB
- references/ovxr-composition-ui/telemetry-contract.md3.8 KiB
- references/ovxr-composition-ui/validation-and-live-gates.md3.9 KiB
- references/ovxr-foveation-and-display/README.md1.1 KiB
- references/ovxr-frame-loop-and-readback/README.md1.2 KiB
- references/ovxr-library-runtime/README.md1.1 KiB
- references/ovxr-library-runtime/ar-compositing.md4.4 KiB
- references/ovxr-library-runtime/frame-input-order.md2.2 KiB
- references/ovxr-library-runtime/library-only.md1.1 KiB
- references/ovxr-library-runtime/live-ar-controls.md4.3 KiB
- references/ovxr-library-runtime/mirror-lifetime.md4.1 KiB
- references/ovxr-library-runtime/settings-and-lifetime.md3.9 KiB
- references/ovxr-library-runtime/viewer-assembly.md225 B
- references/ovxr-openxr-runtime/README.md1012 B
- references/ovxr-python-interactions/README.md1.8 KiB
- references/ovxr-python-interactions/architecture.md5.5 KiB
- references/ovxr-python-interactions/feature-patterns.md7.4 KiB
- references/physics-simulation/README.md7.1 KiB
- references/prim-info-display/README.md10.9 KiB
- references/prim-pick-effects/README.md7.3 KiB
- references/prim-transform-safety/README.md8.6 KiB
- references/realtime-sim-integration/README.md7.0 KiB
- references/render-settings/README.md12.6 KiB
- references/routing.md37.7 KiB
- references/section-views/README.md5.8 KiB
- references/seg-outline-highlight/README.md1.5 KiB
- references/selection-animation/README.md5.0 KiB
- references/selection-feedback/README.md7.5 KiB
- references/smlib-brep-pitfalls/README.md2.5 KiB
- references/spg-processing/README.md8.0 KiB
- references/stage-attribute-reads/README.md6.2 KiB
- references/stage-hierarchy/README.md20.3 KiB
- references/stage-hierarchy/fallback-worker-protocol.md7.4 KiB
- references/stage-loading/README.md7.1 KiB
- references/stage-management/README.md6.6 KiB
- references/stage-queries/README.md6.1 KiB
- references/streaming-client/README.md25.6 KiB
- references/streaming-lifecycle/README.md4.6 KiB
- references/streaming-messages/README.md19.5 KiB
- references/streaming-messages/server-handler-map.md3.1 KiB
- references/streaming-server/README.md17.7 KiB
- references/streaming-server/frame-loop-and-continuity.md3.8 KiB
- references/streaming-viewer-recipe/README.md1.9 KiB
- references/streaming-viewer-recipe/client-protocol.md14.2 KiB
- references/streaming-viewer-recipe/interaction-features.md13.8 KiB
- references/streaming-viewer-recipe/project-structure.md7.3 KiB
- references/streaming-viewer-recipe/server-runtime.md20.2 KiB
- references/streaming-viewer-recipe/validation-build-order.md8.5 KiB
- references/streaming-vs-local/README.md9.4 KiB
- references/stylized-visualization/README.md8.7 KiB
- references/stylized-visualization/aov-guide-contracts.md8.1 KiB
- references/stylized-visualization/implementation.md11.4 KiB
- references/stylized-visualization/line-compositor-delivery.md7.7 KiB
- references/stylized-visualization/mesh-xray.md10.1 KiB
- references/stylized-visualization/reproduction-validation.md10.2 KiB
- references/stylized-visualization/style-composition-contract.md5.4 KiB
- references/stylized-visualization/style-recipes.md14.7 KiB
- references/stylized-visualization/usd-brep-source.md4.9 KiB
- references/subprocess-geometry-bridge/README.md3.5 KiB
- references/tauri-local-viewer/README.md6.7 KiB
- references/tauri-shm-transform-gizmo/README.md12.3 KiB
- references/transform-manipulator/README.md17.1 KiB
- references/troubleshooting/README.md11.2 KiB
- references/troubleshooting/scenario-playbooks.md24.7 KiB
- references/usd-sample-data/README.md12.0 KiB
- references/usd-viewer-app/README.md5.0 KiB
- references/validation.md6.3 KiB
- references/viewer-backend-interface/README.md20.1 KiB
- references/viewer-control-patterns/README.md4.8 KiB
- references/viewer-data-view-patterns/README.md5.6 KiB
- references/viewer-feedback-status/README.md5.0 KiB
- references/viewer-input-routing/README.md11.9 KiB
- references/viewer-layout-patterns/README.md4.7 KiB
- references/viewer-ux-workflow/README.md5.2 KiB
- references/viewport-overlays/README.md9.9 KiB
- references/viewport-overlays/cuda-compositing.md6.6 KiB
- references/viewport-resize/README.md4.0 KiB
- references/vulkan-compositing/README.md6.1 KiB
- references/vulkan-compositing/depth-overlays.md15.7 KiB
- references/vulkan-compositing/interop-and-lifecycle.md6.6 KiB
- references/webgl-shm-transport/README.md14.5 KiB
- references/windows-native-setup/README.md11.6 KiB
- references/xr-client-connection/README.md1.1 KiB
- references/xr-client-message-contract/README.md8.5 KiB
- references/xr-desktop-mirror/README.md13.8 KiB
- references/xr-session-modes-and-passthrough/README.md930 B
- references/xr-spatial-input/README.md2.3 KiB
- references/xr-spatial-input/advanced-tools.md5.2 KiB
- references/xr-spatial-input/controllers.md16.3 KiB
- references/xr-spatial-input/feature-validation.md4.9 KiB
- references/xr-spatial-input/gesture-arbitration.md4.9 KiB
- references/xr-spatial-input/gesture-filtering.md5.5 KiB
- references/xr-spatial-input/hand-recognizers.md4.0 KiB
- references/xr-spatial-input/hands.md10.3 KiB
- references/xr-spatial-input/navigation.md13.5 KiB
- references/xr-spatial-input/physics-interaction.md23.2 KiB
- references/xr-spatial-input/simulation-lifecycle.md5.9 KiB
- references/xr-spatial-input/stage-composition.md4.9 KiB
- references/xr-spatial-input/teleport-acceptance.md5.2 KiB
- references/xr-spatial-input/webxr-client.md3.9 KiB
- references/xr-tracking-anchor-and-scale/README.md950 B
- references/xr-viewer-recipe/README.md10.5 KiB
- skill-card.md7.7 KiB
- skill.oms.sig58.2 KiB
references/viewer-backend-interface/README.md
Viewer Backend Interface
Triggers
Use this skill for ViewerBackend, local shared UI, backend-agnostic React
viewer UI, reusable viewer components, viewer interface adapters, or
cross-transport UI.
Use this when a frontend should share the same panels, inspectors, selection controls, asset list, and viewer widgets across WebRTC streaming, Electron SHM, Tauri SHM/native IPC, or a future transport.
Purpose
The local viewer UI module is generated React component code plus a TypeScript
interface contract. The contract lets UI components depend on one
ViewerBackend object instead of transport-specific APIs such as AppStreamer
messages, Electron preload calls, Tauri commands, or future IPC layers.
The shared UI does not render USD or 3D content. All USD rendering still uses
ovrtx in the appropriate server or native process. In OVStage-backed apps, the
backend runtime also owns stage lifetime, ordinals, write floors, and renderer
publication. The UI displays a video, canvas, or pixel surface owned by the
transport and overlays reusable React controls that call ViewerBackend.
Read These Skills
| Need | Read |
|---|---|
| Browser/WebRTC transport | streaming-client, streaming-messages, streaming-lifecycle |
| Electron + SHM local transport | electron-shm-viewer, webgl-shm-transport |
| Tauri/native desktop transport | tauri-local-viewer |
| Camera input behavior | viewer-input-routing, camera-controls |
| Picking and selection | viewer-input-routing, object-selection, selection-feedback |
| Hierarchy and property data | stage-hierarchy, stage-attribute-reads |
| AOV and render settings messages | aov-switching, render-settings |
Local Module Setup
Generate these files inside the frontend app unless the user requests a different local structure:
frontend/src/viewer-ui/
ViewerBackend.ts
types.ts
StageTree.tsx
PropertyPanel.tsx
Inspector.tsx
PrimIconSprite.tsx
USDAsset.tsx
index.tsUse index.ts as the local barrel export. Do not add an external package
dependency for shared viewer UI.
Import components and types from the local module:
import {
Inspector,
PrimIconSprite,
PropertyPanel,
StageTree,
USDAsset,
type FrameData,
type PrimNode,
type PrimProperty,
type USDAssetItem,
type ViewerBackend,
} from './viewer-ui';The local index.ts exports Inspector, InspectorProps, PrimIconSprite,
PropertyPanel, StageTree, StageTreeProps, USDAsset, and all shared
viewer types.
ViewerBackend Interface
Implement this interface at the transport boundary. Components should call this interface, not raw WebRTC, Electron, Tauri, or server-message APIs.
export interface ViewerBackend {
connect(): Promise<void>;
disconnect(): void;
loadStage(path: string): Promise<void>;
resize?(width: number, height: number): Promise<void>;
sendRenderScale?(scale: number): Promise<void>;
setCamera(params: CameraParams): Promise<void>;
cameraMouseButton(input: PointerInput): Promise<boolean>;
cameraMouseMove(x: number, y: number): Promise<void>;
cameraWheel(delta: number): Promise<void>;
onFrame(callback: (frame: FrameData) => void): () => void;
onStats?(callback: (stats: FrameBudgetStats) => void): () => void;
onLoadProgress?(callback: (progress: LoadProgressEvent) => void): () => void;
onAOVStateChanged?(callback: (active: string, available: string[]) => void): () => void;
changeAOV?(aov: string): Promise<void>;
getCapabilities?(): Promise<ViewerCapabilities>;
invokeFeature?<T = unknown>(feature: string, payload: Record<string, unknown>): Promise<T>;
onSelectionChanged(callback: (paths: string[]) => void): () => void;
pick(x: number, y: number): Promise<string | null>;
getStageTree(rootPath?: string): Promise<PrimNode[]>;
selectPrims(paths: string[]): Promise<void>;
getProperties(path: string): Promise<PrimProperty[]>;
}Method contract:
| Method | Contract |
|---|---|
connect() | Establish the transport, register event/frame listeners, and resolve when commands can be sent. Guard duplicate calls from React remounts. |
disconnect() | Remove listeners, stop frame pumps, close transport handles, and reject or clear pending resolvers. Make cleanup safe to call more than once. |
loadStage(path) | Resolve when the runtime has produced the new scene's first valid frame and published its matching scene state. Reject failure, cancellation, or supersession; transport acceptance alone is not completion. Preserve the active scene during download and invalidate scene-local UI at renderer handoff. Track decoded-video readiness separately. |
resize?(width, height) | Resize a backend-owned dynamic render target when supported. Fixed-resolution video and fixed render-product transports should implement a no-op or omit this method. |
sendRenderScale?(scale) | Request a render-scale change when the backend supports adaptive scaling. Clamp to supported values and publish the effective scale through frame or stats updates when possible. |
setCamera(params) | Set camera state directly for backends that own explicit camera parameters. Native-input transports may resolve without action if camera motion is driven by pointer messages. |
cameraMouseButton(input) | Send a button press/release to the camera controller. Return true when the backend classifies the gesture as a click so callers can perform selection picking. |
cameraMouseMove(x, y) | Send pointer motion in viewport-local CSS pixels. Continuous input should be fire-and-forget internally but the Promise should settle quickly. |
cameraWheel(delta) | Send wheel zoom input. Preserve the backend's existing wheel sign convention from viewer-input-routing and camera-controls. |
onFrame(callback) | Subscribe to frame arrivals or frame timing. Return an unsubscribe function. FrameData.pixels is optional because WebRTC video transports may expose only timing. |
onStats?(callback) | Subscribe to transport/render performance stats such as FPS, queue depth, dropped frames, latency, and WebRTC inbound RTP stats when available. |
onLoadProgress?(callback) | Subscribe to stage-load progress phases. Use this for progress bars and disabled UI states during load. |
onAOVStateChanged?(callback) | Subscribe to active AOV and available AOV list changes. Call immediately with cached state when available so controls populate after reconnect. |
changeAOV?(aov) | Request an AOV/render-var switch. Reject unsupported AOV names or no-op only when the backend intentionally has no AOV support. |
getCapabilities?() | Return transport-neutral feature flags and effective runtime capabilities, such as supported AOVs, transform modes, pick effects, physics impulse support, and settings keys. |
invokeFeature?(feature,payload) | Optional extension command for app-specific capabilities. Reject unsupported features instead of falling through to transport internals. |
onSelectionChanged(callback) | Subscribe to canonical selected prim paths. Return an unsubscribe function and fan out both local UI selections and server/native selection events. |
pick(x, y) | Return the prim path under a viewport-element-local CSS pixel coordinate, or null. Never require callers to pass window coordinates. |
getStageTree(rootPath?) | Return normalized PrimNode[] for the root or requested prim path. It may use cached tree data, lazy queries, or a full hierarchy snapshot. |
selectPrims(paths) | Select the canonical prim paths in the backend and publish the same path list through onSelectionChanged. Also update native selection/highlight state when supported. |
getProperties(path) | Return displayable properties for a prim as PrimProperty[]. Normalize backend dictionaries, USD values, or typed command responses at this boundary. |
Critical Coordinate Contract
pick(x, y), cameraMouseButton(input), and cameraMouseMove(x, y) use viewport-element-local CSS pixel coordinates, not window coordinates.
For a local adapter that owns DOM gestures, subtract the viewport element rect. WebRTC/AppStreamer owns native viewport input: subscribe to its resulting selection events instead of forwarding a second DOM camera/pick path. The local release handler below assumes its adapter also received the matching press and motion events:
function toViewportPoint(event: React.PointerEvent, viewport: HTMLElement) {
const rect = viewport.getBoundingClientRect();
return {
x: event.clientX - rect.left,
y: event.clientY - rect.top,
};
}
const { x, y } = toViewportPoint(event, viewportElement);
const clicked = await backend.cameraMouseButton({ x, y, button: event.button, pressed: false });
if (clicked) {
const pickedPath = await backend.pick(x, y);
await backend.selectPrims(pickedPath ? [pickedPath] : []);
}If a backend needs render-product pixels, map from viewport-local CSS pixels to the contained image/canvas area inside the backend or viewport adapter. Do not pass raw PointerEvent.clientX/clientY into ViewerBackend.
Frame Delivery Contract
FrameData.pixels is optional. WebRTC/AppStreamer transports usually render into a <video> element and can only report frame timing, decoded dimensions, or stats through onFrame. SHM, Tauri, or future pixel transports may provide RGBA pixels.
Shared UI components must not require pixel data. Viewport display components may choose the transport-specific surface:
| Transport | Display surface | onFrame payload |
|---|---|---|
| WebRTC streaming | <video> from AppStreamer | Timing/dimensions; pixels usually absent |
| Electron SHM | Canvas/WebGL texture upload from SHM | RGBA pixels or transport-local buffer metadata adapted to FrameData |
| Tauri SHM/native IPC | Canvas/ImageData or texture upload | RGBA pixels when copied/decoded for the React layer |
| Future transport | Transport-owned surface | At least width, height, encoding, and timing when available |
Type Catalog
export interface CameraParams {
azimuth?: number;
elevation?: number;
distance?: number;
target?: [number, number, number];
}
export interface FrameData {
width: number;
height: number;
encoding: 'rgba';
pixels?: Uint8ClampedArray;
frameIndex?: number;
renderScale?: number;
}
export interface FrameBudgetStats {
timestampMs: number;
fps: number;
sourceFps: number;
frameIntervalMs: number;
deliveryMs: number;
queueDepth: number;
skippedFrames: number;
droppedFrames: number;
renderScale: number;
backpressure: boolean;
frame_time_ms?: number;
stream_time_ms?: number;
frames_rendered?: number;
gpu_encoder_active?: boolean;
roundTripTimeMs?: number;
packetsLost?: number;
jitter?: number;
framesDecoded?: number;
freezeCount?: number;
framesPerSecond?: number;
}
export type LoadProgressPhase =
| 'resolving_asset'
| 'loading_stage'
| 'compiling_shaders'
| 'ready';
export interface LoadProgressEvent {
phase: LoadProgressPhase;
stage_url?: string;
}
export type PrimType = 'xform' | 'scope' | 'geom' | 'light' | 'camera';
export interface PrimNode {
name?: string;
path: string;
children?: PrimNode[] | null;
hasChildren?: boolean;
type?: PrimType;
}
export type USDPrim = PrimNode;
export interface PrimProperty {
name: string;
type: string;
value: string;
}
export interface USDAssetItem {
name: string;
url: string;
}
export interface PointerInput {
x: number;
y: number;
button: number;
pressed: boolean;
}
export interface ViewerCapabilities {
aovs?: string[];
renderSettings?: string[];
runtimeTransforms?: boolean;
pickEffects?: string[];
physicsImpulse?: boolean;
transport?: 'webrtc' | 'electron-shm' | 'tauri' | 'ovui' | 'native' | string;
}Normalize transport payloads to these types before data reaches shared components. In particular, convert server fields such as has_children or boolean children into hasChildren, and convert property dictionaries into PrimProperty[].
Capability Extensions
Keep optional features out of the required interface so the same UI can run on
WebRTC, Electron SHM, Tauri, ovui, or future transports. Use
getCapabilities() to decide whether to show controls, and use
invokeFeature() or a typed adapter method in the transport adapter for the
actual command.
Useful feature names:
runtimeTransform: move, rotate, or scale selected prims through the runtime owner.pickEffect: apply a verified selection-driven material, visibility, or effect change.physicsImpulse: run a bounded physics worker and apply returned pose samples through parent runtime state.
Rules:
Shared components should never receive live OVStage handles, OVRTX handles, DLPack buffers, SHM pointers, or process-local tokens.
The backend adapter translates feature commands into data-channel messages, Tauri invokes, Electron IPC, or local API calls.
Physics controls should be disabled unless the backend reports either a verified
PhysX.attach_ovstage(stage, read_ordinal=...)path or a bounded OVPhysX worker path.A missing capability is a normal unsupported state, not a reason to add a browser-side renderer or mutate user USD files.
Shared Components
| Component | Use |
|---|---|
StageTree | Displays the USD hierarchy, selected-row state, expandable prims, and prim type icons. Wire row selection to backend.selectPrims() and expansion/lazy loading to backend.getStageTree(path) when the component props require callbacks. |
PropertyPanel | Displays PrimProperty[] for one prim. Feed it data from backend.getProperties(selectedPath). |
Inspector | Higher-level selected-prim inspector. Use it when the app wants shared selection/property behavior instead of composing PropertyPanel directly. |
PrimIconSprite | Defines the icon sprite used by hierarchy rows and inspector UI. Render once near the application root. |
USDAsset | Displays a loadable USD asset item. Feed it USDAssetItem values and call backend.loadStage(asset.url) on activation. |
When generating components, keep prop names small and stable. Do not bake
transport APIs into components; adapt the transport to ViewerBackend instead.
Minimum prop contracts:
export interface StageTreeProps {
backend: ViewerBackend;
selectedPaths: string[];
rootPath?: string;
}
export interface PropertyPanelProps {
properties: PrimProperty[];
}
export interface InspectorProps {
backend: ViewerBackend;
selectedPaths: string[];
}
export interface USDAssetProps {
asset: USDAssetItem;
backend?: ViewerBackend;
onLoad?: (asset: USDAssetItem) => void;
}Minimum behavior:
StageTreeloads root nodes withbackend.getStageTree(rootPath)on mount, loads children when an expandable row opens, highlightsselectedPaths, and callsbackend.selectPrims([path])on row activation.PropertyPanelrenders a compact name/type/value table and treats values as display strings unless another skill adds editing behavior.Inspectorsubscribes to selected paths through props, fetches properties for the primary selected path withbackend.getProperties(path), cancels stale responses on selection change, and renders an empty state for no selection.PrimIconSpritemay be a no-op component when the app uses text labels or CSS icons instead of an SVG sprite.USDAssetrenders one loadable asset row or button and callsonLoad(asset)when supplied; otherwise it callsbackend.loadStage(asset.url)when a backend prop is supplied.
Implementing a New Backend
Use the hook-per-transport pattern:
useWebRTCBackend.ts -> AppStreamer + data-channel messages + video timing
useShmBackend.ts -> Electron preload API + SHM frame pump + JSON control messages
useTauriBackend.ts -> Tauri commands/events/channels + native frame deliveryImplementation rules:
Return one stable
ViewerBackendobject from the hook withuseMemo.Keep transport objects, request resolvers, caches, and subscriber sets in refs.
Convert transport events into shared callbacks: frame, stats, load progress, AOV state, and selection.
Add timeouts to request/response promises for
loadStage,pick,getStageTree, andgetProperties.Resolve responses by request id when the protocol supports it; otherwise bucket by URL/path/message type.
Normalize all hierarchy nodes, property values, AOV names, and selected paths at the backend boundary.
Make
disconnect()clear subscribers only when the app is truly tearing down; ordinary event-handler cleanup should only unsubscribe that handler.Preserve the single render-thread/server ownership rules from the transport skill. The React backend is an adapter, not a renderer.
Resolver pattern:
type Resolver<T> = {
resolve: (value: T) => void;
reject: (error: Error) => void;
timer: number;
};
const selectionHandlers = useRef(new Set<(paths: string[]) => void>());
const frameHandlers = useRef(new Set<(frame: FrameData) => void>());
const treeResolvers = useRef(new Map<string, Resolver<PrimNode[]>[]>());
const propertyResolvers = useRef(new Map<string, Resolver<PrimProperty[]>[]>());
const treeCache = useRef(new Map<string, PrimNode[]>());
function emitSelection(paths: string[]) {
for (const handler of selectionHandlers.current) handler(paths);
}
function resolveBucket<T>(buckets: Map<string, Resolver<T>[]>, key: string, value: T) {
const bucket = buckets.get(key) || [];
buckets.delete(key);
for (const resolver of bucket) {
window.clearTimeout(resolver.timer);
resolver.resolve(value);
}
}Transport notes:
WebRTC/AppStreamer:
connect()owns one AppStreamer connection. RouteonCustomEventmessages into resolver buckets and subscriber sets.onFrameusually publishes timing from video playback quality or stats; leavepixelsundefined.Electron SHM:
connect()attaches preload/native SHM APIs and starts one frame pump. Convert SHM frames to the viewport's upload path and publish sharedFrameDataonly for data the shared UI needs.Tauri SHM/native IPC:
connect()registers Tauri event listeners and frame channels once. Decode binary RGBA frames when the React layer owns a canvas; otherwise publish timing/dimensions and let the viewport adapter own pixels.
Integration Recipe
Generate
frontend/src/viewer-ui/with theViewerBackendtypes and local React components required by the app.Implement a backend hook for the chosen transport:
useWebRTCBackend,useShmBackend,useTauriBackend, or a new hook.Mount the transport viewport surface:
<video>,<canvas>, or a native pixel-presenting component.Give the viewport one input owner. WebRTC uses AppStreamer native input; local DOM adapters convert coordinates before calling camera/pick methods.
Subscribe to backend selection and frame/stat events in React effects.
Render shared UI components against the backend rather than raw transport APIs.
Keep transport-specific message names and native handles inside the backend hook.
WebRTC skeleton (the backend hook owns AppStreamer input and connection state):
function ViewerApp() {
const backend = useWebRTCBackend(config); // stable identity for this endpoint
const [connectionError, setConnectionError] = useState<string | null>(null);
const [selectedPaths, setSelectedPaths] = useState<string[]>([]);
useEffect(() => {
let active = true;
void backend.connect().catch(error => {
if (active) setConnectionError(String(error));
});
return () => { active = false; backend.disconnect(); };
}, [backend]);
useEffect(() => backend.onSelectionChanged(setSelectedPaths), [backend]);
return (
<>
<PrimIconSprite />
{connectionError && <div role="alert">{connectionError}</div>}
<main className="viewer-shell">
<section className="viewport">
<video id="remote-video" />
</section>
<aside className="sidebar">
<StageTree backend={backend} selectedPaths={selectedPaths} />
<Inspector backend={backend} selectedPaths={selectedPaths} />
</aside>
</main>
</>
);
}Keep the dependency direction the same: app UI calls local viewer UI
components, those components call ViewerBackend, and only backend hooks know
the transport.
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Needs: Needs Python, Needs Node.js
The author says: Orchestrator skill. Downstream focused references may require NVIDIA GPUs, ovrtx, ovstream, ovui, OpenUSD, Python, Node/React, Tauri, Electron, C++, or cloud GPU deployment access depending on the selected viewer path.
Security
What our scanner noticed· Medium risk
- Large base64-encoded blobs
- Instructions that use the network
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Created by
- NVIDIA Omniverse
- Publisher
- NVIDIA (Official)
- Source
- NVIDIA/skills · skills/omniverse-realtime-viewer · commit fce3cca
- Licence
- Apache License 2.0 (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE-APACHE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by NVIDIA Omniverse or NVIDIA.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download omniverse-realtime-viewer.zip