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/cae-cfd-visualization/usd-authoring-and-materials.md
<!-- SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -->
<!-- SPDX-License-Identifier: Apache-2.0 -->
CAE/CFD USD Authoring And Materials
Triggers
Use this reference when turning CAE/CFD operator output (a surface, iso-surface,
slice, point cloud, or streamlines plus a scalar field) into a renderable,
colored USD prim for an ovrtx viewer: composing the viewer-root USDA,
authoring UsdGeomMesh/UsdGeomPoints/UsdGeomBasisCurves geometry, baking a
colormap into primvars:displayColor, wiring a UsdPreviewSurface, and adding
the lights the path tracer needs. Read references/conventions.md and
references/ovrtx-rendering/README.md first for the render loop and import
order.
This document covers exactly one step: operator output (points + a field) → a
renderable, colored USD prim inside a composed viewer stage. It does not cover
solving, meshing, or field extraction; those produce the points,
faceVertexCounts/faceVertexIndices (or curveVertexCounts), and per-vertex
scalar field this document consumes.
Author The Viewer USDA As A Text String
Compose the whole viewer-root stage as a USDA text string and hand it to
OVStage with population.open_usd_from_string(stage, usda, ordinal=N, domains=PopulationDomain.RENDERING). Do not import pxr / usd-core in the
render process to build the stage in memory. Mixing usd-core with the ovrtx
bundled USD in the wrong order causes duplicate-symbol crashes and MDL resolver
failures (see references/ovrtx-rendering/README.md import-order notes). Text
authoring keeps this process pxr-free and lets OVStage own composition and
population.
Implement a small application-owned USDA builder from numpy arrays. Keep it pxr-free and split it into block builders for the session header, render/camera, lights/materials, and each geometry prim. Its structure, top to bottom under one session scope:
/Session (Scope, defaultPrim, upAxis="Y")
Cameras/Main UsdGeomCamera (resolution-derived aperture, xform)
Render/Viewport RenderProduct (uniform int2 resolution)
Render/Vars/LdrColor RenderVar (sourceName="LdrColor")
Render/Settings RenderSettings
Lights/Dome, Lights/Key DomeLight + DistantLight
Looks/FieldMat Material (UsdPreviewSurface + PrimvarReader)
Geometry/<prim> Mesh | Points | BasisCurves (+ displayColor primvar)Header and root scope:
#usda 1.0
(
defaultPrim = "Session"
doc = "cae viewer root (colormap=viridis, field=Pressure)"
upAxis = "Y"
)
def Scope "Session"
{
# ... camera, render, lights, looks, geometry blocks ...
}Camera And Render Blocks
The RenderProduct resolution is viewer-owned and must be set in this composed
layer before the stage loads; the RenderProduct path is the same path passed to
renderer.step(render_products={...}). Keep it fixed for the session (typically
1920x1080 for streaming). Camera matrices are row-major with translation in row
3 (right, up, -forward, eye).
def Xform "Cameras"
{
def Camera "Main"
{
float2 clippingRange = (0.1, 100000)
float focalLength = 24
float horizontalAperture = 20.955
float verticalAperture = 11.7872
matrix4d xformOp:transform = ( (1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1) )
uniform token[] xformOpOrder = ["xformOp:transform"]
}
}
def Scope "Render"
{
def RenderProduct "Viewport"
{
rel camera = </Session/Cameras/Main>
uniform int2 resolution = (1920, 1080)
rel orderedVars = [ </Session/Render/Vars/LdrColor> ]
}
def Scope "Vars"
{
def RenderVar "LdrColor"
{
string sourceName = "LdrColor"
token sourceType = "raw"
}
}
def RenderSettings "Settings"
{
rel products = [ </Session/Render/Viewport> ]
rel camera = </Session/Cameras/Main>
uniform int2 resolution = (1920, 1080)
}
}Request only LdrColor for a basic viewer. verticalAperture is derived from
horizontalAperture * height / width so pixels stay square.
Geometry Prims By Representation
Pick the prim type from the operator representation:
| Representation | USD prim |
|---|---|
| external faces / iso-surface / slice | UsdGeomMesh |
| point cloud | UsdGeomPoints |
| streamlines | UsdGeomBasisCurves |
All three carry the same two field primvars (see next section):
primvars:displayColor (baked color) and primvars:<field> (raw scalar).
Surface / Iso / Slice — UsdGeomMesh
def Xform "Geometry"
{
def Mesh "Surface"
{
point3f[] points = [ (0, 0, 0), (1, 0, 0), (1, 1, 0), (0, 1, 0) ]
int[] faceVertexCounts = [ 3, 3 ]
int[] faceVertexIndices = [ 0, 1, 2, 0, 2, 3 ]
uniform token subdivisionScheme = "none"
rel material:binding = </Session/Looks/FieldMat>
float[] primvars:Pressure = [ 0.1, 0.4, 0.9, 0.5 ] (interpolation = "vertex")
color3f[] primvars:displayColor = [ (0.27, 0, 0.33), (0.16, 0.47, 0.56), (0.99, 0.9, 0.14), (0.13, 0.57, 0.55) ] (interpolation = "vertex")
}
}subdivisionScheme = "none" renders the authored triangles/polygons directly
(no Catmull-Clark). faceVertexCounts is one count per face (3 per triangle);
faceVertexIndices indexes into points. In the app's USD-authoring module,
map NODE-associated fields to vertex interpolation (one value per output
point) and ELEMENT/cell fields to uniform (one value per output face).
When an operator changes topology, use its output field association and count;
do not attach the original cell array to a triangulated or extracted mesh
without remapping it to the output faces. See
data-and-operators.md for the geometry/field handoff.
Point Cloud — UsdGeomPoints
Use when the dataset has points and fields but no cells. widths is per-point
(world units); estimate it from the bbox diagonal over sqrt(N) when the
operator does not supply one.
def Points "Surface"
{
point3f[] points = [ (0, 0, 0), (1, 0, 0), (1, 1, 0) ]
float[] widths = [ 0.02, 0.02, 0.02 ]
rel material:binding = </Session/Looks/FieldMat>
float[] primvars:Pressure = [ 0.1, 0.4, 0.9 ] (interpolation = "vertex")
color3f[] primvars:displayColor = [ (0.27, 0, 0.33), (0.16, 0.47, 0.56), (0.99, 0.9, 0.14) ] (interpolation = "vertex")
}Streamlines — UsdGeomBasisCurves
type = "linear" gives polyline curves. curveVertexCounts is the vertex count
per curve; points is the concatenation of all curve vertices in order.
widths is per-vertex here (interpolation = "vertex").
def BasisCurves "Streamlines"
{
uniform token type = "linear"
int[] curveVertexCounts = [ 3, 2 ]
point3f[] points = [ (0,0,0), (1,0,0), (2,0,0), (0,1,0), (1,1,0) ]
float[] widths = [ 0.02, 0.02, 0.02, 0.02, 0.02 ] (interpolation = "vertex")
rel material:binding = </Session/Looks/FieldMat>
float[] primvars:Pressure = [ 0.1, 0.4, 0.9, 0.2, 0.6 ] (interpolation = "vertex")
color3f[] primvars:displayColor = [ (0.27,0,0.33), (0.16,0.47,0.56), (0.99,0.9,0.14), (0.28,0.14,0.46), (0.13,0.57,0.55) ] (interpolation = "vertex")
}Field → Color: Bake A Colormap LUT
The simplest guaranteed-to-render color path is to bake the colormap into
per-vertex color and let a UsdPreviewSurface read it. Two things are
authored per prim:
color3f[] primvars:displayColor (interpolation = "vertex")— the baked RGB.float[] primvars:<field> (interpolation = "vertex")— the raw scalar, kept so downstream tools (legends, thresholds, re-coloring, probing) still have the physical values.
Implement the colormap in the generated app. Store a small RGB control-point table for each supported name, interpolate it to a 256-entry LUT, then normalize and index it:
import numpy as np
def apply_lut(values, vmin, vmax, lut):
values = np.asarray(values, dtype=np.float32)
if not np.isfinite(vmax) or not np.isfinite(vmin) or vmax <= vmin:
return np.full((values.size, 3), 0.5, dtype=np.float32)
unit = np.nan_to_num((values - vmin) / (vmax - vmin), nan=0.0, posinf=1.0, neginf=0.0)
index = np.rint(np.clip(unit, 0.0, 1.0) * (len(lut) - 1)).astype(np.intp)
return np.asarray(lut, dtype=np.float32)[index, :3]
# `lut` is a generated `(256, 3)` float32 table for the selected named colormap.
colors = apply_lut(surface.field_values, *surface.field_range, lut)Use viridis as the default and document any additional maps that the app ships. Preserve raw
field values alongside the RGB result so legends, thresholds, and recoloring remain possible.
The (N,3) colors array becomes the primvars:displayColor values and the
raw surface.field_values becomes primvars:<field>.
Material And Lights
UsdPreviewSurface Reading displayColor
Author one Material under Looks whose surface shader's diffuse input is
connected to a UsdPrimvarReader_float3 that reads the displayColor
primvar. Bind it on each geometry prim with rel material:binding.
def Scope "Looks"
{
def Material "FieldMat"
{
token outputs:surface.connect = </Session/Looks/FieldMat/Surface.outputs:surface>
def Shader "Surface"
{
uniform token info:id = "UsdPreviewSurface"
color3f inputs:diffuseColor.connect = </Session/Looks/FieldMat/PvReader.outputs:result>
color3f inputs:emissiveColor = (0, 0, 0)
float inputs:roughness = 0.65
float inputs:metallic = 0
token outputs:surface
}
def Shader "PvReader"
{
uniform token info:id = "UsdPrimvarReader_float3"
string inputs:varname = "displayColor"
float3 inputs:fallback = (0.55, 0.55, 0.55)
float3 outputs:result
}
}
}The example authoring code also drives emissiveColor at low weight from the same
reader as insurance so the colormap stays visible under weak lighting, while
diffuse still gives lit shading form; plain emissiveColor = (0,0,0) with real
lights is the baseline shown above.
Lights — CRITICAL GOTCHA
A path tracer renders unlit diffuse geometry BLACK. A UsdPreviewSurface
with only a diffuse color contributes nothing until light hits it, so a scene
with no light produces a black frame that looks like a broken render. You MUST
author at least one light. Use a DomeLight (soft fill so the whole surface is
lit) plus a DistantLight (key, for shading form):
def Scope "Lights"
{
def DomeLight "Dome"
{
float inputs:intensity = 550
float inputs:exposure = 0
color3f inputs:color = (1, 1, 1)
}
def DistantLight "Key"
{
float inputs:intensity = 3000
float inputs:angle = 1.5
double3 xformOp:rotateXYZ = (-45, 25, 0)
uniform token[] xformOpOrder = ["xformOp:rotateXYZ"]
}
}If a rendered CAE frame is black despite valid geometry and colors, check for a missing light before anything else.
Beauty-Grade Fidelity: MDL Materials + HDRI Lighting
The baked-displayColor + UsdPreviewSurface path above is the right choice for
the CAE scalar field itself — the streamlines/iso/slice/point-cloud geometry
whose color is the data. For those prims the color must map the field faithfully
and must not be reshaped by a physically-based lighting response, so keep them
on the baked path.
A realtime CAE viewer often also carries non-data "beauty" geometry in the same
frame: the car body under the streamlines, a wind-tunnel floor, chrome trim, a glass
canopy. Those surfaces should look physically real — reflect the environment, show
clearcoat and metallic flake — not read as a flat lit color. ovrtx has full
USD/MDL support and bundles a large MDL material library, so bind a real MDL
material to that geometry while the scientific field stays on the colormap path.
The two coexist in one stage: bake displayColor for the field, bind MDL for the
props. This section is the fidelity upgrade layered on top of the baseline above.
MDL Materials Via UsdShade
MDL resolution depends on OVRTX_BIN_PATH pointing at ovrtx/bin (the bundled MDL
library lives under ovrtx/bin/library/mdl/). Without it, MDL surfaces render
magenta — this is the single most common MDL failure. See the MDL resolution and
magenta-material rows in references/ovrtx-rendering/README.md; that document owns
the OVRTX_BIN_PATH / LD_LIBRARY_PATH / import-order rules and this reference does
not repeat them.
An MDL material is authored with UsdShade, but its wiring differs from the
UsdPreviewSurface block above: the surface output is outputs:mdl:surface (not
outputs:surface), the shader's info:implementationSource is "sourceAsset", the
.mdl module is named by info:mdl:sourceAsset, and the specific material inside
that module is selected by info:mdl:sourceAsset:subIdentifier:
def Material "CarMat"
{
token outputs:mdl:surface.connect = </Session/Looks/CarMat/S.outputs:out>
def Shader "S"
{
uniform token info:implementationSource = "sourceAsset"
uniform asset info:mdl:sourceAsset = @OmniSurfacePresets.mdl@
uniform token info:mdl:sourceAsset:subIdentifier = "OmniSurface_CarPaintMetallic"
token outputs:out
}
}Useful bundled modules and their subIdentifier materials (any MDL in the library
works — these are convenient beauty presets):
.mdl module | subIdentifier (material) | Use |
|---|---|---|
OmniSurfacePresets.mdl | OmniSurface_CarPaint | flat automotive paint |
OmniSurfacePresets.mdl | OmniSurface_CarPaintMetallic | metallic-flake car paint |
OmniSurfacePresets.mdl | OmniSurface_TwoToneCarPaint | flip/two-tone paint |
OmniSurfacePresets.mdl | OmniSurface_GlossyPaint | glossy non-metallic paint |
OmniSurfacePresets.mdl | Chrome | polished chrome trim |
OmniPBR_ClearCoat.mdl | (module material) | clearcoat over a PBR base |
OmniSurface.mdl / OmniPBR.mdl | (general) | general PBR body / props |
OmniGlass.mdl | (general) | glass canopy / transparent parts |
Bind the material with MaterialBindingAPI + rel material:binding, exactly like
the field material. The key rule when mixing bound and inherited materials:
A
material:bindingauthored on a prim overrides a binding inherited from an ancestor Xform or reference container.
So the streamlines/field prims inherit FieldMat from the /Session/Geometry
container (no binding of their own), while the car mesh carries its own
rel material:binding = </Session/Looks/CarMat> and overrides that inherited
colormap material for just that prim:
def Mesh "Car"
{
# ... points / faceVertexCounts / faceVertexIndices / normals ...
uniform token subdivisionScheme = "none"
rel material:binding = </Session/Looks/CarMat>
}When to use which: MDL for beauty surfaces (car body, floor, chrome, glass) that
should reflect the environment and read as physical materials; the baked
displayColor colormap for the CAE scalar field (streamlines/iso/slice/points),
where the color encodes the data and must survive unchanged.
HDRI DomeLight For Real Reflections
A plain color3f DomeLight lights the scene, but it gives a metallic or clearcoat
surface nothing to reflect — the car paint looks flat and dead, defeating the
MDL upgrade. Load an equirectangular HDRI into the DomeLight so reflective MDL
materials mirror a real environment. For metallic/clearcoat/glass this is the single
biggest fidelity jump in the whole scene — without it the reflective lobe has no
content:
def DomeLight "Env"
{
float inputs:intensity = 900
asset inputs:texture:file = @environment.hdr@ # app-supplied asset URI
token inputs:texture:format = "latlong"
double3 xformOp:rotateXYZ = (-90, 0, 0)
uniform token[] xformOpOrder = ["xformOp:rotateXYZ"]
}Use an application-supplied or user-selected equirectangular .hdr/.exr asset URI.
Do not rely on a package-layout-dependent bundled texture path.
CRITICAL — orient the HDRI to the scene's up axis. A latlong (equirectangular)
HDRI wraps around a specific up axis; loaded raw it can arrive rolled 90°, so
reflections and the horizon come from the wrong direction (e.g. the "ground" of the
environment appears overhead). The DomeLight needs a rotation to level the horizon
for the scene's up axis. For the Y-up viewer scene used throughout this
reference, double3 xformOp:rotateXYZ = (-90, 0, 0) levels it (this is a suitable starting value for Y-up scenes). Match the rotation to
whichever up axis your geometry uses — see coordinate-systems-and-up-axis.md for the
Z-up vs Y-up handling; the dome rotation must track the same up-axis choice
as the geometry, or the reflected world and the model disagree.
Smooth Normals For Imported Meshes
Imported CAE/prop surfaces are usually faceted — an STL, or a vertex-clustered decimation, ships triangles with no authored normals. The path tracer then shades each triangle flat, and MDL car paint reads visibly low-poly: every facet edge catches a different highlight. Author computed area-weighted vertex normals so the faceted body shades as one smooth surface. Each vertex normal is the (area-weighted) sum of its incident face normals, normalized, authored per vertex:
def Mesh "Car"
{
point3f[] points = [ ... ]
int[] faceVertexCounts = [ 3, 3, ... ]
int[] faceVertexIndices = [ ... ]
normal3f[] normals = [ (0, 1, 0), ... ] (interpolation = "vertex")
uniform token subdivisionScheme = "none"
rel material:binding = </Session/Looks/CarMat>
}Compute face normals with a cross product, accumulate them onto each vertex, then normalize. If you also rotate the mesh between up axes (a Z-up STL into a Y-up scene), rotate the normals with the same rotation — a pure rotation maps points and direction vectors identically, so the smooth shading survives the reorientation.
Curve Widths: Prefer Constant Interpolation For Live Geometry
The streamlines example earlier authors per-vertex widths
(interpolation = "vertex"), which is fine for a static curve set. But when the
streamlines are updated live via the data plane — an emitter move recomputes the
curves and the total point count changes — a per-vertex widths array goes stale the
instant the point count changes: its length no longer matches points, so the write
fails or renders wrong. Prefer constant interpolation (one width for the whole
prim) so a point-count change never invalidates the widths array:
def BasisCurves "Streamlines"
{
uniform token type = "linear"
int[] curveVertexCounts = [ ... ]
point3f[] points = [ ... ]
float[] widths = [ 0.02 ] (interpolation = "constant")
color3f[] primvars:displayColor = [ ... ] (interpolation = "vertex")
}displayColor stays per-vertex (it is the field, one color per point). Only
widths moves to constant. See the live data-plane array-write path in
driving-cae-viz-via-ovstage.md, which rewrites points /
curveVertexCounts / primvars:displayColor in place as the emitter moves — a
constant widths is what lets that fast path skip re-authoring the curve every move.
USDA Authoring Gotchas
These are common USDA parser constraints:
Attribute metadata goes AFTER the value. Interpolation is trailing metadata:
float[] primvars:x = [ ... ] (interpolation = "vertex"), not before the attribute. Same for other primvar metadata.Use multi-line brace bodies. Compact one-line prim bodies can trip the parser. Author each prim with
{and}on their own lines and one attribute per line. Long arrays wrap across lines (the example authoring code wraps ~6 elements per line for readability and parser safety).float2 clippingRange = (0.1, 100000)— author the camera clipping range as afloat2tuple. A far plane large enough to contain CAE bounds avoids clipped geometry.matrix4d xformOp:transformis row-major with translation in row 3 (M[0]=right, M[1]=up, M[2]=-forward, M[3]=eye), matching the viewer camera convention inreferences/conventions.md.Numeric literals should be finite; substitute
0.0for any NaN/inf, and emit compact but valid floats (e.g.%.6g).
Supported Colormap Boundary
This package supports the baked displayColor path above. Do not depend on applied schemas, dynamic texture services, or undocumented MDL LUT conventions for a generated app.
If the requested result requires a dynamic opacity transfer function or a runtime-managed texture
LUT, describe that as an unsupported extension rather than implying it is available here.
See also: references/conventions.md, references/ovrtx-rendering/README.md,
references/ovstage-population/README.md, references/render-settings/README.md,
references/usd-sample-data/README.md.
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