Omniverse Realtime Viewer
OpenAIOfficialCreated by NVIDIA OmniverseDistributed by OpenAI
- Skill
- Meta (authoring, orchestration, planning, memory)
- 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 orchestrator for developing USD-based viewer applications. It provides a structured approach to selecting implementation recipes, enforcing architectural conventions, and managing dependencies. By utilizing a set of focused reference documents, it guides developers through the lifecycle of building, configuring, and validating viewer applications, ensuring consistent behavior across different delivery paths such as local workstations or streaming environments.
What it does
- Routes development requests to specific implementation recipes based on the target delivery path.
- Enforces architectural rules for USD rendering, stage management, and UI integration.
- Provides guidance on camera selection, input handling, and viewport interaction.
- Standardizes the integration of AOV switching and render product configuration.
- Facilitates the capture of validation evidence for viewer readiness.
- Maintains separation between user-provided USD files and application-specific session state.
When to use it
- When initiating the development of a new USD viewer application within the Omniverse ecosystem.
- When determining the appropriate delivery path for a viewer, such as local native or streaming.
- When needing to implement consistent camera, selection, or UI behavior across viewer projects.
- When integrating advanced rendering features like AOV switching into an existing viewer.
Advantages
- Ensures architectural consistency across diverse viewer implementations.
- Provides a clear, modular path for adding specific capabilities like input routing or data display.
- Promotes clean separation of concerns between stage data and viewer-owned state.
- Standardizes the validation process for consistent delivery.
Usage examples
- “I need to build a browser-based viewer for USD files.”
- The agent will route you to the streaming viewer recipe, providing guidance on WebRTC stream setup, UI integration, and viewport interaction.
- “How do I implement AOV switching in my local USD viewer?”
- The agent will provide the AOV switching reference, detailing how to map render vars and update the display state on the server.
Install
Download the skill as a ZIP:
https://autogineer.com/agent-skills/openai/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
This is the top-level entry point for the Omniverse Realtime Viewer skill package. It is self-contained: all required routing, conventions, and validation guidance live in the selected references.
Use the focused reference documents as implementation recipes. This file chooses the right recipes and preserves the architectural rules that must hold across all generated viewer apps.
Instructions
Start by classifying the requested viewer, then read only the references needed
for that delivery path and feature set. Implement the render path first, layer
interaction and UI behavior on top of it, and finish by capturing validation
evidence from references/validation.md.
Read Order
Read
references/routing.mdto choose the delivery path and focused references.Read
references/conventions.mdbefore implementing camera, input, selection, viewport, streaming protocol, scene loading, or environment behavior.For broad viewer requests, read
references/usd-viewer-app/README.md.If the delivery path is unclear, read
references/streaming-vs-local/README.md.If the prompt includes layout, panels, controls, inspectors, status, or UX, read
references/viewer-ux-workflow/README.mdand then the focused viewer UI references. This applies to React/WebRTC, Tauri, Electron,ovui,ovwidgets, and Dear ImGui apps; "frontend" means user-facing UI, not only browser UI.For viewport interaction, read
references/viewer-input-routing/README.mdbeforereferences/camera-controls/README.md,references/native-picking-selection/README.md, orreferences/object-selection/README.md.Read only the focused capability references needed for the requested app.
Use
references/validation.mdto capture review evidence before handoff.
Non-Negotiables
Use
ovrtxfor all USD and 3D rendering.Browser apps display an
ovstreamWebRTC video stream plus UI. The browser does not render USD geometry.Do not substitute WebGL, Three.js, Babylon.js, PlayCanvas, A-Frame, model-viewer, react-three-fiber, glTF browser viewers, or other client-side 3D renderers.
If local validation cannot run because the GPU/runtime environment is absent, scaffold the
ovrtxpath and document the runtime requirement. Do not add a browser-renderer fallback.Keep user USD files unmodified. Viewer cameras, render products, render vars, settings, selection metadata, and runtime state belong in session/composite layers or app state.
Keep one owner for
renderer.step(), stage mutation, native picking, selection writes, and live attribute writes.Keep dependency acquisition in
references/dependencies/README.mdand deployment choices inreferences/cloud-deployment/README.md; do not duplicate package locations or deployment setup.
Focused Reference Families
Entry points and recipes:
references/usd-viewer-app/README.md,references/streaming-viewer-recipe/README.md,references/ovui-local-viewer-recipe/README.md,references/streaming-vs-local/README.md,references/electron-shm-viewer/README.md,references/ovwidgets-editor-shell/README.md.Rendering and stage:
references/ovrtx-rendering/README.md,references/stage-loading/README.md,references/stage-management/README.md,references/render-settings/README.md,references/aov-switching/README.md,references/stage-hierarchy/README.md,references/stage-queries/README.md,references/stage-attribute-reads/README.md,references/prim-transform-safety/README.md,references/usd-sample-data/README.md.Delivery and runtime:
references/streaming-server/README.md,references/streaming-client/README.md,references/streaming-messages/README.md,references/streaming-lifecycle/README.md,references/local-viewer/README.md,references/tauri-local-viewer/README.md,references/cpp-native-viewer/README.md,references/headless-shm-cli/README.md,references/viewer-backend-interface/README.md,references/webgl-shm-transport/README.md.Viewer UI/UX:
references/viewer-ux-workflow/README.md,references/viewer-layout-patterns/README.md,references/viewer-control-patterns/README.md,references/viewer-data-view-patterns/README.md,references/viewer-feedback-status/README.md.Interaction:
references/viewer-input-routing/README.md,references/camera-controls/README.md,references/object-selection/README.md,references/native-picking-selection/README.md,references/selection-feedback/README.md,references/selection-animation/README.md,references/transform-manipulator/README.md,references/gl-viewport-overlay/README.md,references/ovui-library/README.md,references/prim-pick-effects/README.md,references/prim-info-display/README.md,references/viewport-overlays/README.md.Infrastructure:
references/dependencies/README.md,references/windows-native-setup/README.md,references/cloud-assets/README.md,references/cloud-deployment/README.md,references/troubleshooting/README.md.
Build Workflow
Classify the prompt by delivery path, target user, required capabilities, runtime environment, validation needs, and explicit constraints.
Select a small reference set. Start with the recipe or routing reference, then add focused capabilities such as camera, picking, hierarchy, properties, render settings, transform tools, cloud assets, or deployment.
Read selected references before writing app code. Follow their build order, import order, data-channel contracts, and renderer ownership rules.
Implement the core render path first, then input routing and camera, then selection and data panels, then scene/settings features, then packaging or deployment.
Treat the selected references as the behavior contract for API shape, compatibility, and generated project structure.
Capture validation evidence before calling the viewer ready.
Examples
For a browser viewer request, use the streaming recipe references plus camera, picking, hierarchy, properties, render settings, and stream-status references.
For a local workstation viewer request, use the local or native delivery references plus renderer setup, stage loading, viewport input, and validation.
Completion Checklist
Selected references match the user's intent and delivery path.
No code path uses a browser-side 3D renderer for USD.
The generated app has one clear owner for render stepping and stage mutation.
User USD files remain untouched by viewer-owned session data.
Camera, input, selection, scene loading, and stream behavior follow
references/conventions.md.Setup/build/run results and visual interaction evidence are captured with
references/validation.md.
Files
- ATTRIBUTION.mdAdded by AutoGineer1.0 KiB
- BENCHMARK.md5.5 KiB
- LICENSEAdded by AutoGineer10.0 KiB
- SKILL.md7.4 KiB
- agents/openai.yaml315 B
- evals/evals.json8.1 KiB
- references/aov-switching/README.md15.2 KiB
- references/camera-auto-select/README.md7.4 KiB
- references/camera-controls/README.md17.1 KiB
- references/camera-picker/README.md9.7 KiB
- references/cloud-assets/README.md10.4 KiB
- references/cloud-deployment/README.md18.0 KiB
- references/conventions.md5.3 KiB
- references/cpp-native-viewer/README.md2.4 KiB
- references/cpp-native-viewer/interaction-features.md19.2 KiB
- references/cpp-native-viewer/presentation-loop.md9.0 KiB
- references/cpp-native-viewer/project-build.md6.4 KiB
- references/cpp-native-viewer/renderer-session.md4.5 KiB
- references/cpp-native-viewer/validation.md3.3 KiB
- references/dependencies/README.md3.4 KiB
- references/dependencies/electron-shm.md1.5 KiB
- references/dependencies/environment-validation.md4.4 KiB
- references/dependencies/frontend.md2.3 KiB
- references/dependencies/local-openusd-gpu.md4.4 KiB
- references/dependencies/nvidia-runtime.md9.0 KiB
- references/dependencies/ovrtx.md2.4 KiB
- references/dependencies/ovstream.md2.5 KiB
- references/dependencies/quick-setup.md5.3 KiB
- references/electron-shm-viewer/README.md2.2 KiB
- references/electron-shm-viewer/architecture-project.md6.3 KiB
- references/electron-shm-viewer/electron-client.md5.6 KiB
- references/electron-shm-viewer/protocol-interaction-lifecycle.md6.9 KiB
- references/electron-shm-viewer/python-shm-server.md4.9 KiB
- references/electron-shm-viewer/validation.md2.8 KiB
- references/gl-viewport-overlay/README.md7.9 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.2 KiB
- references/huggingface-usd/README.md7.7 KiB
- references/local-viewer/README.md15.0 KiB
- references/native-picking-selection/README.md10.4 KiB
- references/object-selection/README.md9.4 KiB
- references/ovrtx-rendering/README.md18.2 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.md3.7 KiB
- references/ovui-local-viewer-recipe/interaction-features.md16.1 KiB
- references/ovui-local-viewer-recipe/project-structure.md6.2 KiB
- references/ovui-local-viewer-recipe/setup-shell-renderer.md14.3 KiB
- references/ovui-local-viewer-recipe/validation-build-order.md5.5 KiB
- references/ovwidgets-editor-shell/README.md8.6 KiB
- references/prim-info-display/README.md9.3 KiB
- references/prim-pick-effects/README.md5.9 KiB
- references/prim-transform-safety/README.md8.2 KiB
- references/render-settings/README.md9.9 KiB
- references/routing.md16.5 KiB
- references/seg-outline-highlight/README.md1.4 KiB
- references/selection-animation/README.md9.7 KiB
- references/selection-feedback/README.md6.6 KiB
- references/stage-attribute-reads/README.md5.5 KiB
- references/stage-hierarchy/README.md17.1 KiB
- references/stage-hierarchy/fallback-worker-protocol.md3.5 KiB
- references/stage-loading/README.md19.3 KiB
- references/stage-management/README.md10.1 KiB
- references/stage-queries/README.md5.3 KiB
- references/streaming-client/README.md17.4 KiB
- references/streaming-lifecycle/README.md8.8 KiB
- references/streaming-messages/README.md16.5 KiB
- references/streaming-messages/server-handler-map.md3.1 KiB
- references/streaming-server/README.md18.6 KiB
- references/streaming-server/frame-loop-and-continuity.md3.3 KiB
- references/streaming-viewer-recipe/README.md4.8 KiB
- references/streaming-viewer-recipe/client-protocol.md11.0 KiB
- references/streaming-viewer-recipe/interaction-features.md13.0 KiB
- references/streaming-viewer-recipe/project-structure.md7.0 KiB
- references/streaming-viewer-recipe/server-runtime.md16.8 KiB
- references/streaming-viewer-recipe/validation-build-order.md5.8 KiB
- references/streaming-vs-local/README.md8.1 KiB
- references/tauri-local-viewer/README.md18.2 KiB
- references/tauri-shm-transform-gizmo/README.md11.8 KiB
- references/transform-manipulator/README.md15.0 KiB
- references/troubleshooting/README.md7.2 KiB
- references/troubleshooting/scenario-playbooks.md18.8 KiB
- references/usd-sample-data/README.md11.7 KiB
- references/usd-viewer-app/README.md7.5 KiB
- references/validation.md3.0 KiB
- references/viewer-backend-interface/README.md17.7 KiB
- references/viewer-control-patterns/README.md4.8 KiB
- references/viewer-data-view-patterns/README.md4.8 KiB
- references/viewer-feedback-status/README.md4.9 KiB
- references/viewer-input-routing/README.md7.8 KiB
- references/viewer-layout-patterns/README.md4.7 KiB
- references/viewer-ux-workflow/README.md4.6 KiB
- references/viewport-overlays/README.md4.8 KiB
- references/viewport-resize/README.md8.5 KiB
- references/webgl-shm-transport/README.md14.5 KiB
- references/windows-native-setup/README.md5.7 KiB
- skill-card.md2.9 KiB
- skill.oms.sig28.6 KiB
references/troubleshooting/scenario-playbooks.md
<!-- SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -->
<!-- SPDX-License-Identifier: Apache-2.0 -->
Troubleshooting Scenario Playbooks
Server Startup
Check first:
OVRTX_SKIP_USD_CHECK=1is set before ovrtx is imported or constructed.OVRTX_BIN_PATHpoints at the ovrtxbindirectory when renderer plugins or MDL materials fail.OVSTREAM_LIB_PATHpoints at the native ovstream library directory whenovstreamcannot import.The process uses one USD import strategy: ovrtx-first for streaming, documented local-viewer ordering for lightweight local paths, or a separate
pxrworker on Windows.A GPU is visible and the selected CUDA device is not already held by a stale Omniverse Realtime Viewer process.
Signaling and media ports are available.
Logs to inspect:
Python server stdout/stderr, including ovrtx construction and ovstream initialize logs.
Any app log file configured by the generated viewer, commonly under
logs/or the current working directory.pxr_worker.pystderr if hierarchy/properties run in a subprocess.Native crash output from the terminal that launched the server.
Usual fixes:
Set the environment before launching Python, then fully restart the server.
Move ovrtx bundled plugin libraries first in the dynamic library path if another USD build is loaded.
Kill stale GPU Omniverse Realtime Viewer processes after a renderer crash or hang.
Change the signaling port if another process owns it.
Server-Side Diagnostics
Run these from the server machine:
nvidia-smi
ps -ef | rg 'python|ovstream|viewer|vite'
ss -ltnup | rg '49100|47999|8554'
lsof -iTCP:49100 -sTCP:LISTEN
env | rg 'OVRTX|OVSTREAM|LD_LIBRARY_PATH|PATH'Interpretation:
nvidia-smishows whether the GPU is visible and which PIDs still own GPU memory.psidentifies duplicate servers, stale renderers, and runaway frontend dev servers.ss/lsofconfirms whether signaling port49100, WebRTC media UDP, or RTSP port8554is already bound.Environment output confirms whether the launched process actually received the paths you set in the shell.
Browser Cannot Connect
Check first:
The server was started before the frontend connects.
The frontend uses
serverandsignalingPort, notsignalingServer.The frontend uses standalone ovstream Direct config:
serverandsignalingPort.The frontend does not set
mediaServer,mediaPort,signalingPath, or auth/session fields inDirectConfig. If an orchestrator launches the container, map its exposed endpoint toserverandsignalingPort.Local development uses
webrtc_public_ip=127.0.0.1or an explicitly reachable LAN IP.Only one WebRTC client is connected unless the server intentionally replaces the old session.
Logs to inspect:
Browser console for WebSocket/signaling errors.
Browser Network tab for the signaling request and WebSocket upgrade. If
POST /sign_inreturns HTTP 501, verify the frontend did not follow a Kit/OVC/NVCF/GFN client profile or inject auth/session fields before changing the ovrtx or ovstream server.Server logs for connection callbacks.
chrome://webrtc-internalsoredge://webrtc-internalsfor ICE, DTLS, and media state.
Usual fixes:
Match frontend host/port to the server's WebRTC signaling config.
Remove
mediaPortfrom frontend config.Reduce aggressive reconnect settings when logs show repeated previous-session messages.
Close the old browser tab or restart the ovstream server if the previous session is stuck.
Video Does Not Stream
Check first:
server.on_connection,server.on_message, andserver.on_inputare registered beforeserver.start().The render loop is calling
renderer.step()with the exact active RenderProduct path.LdrColorexists in the returned render vars.The app submits BGRA8 frames to ovstream, not ovrtx RGBA8.
CUDA or CPU frame buffers stay alive until
stream_video()returns.Render var data is copied while the owning
RenderProductSetOutputsis still alive; frame views are not held across laterrenderer.step()calls.Stream width, height, and pitch match the frame buffer.
The
<video>element exists beforeAppStreamer.connect().On cold start, the first
renderer.step()may spend 2-5 minutes compiling RTX shaders or pipelines before producing a frame.
Logs to inspect:
Server frame counters and render product names.
ovrtx logs for first-run shader or pipeline compilation progress.
ovstream warnings from the log callback.
Browser media element errors in the console.
WebRTC internals inbound video stats: frames decoded, frames dropped, resolution, bitrate.
Usual fixes:
Fix RenderProduct/session layer setup before changing WebRTC code.
Add or repair RGBA-to-BGRA conversion when red and blue are swapped.
Keep browser streaming at the configured fixed resolution. If that startup configuration changes, restart/reconnect instead of resizing the live stream.
Copy frame data inside the same render-loop step when passing it to an encoder, stream, UI bridge, or worker queue.
Use at least a 300 second timeout for the first rendered frame on a cold cache, then expect later steps to be much faster.
Local ovui Window Is Black Or Blank
Use this for local desktop viewers where ovrtx renders in-process and ovui presents copied RGBA frames.
Check first:
Save a direct ovrtx
LdrColorartifact from the same RenderProduct and RenderVar path used by the window.Push a synthetic RGBA gradient through the exact ovui provider/widget path and capture a desktop screenshot of the window.
Verify the image widget has nonzero computed size, visible opacity, and is not covered by an opaque overlay.
Verify ovui style colors use
0xAARRGGBB, not another byte order.Verify only one owner calls
renderer.step(), and no step overlapsopen_usd*, reference mutation, orreset_stage().
Interpretation:
Direct
LdrColoris blank: debug scene loading, camera path, render product, render var source, camera transform, stage lighting, and material/plugin resolution.Direct
LdrColoris nonblank but the synthetic ovui frame is blank: debug ovui presentation, provider updates, widget layout, and main-loop stepping.Direct
LdrColoris nonblank and the synthetic frame paints, but live frames stay blank: debug copied-frame lifetime, provider update calls, and whether the ovui loop is presenting the latest copied frame.
Usual fixes:
Prove presentation with the synthetic frame before changing camera or USD composition.
If dynamic byte-provider updates do not paint in the active build, validate with a known-good ovui-native path such as a
RasterImageProviderscreenshot/frame fallback.Render or warm up one direct ovrtx frame before entering the long-running ovui loop when startup ordering is unstable.
Move continuous rendering into one render worker that owns renderer mutation; let the ovui/main loop present only the latest copied RGBA frame.
Electron SHM Viewer
Use this for local separate-process Electron viewers where the Python server owns ovrtx rendering and Electron only presents already-rendered pixels through SharedArrayBuffer and WebGL texture upload.
Check first:
Black viewport in Electron: check the canvas
desynchronizedcontext flag and remove it under Xvfb, verify SAB delivery, and log frame sequence numbers on both sides.Wrong colors: BGRA/RGBA swap was not applied, or
GL_BGRA_EXTis not available.SHM segment not found: server was not started with
--shm, or the stream name does not match the Electron client.N-API addon won't build:
node-gypis missing, the Node ABI does not match Electron, orlibovstream_shm_client.sois missing.SharedArrayBuffer unavailable: COOP/COEP headers are missing in Electron
BrowserWindowwebPreferences.Electron shows "SHM connected" but no frames: AsyncWorker vs ThreadSafeFunction issue in Electron; use TSFN for frame callbacks.
Frame stutter at >30fps: check the frame pacing throttle and confirm the renderer updates with
texSubImage2Dinstead of reallocating withtexImage2D.
Logs to inspect:
Python server startup arguments, especially
--shm, stream name, frame size, ring-buffer size, and frame counters.Native N-API addon build logs for ABI, include path, and
libovstream_shm_client.soresolution errors.Electron main-process logs for BrowserWindow isolation, preload setup, and native addon load failures.
Electron renderer logs for SAB byte length, frame sequence numbers, pixel format, and WebGL extension availability.
Usual fixes:
Start the server in SHM mode with the same stream name the Electron client uses.
Configure Electron so SharedArrayBuffer is available through the isolated preload/contextBridge path.
Use ThreadSafeFunction for native-to-JavaScript frame notifications instead of relying on AsyncWorker callbacks.
Remove the desynchronized canvas context flag when running under Xvfb.
Apply the expected BGRA/RGBA conversion path or use
GL_BGRA_EXTonly after checking support.Reuse the WebGL texture with
texSubImage2Dand throttle presentation to the intended frame rate.
Data Channel Does Not Work
Check first:
Frontend sends only after streaming status is connected.
Server send helper checks that a client is connected before
send_message.The server unwraps browser library messages that contain
messageType,messageRecipient, and nesteddata.Exact event names match on both sides:
openStageResult,getChildrenResult,stageSelectionChanged,getPropertiesResponse.The frontend
onCustomEventrouter is registered before responses arrive, or the server proactively pushes state on connect.Slow USD queries are not running directly inside ovstream callback threads.
Logs to inspect:
Raw incoming data-channel messages on the server before dispatch.
Frontend
onCustomEventpayloads.Browser console for JSON parse errors.
Server handler map misses or "unknown event" warnings.
Usual fixes:
Unwrap the AppStreamer envelope before reading
event_type.Add one shared message-name reference and update both frontend and server routers.
Push current stage, hierarchy root, selection, loading state, and render settings after a reconnect.
Queue slow work for the render/runtime thread.
Frame Looks Wrong
Check first:
Red/blue swapped means ovrtx RGBA was sent to ovstream without BGRA conversion.
Black frame means invalid camera relation, bad camera transform, missing resolution, wrong RenderVar
sourceName, or wrong RenderProduct path.Magenta materials mean MDL resolver paths are wrong, usually missing
OVRTX_BIN_PATHor plugin library path.Frozen frame means
renderer.step()stopped, a buffer lifetime bug exists, or the browser is still connected to an old session.Invalid output-handle errors usually mean a frame or mapped render var view outlived its
RenderProductSetOutputs.Stale GPU hangs after crashes usually mean an old Python process still owns GPU resources.
GPU utilization can show 0% during first-run shader compilation; inspect logs before assuming a graphics hang.
Logs to inspect:
ovrtx warnings about RenderProduct, RenderVar, camera, material, and MDL resolution.
Per-frame counters on the render loop and stream submission.
nvidia-smiprocess and memory output.Browser WebRTC internals for decoded frame count.
Usual fixes:
Repair stage-loading inline/session data before tuning quality settings.
Set
OVRTX_BIN_PATHand put ovrtx plugin libraries first.Copy mapped render vars before leaving the step context, and never reuse frame views across steps.
Restart the Python process after native-library or import-order changes.
Kill stale render PIDs before relaunching.
Scene Will Not Load
Check first:
The requested path exists from the server process, not just from the browser.
Asset root, allowed schemes, cache path, and user-provided path validation agree.
Inline root sublayer paths resolve from the server process and preserve relative asset resolution.
The viewer creates Camera -> RenderProduct -> RenderVar -> RenderSettings data for every load.
reset_stage()andopen_usd*()do not run concurrently withrenderer.step().
Logs to inspect:
openStageRequestURL and resolved server path.pxr stage-open or worker errors.
ovrtx stage load and RenderProduct errors.
Missing texture, sublayer, and asset resolver warnings.
Usual fixes:
Resolve paths on the server and send clear
openStageResulterrors to the frontend.Keep generated inline/session content stable until the load operation completes and a valid frame is produced.
Rebuild session render prims after every reset.
Write wrapper files near the source asset or preserve directory structure in the cache.
Camera Does Not Move
Check first:
In WebRTC streaming, camera input is handled from NVST/ovstream
InputEventcallbacks, not JSON.In SHM streaming, camera input must use
ovstream.ShmClient.send_input_event()from Python, orovstream_shm_client_send_input_event()from C, not JSONmouseInput.In in-process apps, camera input should call the Python/C++ camera APIs directly.
Mouse coordinates are converted through the rendered image rect, including letterboxing.
The camera path used by controls is the same path referenced by the RenderProduct.
Live transform writes target
omni:xform, not authoredxformOp:*.Writes use the correct transform semantic and create attributes that may not already exist.
Orbit/pan/zoom state remains finite after scene switch or camera restore.
Logs to inspect:
Input callback event type, button/wheel state, and coordinates.
Camera controller target, distance, azimuth/elevation, and matrix values.
Renderer write errors or silent skipped writes.
Usual fixes:
Route input events to a render-thread command queue.
Write
omni:xformwith create-new prim mode for viewer camera updates.Refit the camera to stage bounds after invalid restore state.
Keep drag threshold logic from turning every click into a camera move or every drag into a selection.
Picking Does Not Work
Check first:
The native pick query was enqueued for the same RenderProduct that is stepped next.
The next frame contains the synthetic
ovrtx_pick_hitrender var and its params pass validation.Picked
primPathids are resolved through the renderer path dictionary before publishing UI state.Pixel coordinates are render pixels, not full DOM/widget pixels when letterboxed.
Pending pick state and selectable path sets are cleared after scene reset.
Tree selection expands Xform/Scope paths to descendant mesh paths for highlight feedback.
Logs to inspect:
Pick click coordinates before and after viewport-to-render mapping.
Pick-hit params and resolved prim paths.
Selected prim path, mesh expansion result, and
stageSelectionChangedpayload.
Usual fixes:
Pin the picking RenderProduct to CUDA-visible GPU 0 when required by the active ovrtx build.
Use
renderer.query_primsor native pickability APIs to refresh selectable paths after scene switches.Avoid selecting on left-button release if the drag threshold was exceeded.
Hierarchy, Prim Info, And Variants
Check first:
Direct
pxrimports follow the process import discipline, or USD queries run in a subprocess worker.Worker protocol is one JSON object per line and logs go to stderr, not stdout.
USD values are serialized into JSON-safe primitives before sending to React.
Frontend route names match the active protocol:
getChildrenResult,getPropertiesResponse,getVariantsResponse.Variant changes refresh children, properties, selection expansion, pickability filters, and selected paths that may have changed.
Logs to inspect:
Worker request and response IDs.
Frontend custom-event router output.
Serialization failures for large arrays, matrices, asset paths, or unknown pxr values.
Usual fixes:
Move pxr queries into a worker on Windows or when USD registry conflicts appear.
Cap large arrays in property payloads.
Re-query affected subtree and selected prim info after variant edits.
Scene Switching And Persistent State
Check first:
Scene switch clears selection, info panel, hierarchy cache, pending pick state, animation bindings, and native selection outline state before the new load.
Settings are stored in app JSON and reapplied after each load, not authored into user USD files.
Native selection outline groups are cleared after every stage load when selection feedback is present.
Scene switches should reuse the configured fixed stream/render resolution. For local Omniverse Realtime Viewers or explicit startup configuration changes, rebuild derived buffers, letterbox math, and pick coordinate mapping together.
Logs to inspect:
Stage lifecycle state: idle, loading, streaming, error, shutting down.
Active settings snapshot before and after load.
Concurrent render-step and reset attempts.
Usual fixes:
Serialize stage mutation through the render thread.
Rebuild all derived state after
reset_stage().Send fresh initial state to reconnecting clients.
Frontend Diagnostics
Use these browser tools:
Console: AppStreamer errors, JSON parse failures, unhandled custom events, media element errors, React state warnings.
Network tab: signaling request, WebSocket upgrade, failed CORS/proxy requests, and any
POST /sign_in501 response that indicates the wrong standalone ovstream Direct client profile.chrome://webrtc-internalsoredge://webrtc-internals: ICE candidate pair, connection state, bytes received, frames decoded, frame size, frame rate.React DevTools: connection status, current scene URL, selected prim, hierarchy cache, settings state.
What to look for:
Connected state but zero decoded frames points at stream submission or media negotiation.
Decoded frames increasing but black video points at renderer or scene setup.
Custom events arriving but UI unchanged points at frontend reducer/state wiring.
No custom events arriving points at data-channel send/receive, envelope unwrapping, or server send guard.
Recovery Patterns
Restart the Python server when:
Environment variables, dynamic library paths, import order, ovstream native libraries, or ovrtx plugin paths changed.
The renderer crashed, hung, or left stale GPU memory in
nvidia-smi.Callback registration order or WebRTC server configuration changed.
Fixed stream resolution configuration, codec, or native frame buffer allocation changed.
Restart or reconnect the browser when:
AppStreamer config changed.
A previous WebRTC session is stuck.
The video element or frontend connection provider was rebuilt.
Fix code before restarting repeatedly when:
Event names do not match.
Renderer stage mutation races with
renderer.step().Scene wrappers are written to paths that break relative asset resolution.
Camera writes target
xformOp:*instead ofomni:xform.Picking uses DOM coordinates or
[x, y]buffer indexing.
Requirements and compatibility
Written for: OpenAI Codex
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.
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
- OpenAI (Official)
- Distributed by
- OpenAI
- Source
- openai/plugins · plugins/nvidia/skills/omniverse-realtime-viewer · commit d420d13
- Licence
- Apache License 2.0 (redistribution allowed)
- LICENSE (written by AutoGineer)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by NVIDIA Omniverse or OpenAI.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download omniverse-realtime-viewer.zip