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://mp-staging.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/local-viewer/README.md
Local Omniverse Realtime Viewer Shell
Triggers
Use this skill for ovui window shell, standalone viewport shell, simple ovui app, ImageBridge, image display, resize handling, mouse capture surfaces, or requests that should avoid the full ovui editor shell.
For a complete local desktop viewer, read ovui-local-viewer-recipe first and use
this as the focused shell/display skill. Use this for a small single-window
viewer: header, RTX viewport, optional sidebar, and inline controls. Do not use
ovui_widgets.app.application.Application; that starts the full USD Viewer editor with docking, menus,
property panels, transform gizmos, and status bars.
For mouse button normalization, click-vs-drag handling, and dispatch to camera
or selection controllers, read viewer-input-routing.
For header/sidebar controls, toolbar actions, render settings widgets,
sliders, and destructive confirmations, read viewer-control-patterns and
translate its client-agnostic control guidance into native ovui widgets.
For ovui widget APIs or native UI behavior not covered here, read
references/dependencies for acquisition guidance and supplemental dependency
documentation.
For ovrtx renderer setup, frame extraction, or release-specific behavior not
covered here, read references/dependencies for acquisition guidance and
supplemental dependency documentation.
Runtime Setup
Install and activate the selected ovui package through references/dependencies
before imports. The lightweight local path should keep the UI/render process
focused on ovui, OVRTX, and live OVStage/session state. Run pxr queries in a
subprocess unless the exact wheel set and import order have been verified for
the target machine.
import asyncio
import os
os.environ.setdefault("OVRTX_SKIP_USD_CHECK", "1")
import ovrtx
ovrtx.register_schema_paths()
import omni.ui as uiFor OVStage-backed local apps, the parent desktop process owns stage lifetime,
ordinals, the write floor, renderer attachment, and publication. Query workers
and physics workers should exchange JSON or other DTOs, not live stage handles,
path tokens, DLPack objects, or mapped buffers. If OVPhysX is requested, prefer
PhysX.attach_ovstage(stage, read_ordinal=...) after verifying the exact
installed OVStage/OVPhysX ABI. If that bridge is unavailable or fails, use a
bounded worker only when its installed-package API is verified; otherwise report
the compatibility block.
Run with a real display from the activated environment:
DISPLAY=:99 OVRTX_SKIP_USD_CHECK=1 python3 -m local_appIf renderer.step() hangs after a crash, use nvidia-smi and kill only stale Python Omniverse Realtime Viewer processes that still hold CUDA/RTX state.
ovui Window Shell
Use this as the canonical standalone ovui bootstrap for generated lightweight
local viewers in this skill package: initialize once, create one fill-window
ui.Window, paint through one provider, then run the update coroutine alongside
ui.run_async() in an application-owned asyncio loop. Do not generate
hasattr(ui, "get_app") or alternate bootstrap branches unless a targeted compatibility validation proves the selected wheel
changed the standalone contract.
Use fill_app_window=True; without it the GLFW window can resize while the UI frame remains stuck at the initial dimensions.
import asyncio
import numpy as np
import omni.ui as ui
def synthetic_rgba(width: int, height: int) -> np.ndarray:
x = np.linspace(0, 255, width, dtype=np.uint8)
y = np.linspace(0, 255, height, dtype=np.uint8)
rgba = np.zeros((height, width, 4), dtype=np.uint8)
rgba[:, :, 0] = x[None, :]
rgba[:, :, 1] = y[:, None]
rgba[:, :, 2] = 64
rgba[:, :, 3] = 255
return np.ascontiguousarray(rgba)
WIDTH = 1280
HEIGHT = 720
ui.init("Omniverse Realtime Viewer", width=WIDTH, height=HEIGHT, max_fps=60)
provider = ui.ByteImageProvider()
window = ui.Window(
"Omniverse Realtime Viewer",
width=WIDTH,
height=HEIGHT,
fill_app_window=True,
flags=ui.WINDOW_FLAGS_NO_TITLE_BAR,
)
with window.frame:
with ui.ZStack(style_type_name_override="Local.Root"):
ui.Rectangle(style_type_name_override="Local.Root")
with ui.VStack(spacing=0):
build_header(height=50)
with ui.HStack(spacing=0, height=ui.Fraction(1)):
with ui.Frame(width=ui.Fraction(1)):
ui.ImageWithProvider(
provider,
fill_policy=ui.IwpFillPolicy.IWP_PRESERVE_ASPECT_FIT,
)
with ui.Frame(width=ui.Pixel(280)):
sidebar.build()
provider.set_data_array(synthetic_rgba(640, 360), [640, 360])
async def render_loop():
while True:
# Advance viewer state here; ui.run_async owns presentation.
await asyncio.sleep(1.0 / 120.0)
async def run_until_closed(update, presentation):
tasks = [asyncio.create_task(update), asyncio.create_task(presentation)]
try:
done, _ = await asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED)
for task in done:
task.result() # propagate update or presentation failures
finally:
for task in tasks:
if not task.done():
task.cancel()
await asyncio.gather(*tasks, return_exceptions=True)
try:
asyncio.run(run_until_closed(render_loop(), ui.run_async()))
finally:
# Stop and join the render owner here once a runtime is connected.
window.destroy()
ui.shutdown()Keep the surface focused: black header, large viewport, white/sidebar utility area, green #76b900 accents. Avoid editor-only affordances unless requested.
ui.init(...) returns None. ui.run_async() presents frames until the native
window closes. When either task finishes, cancel and await the other before
stopping the render owner, destroying the window, and calling ui.shutdown().
The update coroutine should yield after each state update. This gives its
finally blocks time to run before the event loop and native backend disappear.
Validate this bootstrap before adding renderer or USD code.
Header And Load Controls
Keep scene loading boring and reliable. For lightweight local viewers, default
to one path field plus one LOAD button that calls the same serialized scene
load path used by command-line startup. Do not add a separate OPEN button or
native file dialog unless it is implemented and validated under the same
display/session environment as the viewer. A broken dialog next to a working
path loader creates needless ambiguity.
path_model = ui.SimpleStringModel(str(initial_stage))
ui.StringField(model=path_model, height=30)
ui.Button("LOAD", clicked_fn=lambda: runtime.load(path_model.get_value_as_string()))If a native file dialog is explicitly requested, keep it secondary and test it
with the target display stack (DISPLAY, Xvfb/VNC, Wayland/X11, container
permissions). On failure, report the dialog failure in the status bar and leave
the path-field loader usable.
Image Display
Use the app's local image bridge helper when a plain image widget is enough.
For projects using the ovui_widgets helper, import
ovui_widgets.viewport.image_bridge.ImageBridge; otherwise use
ui.ByteImageProvider directly. The renderer may stay at fixed resolution while
ImageWithProvider stretches with preserve-aspect letterboxing.
bridge = ImageBridge(render_width, render_height)
image = ui.ImageWithProvider(bridge.provider, fill_policy=ui.IwpFillPolicy.IWP_PRESERVE_ASPECT_FIT)
bridge.update(frame_rgba_uint8)For a direct provider path:
provider = ui.ByteImageProvider()
image = ui.ImageWithProvider(provider, fill_policy=ui.IwpFillPolicy.IWP_PRESERVE_ASPECT_FIT)
# arr is C-contiguous uint8 RGBA, shape H x W x 4
provider.set_data_array(arr, [arr.shape[1], arr.shape[0]])Use ui.color("#76b900") or ui.color(r, g, b, a) for style colors. The helper
packs ovui's integer 0xAABBGGRR format; image-provider pixels remain RGBA bytes.
Read LdrColor inside the map context and copy before returning:
# products is the mapping-like result of the render owner's renderer.step().
# RenderVar output maps use the full authored prim path.
rv = products[RENDER_PRODUCT_PATH].frames[0].render_vars["/Session/Render/Vars/LdrColor"]
with rv.map(device=ovrtx.Device.CPU) as mapping:
frame = np.from_dlpack(mapping).copy() # owned pixels for UI presentationDisplay Smoke Test And Blank-Viewport Triage
Before debugging camera, lighting, or USD composition, prove the ovui image path can paint a synthetic frame:
def synthetic_rgba(width: int, height: int) -> np.ndarray:
x = np.linspace(0, 255, width, dtype=np.uint8)
y = np.linspace(0, 255, height, dtype=np.uint8)
rgba = np.zeros((height, width, 4), dtype=np.uint8)
rgba[:, :, 0] = x[None, :] # red horizontal ramp
rgba[:, :, 1] = y[:, None] # green vertical ramp
rgba[:, :, 2] = 64 # visible blue floor
rgba[:, :, 3] = 255
return np.ascontiguousarray(rgba)
provider.set_data_array(synthetic_rgba(640, 360), [640, 360])Capture a desktop screenshot of the window and verify it is nonblank and non-solid. If the synthetic image does not paint, debug ovui presentation first: provider construction, widget visibility, frame sizing, style opacity, main-loop stepping, and whether the active provider API updates in this ovui build.
Use this decision tree for black, blank, or solid-color viewports:
Capture
LdrColordirectly from ovrtx outside ovui and save it as an image.If direct
LdrColoris blank, debug scene loading, camera fit, render product path, render vars, lighting, and material/plugin resolution.If direct
LdrColoris nonblank but the window is blank, debug ovui presentation before touching camera or renderer state.Test the chosen
ImageBridgeorByteImageProviderpath with the synthetic RGBA frame above.If dynamic byte-provider updates do not paint in the active ovui build, use a known-good ovui-native presentation path for validation, such as a
RasterImageProviderscreenshot/frame fallback, then document the selected presentation path in the generated app.
For unstable startup ordering, load the scene and render one direct ovrtx frame
before entering the long-running ovui loop. Continuous rendering may run in a
dedicated render worker that owns renderer.step() and copies the latest RGBA
frame into an application buffer; the ovui/main loop should only present that
latest copied frame. Do not call renderer.step() while another thread is
loading, resetting, or mutating the stage.
Resize And Letterbox Math
For picking, overlays, and camera input, compute the visible rendered image rect inside the viewport widget.
def widget_size(hit_rect, image, fallback):
w = int(float(getattr(hit_rect, "computed_width", 0.0) or 0.0))
h = int(float(getattr(hit_rect, "computed_height", 0.0) or 0.0))
if (w <= 0 or h <= 0) and image is not None:
w = int(float(getattr(image, "computed_width", 0.0) or 0.0))
h = int(float(getattr(image, "computed_height", 0.0) or 0.0))
return max(1, w or fallback[0]), max(1, h or fallback[1])
def image_content_rect(widget_w, widget_h, image_w, image_h):
image_aspect = image_w / max(1.0, float(image_h))
widget_aspect = widget_w / max(1.0, float(widget_h))
if widget_aspect > image_aspect:
draw_h = float(widget_h); draw_w = draw_h * image_aspect
return (widget_w - draw_w) * 0.5, 0.0, draw_w, draw_h
draw_w = float(widget_w)
return 0.0, (widget_h - draw_w / image_aspect) * 0.5, draw_w, draw_w / image_aspectThe ovui wheel callback is (delta_x, delta_y, modifiers). Use delta_y for
vertical zoom, preserve the modifier bitmask, and take cursor position from
pointer events.
Mouse Capture Surface
Attach callbacks to a transparent top-level ui.Rectangle over the image. Wrap callbacks; unguarded ovui callback exceptions can tear down the app loop.
hit_rect = ui.Rectangle(style={"background_color": 0x00000000})
hit_rect.opaque_for_mouse_events = True
hit_rect.set_mouse_pressed_fn(on_mouse_pressed)
hit_rect.set_mouse_released_fn(on_mouse_released)
hit_rect.set_mouse_moved_fn(on_mouse_moved)
hit_rect.set_mouse_wheel_fn(on_mouse_wheel)
def local_render_coords(screen_x: float, screen_y: float, clamp: bool):
x = float(screen_x) - float(hit_rect.screen_position_x)
y = float(screen_y) - float(hit_rect.screen_position_y)
off_x, off_y, draw_w, draw_h = image_content_rect(...)
if not clamp and (x < off_x or y < off_y or x > off_x + draw_w or y > off_y + draw_h):
return None
u = (x - off_x) / max(1.0, draw_w)
v = (y - off_y) / max(1.0, draw_h)
if clamp:
u, v = max(0.0, min(1.0, u)), max(0.0, min(1.0, v))
return u * render_width, v * render_heightdef on_mouse_moved(*args):
try:
if dragging and len(args) >= 2:
camera.on_mouse_move(*local_render_coords(args[0], args[1], clamp=True))
except Exception:
logger.exception("Mouse move failed")
dragging = FalseWhen a SceneView overlay and top-level mouse callbacks coexist, explicitly
arbitrate pointer ownership. A transform drag should suppress orbit and click
selection for that mouse-down; normal left-drag outside the transform handle can
still orbit. Do not let a gizmo drag also enqueue a pick on release.
Local Transform Gizmo Wiring
Use one transform adapter for the gizmo, Inspector and operation commands.
The UI owns pointer gestures; the runtime owner reads and writes scene state.
For attached apps, write local omni:xform values through OVStage and publish
before the renderer consumes them. Follow
prim transform safety for current ancestry,
reset stacks, typed matrix writes and publication. Its standalone-binding path
applies only when the renderer owns the scene.
At drag start, capture the selected paths, active scene generation and current live local/world transforms through that adapter. Keep selected prims separate from descendant meshes used for outlines.
Give the gizmo first refusal on the pointer gesture. Use transform manipulator for hit testing, projection and drag math; suppress camera movement and click-picking while the drag owns the pointer.
Compose each target from the drag-start snapshot in the chosen coordinate space and queue that intent to the runtime owner.
The owner checks generation and edit ownership, then converts a world target
Wto localL = W @ inverse(P)using the current effective parent-to-world matrixP. Reset stacks and simultaneous parent/child edits follow the canonical transform model. Apply the local matrices and publish with the other writes for that tick. Authored USD values are baselines, not replacements for current runtime transforms after live edits.Refresh the gizmo and Inspector from the same live state. On release, commit the final drag value; on cancel, restore the captured baseline through the same owner path. Retire the drag when its scene is replaced.
Verify numeric local/world results under a transformed parent, cancel/restore, and actual window input that moves the selected prim with its handle. A moving handle alone does not prove scene publication. Keep renderer output verification separate from transform readback.
Context Menu (Right-Click)
ovui supports popup context menus via ui.Menu. Show it on RMB release only when the mouse did not drag (use the drag threshold from viewer-input-routing or camera-controls). If the user drags RMB, that's a camera look/dolly — suppress the menu.
def on_mouse_released(x, y, button, modifier):
if button == 1: # RMB
if not _exceeded_drag_threshold:
_show_context_menu(x, y)
return
# ... other release handling
def _show_context_menu(screen_x: float, screen_y: float):
"""Show a popup context menu at the cursor position."""
if hasattr(ui, "Menu"):
menu = ui.Menu("Viewport")
with menu:
ui.MenuItem("Open File...", triggered_fn=_on_open_file)
ui.MenuItem("Reload Stage", triggered_fn=_on_reload)
ui.Separator()
ui.MenuItem("Frame All", triggered_fn=_on_frame_all)
ui.MenuItem("Reset Camera", triggered_fn=_on_reset_camera)
ui.Separator()
ui.MenuItem("Quit", triggered_fn=lambda: ui.shutdown())
menu.show_at(int(screen_x), int(screen_y))Key points:
Create the
ui.Menufresh each time (ovui menus are lightweight)Use
menu.show_at(x, y)with screen-space pixel coordinatesGuard with the drag threshold check — if the mouse moved ≥5 px between press and release, it was a camera gesture, not a menu intent
Wrap in try/except; older ovui builds may not support
show_at
Local Validation
Run python3 -m compileall local_app server, launch with DISPLAY=:99, prove
synthetic ovui presentation paints in the window, save a direct LdrColor
artifact, and capture a desktop screenshot showing that same rendered frame in
the ovui window. Then resize the window, switch Sample 1/Sample 2, verify stage01
renders without extra session lights, check tree/viewport selection, confirm
native selection outlines clear on load, verify prim animation returns on
clear/reset, ensure prim info follows orbit/pan/zoom/resize, and confirm
orbit/pan/right-drag zoom/wheel move the camera. Confirm selected-prim gizmo
drag changes the prim's live omni:xform; do not accept a result where the
gizmo appears but the prim is stationary. Left-click selection
must not fire after orbit drags.
See also: ovrtx-rendering, stage-loading, viewer-input-routing, viewer-control-patterns, camera-controls, object-selection, selection-feedback, transform-manipulator, prim-transform-safety, prim-info-display, stage-management, render-settings, dependencies.
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