Visualization#
Isaac Lab provides 5 visualizers for real-time simulation inspection and debugging. Where renderers produce sensor data for training, visualizers give fast, lightweight feedback for human monitoring and recording. Visualizers can also stream that same sensor data through the streaming camera panel.
This page covers:
Quick Start: launch a visualizer with
--vizVisualizer Overview: each visualizer in its own section
Shared Features: what’s common across visualizers
Usage: common CLI and config recipes
Limitations: per-visualizer differences and troubleshooting
5 visualizers running Isaac-Velocity-Flat-AnymalD with a circular velocity command
Green arrow: commanded velocity. Blue arrow: current velocity.
Note: Newton RTX has no velocity arrows, since it doesn't yet support visualization markers.
Quick Start#
Pass --viz to any train command to launch a visualizer. --visualizer is an equivalent
alias.
# Newton GL: lightweight OpenGL viewport
uv run isaaclab train --rl_library rsl_rl --task Isaac-Cartpole --viz newton_gl
# Viser: browser-based viewer
uv run isaaclab train --rl_library rsl_rl --task Isaac-Cartpole --viz viser
# Kit viewport
uv run isaaclab train --rl_library rsl_rl --task Isaac-Cartpole --viz kit
# Multiple visualizers simultaneously (comma-separated, no spaces)
uv run isaaclab train --rl_library rsl_rl --task Isaac-Cartpole --viz rerun,newton_rtx
./isaaclab.sh train --rl_library rsl_rl --task Isaac-Cartpole --viz newton_gl
./isaaclab.sh train --rl_library rsl_rl --task Isaac-Cartpole --viz viser
./isaaclab.sh train --rl_library rsl_rl --task Isaac-Cartpole --viz kit
./isaaclab.sh train --rl_library rsl_rl --task Isaac-Cartpole --viz rerun,newton_rtx
Note
Most tasks default to a PhysX backend, which requires Isaac Sim. If it isn’t installed yet,
add --extra isaacsim to the uv run commands above; see
Optional extras for details.
For combining visualizers, running headless, and other common use cases, see Usage below.
Visualizer Overview#
Visualizer |
Description |
|---|---|
Newton GL |
Lightweight, strong feature support; Recommended |
Viser |
Web-based, supports recording and replay; Recommended |
Newton RTX |
High-quality RTX rendering; experimental, missing some features |
Rerun |
Web-based, supports recording and replay; limited UI toggles |
Kit |
High-quality RTX rendering, rich Isaac Sim tooling; longer start-up time |
The Newton GL visualizer is a lightweight OpenGL window with minimal startup overhead.
Isaac-Reorient-Cube-Allegro in Newton GL Visualizer
Each Allegro hand reorients
its cube to match the target shown by the marker above it
Visualizer-specific features:
Pause Rendering, Pause Simulation, and Reset Episode ImGui controls
Rigid-body dragging via right-click, see right (Newton solvers only)
Adjustable render update frequency
newton_viewer_dominoes demo
Right-click dragging the first domino
triggers the cascade across an NVIDIA-logo domino layout
Core configuration:
from isaaclab_visualizers.newton import NewtonGLVisualizerCfg
visualizer_cfg = NewtonGLVisualizerCfg(
eye=(8.0, 8.0, 3.0),
lookat=(0.0, 0.0, 0.0),
window_width=1920,
window_height=1080,
show_joints=False,
show_contacts=False,
enable_live_plots=True,
)
For the full config reference, see the config classes below.
NewtonGLVisualizerCfg source
@configclass
class NewtonGLVisualizerCfg(NewtonVisualizerCfg):
"""Configuration for the Newton OpenGL rasterizer visualizer.
Selects Newton's OpenGL backend — fast local window with the full Isaac Lab
feature set: streaming camera panel, particle color override, and live scalar/array plots.
The streaming camera panel is enabled by default (``streaming_view=True``) but starts
hidden — no camera rendering work is performed until the user opens the panel via the
sidebar combo, keeping per-step overhead zero when the panel is closed.
"""
class_type: type[NewtonGLVisualizer] | str = "{DIR}.newton_visualizer:NewtonGLVisualizer"
"""Visualizer implementation class."""
visualizer_type: str = "newton_gl"
"""Visualizer selector identifier. Do not change."""
streaming_view: bool = True
"""Enable the tiled streaming camera panel.
Overrides the base-class default of ``False``. The panel starts **hidden** so there
is no per-step camera rendering cost; the user can open it at any time via the
*Streaming View* combo in the Newton sidebar.
"""
NewtonVisualizerCfg source (shared Newton base class)
@configclass
class NewtonVisualizerCfg(VisualizerCfg):
"""Shared configuration base for Newton visualizer backends.
.. deprecated::
:class:`NewtonVisualizerCfg` is deprecated. Use :class:`NewtonGLVisualizerCfg` for the
OpenGL rasterizer or :class:`NewtonRTXVisualizerCfg` for the OVRTX path tracer.
"""
class_type: type[NewtonGLVisualizer] | str = "{DIR}.newton_visualizer:NewtonGLVisualizer"
"""Deprecated alias for the Newton GL visualizer implementation."""
# Deprecated alias: "newton" routes to the GL backend via simulation_context._VISUALIZER_ALIASES.
visualizer_type: str = "newton_gl"
def __post_init__(self):
if type(self) is NewtonVisualizerCfg:
warnings.warn(
"NewtonVisualizerCfg is deprecated and will be removed in a future release. "
"Use NewtonGLVisualizerCfg (OpenGL rasterizer) or NewtonRTXVisualizerCfg (OVRTX path tracer) instead.",
DeprecationWarning,
stacklevel=3,
)
window_width: int = 1920
"""Window width in pixels."""
window_height: int = 1080
"""Window height in pixels."""
headless: bool = False
"""Run the Newton viewer without requiring a display server."""
update_frequency: int = 1
"""Visualizer update frequency (renders every N simulation frames)."""
world_spacing: tuple[float, float, float] = (0.0, 0.0, 0.0)
"""Visual spacing between simulation worlds along each axis [m].
Non-zero axes arrange visible worlds in a compact grid without changing their simulated poses.
"""
show_joints: bool = False
"""Show joint visualization."""
show_contacts: bool = False
"""Show contact visualization."""
show_collision: bool = False
"""Show collision visualization."""
show_springs: bool = False
"""Show spring visualization."""
show_inertia_boxes: bool = False
"""Show inertia box visualization."""
show_com: bool = False
"""Show center of mass visualization."""
show_particles: bool = False
"""Show particle visualization."""
particle_color: tuple[float, float, float] | None = None
"""Optional particle color RGB [0, 1]. Uses Newton viewer defaults when ``None``."""
enable_picking: bool = True
"""Enable right-click dragging with Newton rigid-body solvers.
Supported coupled solvers may expose dragging through a rigid-body entry.
Disabled automatically for headless viewers, standalone MPM, and non-Newton
physics. MPM particles are not pickable.
"""
enable_shadows: bool = True
"""Enable shadow rendering."""
enable_sky: bool = True
"""Enable sky rendering."""
enable_wireframe: bool = False
"""Enable wireframe rendering."""
sky_upper_color: tuple[float, float, float] = (0.2, 0.4, 0.6)
"""Sky upper color RGB [0, 1]."""
sky_lower_color: tuple[float, float, float] = (0.5, 0.6, 0.7)
"""Sky lower color RGB [0, 1]."""
light_color: tuple[float, float, float] = (1.0, 1.0, 1.0)
"""Light color RGB [0, 1]."""
VisualizerCfg source (shared base class)
@configclass
class VisualizerCfg:
"""Base configuration for all visualizer backends.
Note:
This is an abstract base class and should not be instantiated directly.
Use specific configs from isaaclab_visualizers: KitVisualizerCfg, NewtonGLVisualizerCfg,
RerunVisualizerCfg, or ViserVisualizerCfg (from isaaclab_visualizers.kit/.newton/.rerun/.viser).
"""
class_type: type[BaseVisualizer] | str | None = None
"""Visualizer implementation class. Concrete configs must set this field."""
# Primary interactive camera settings
eye: tuple[float, float, float] = (4.0, -4.0, 3.0)
"""Interactive visualizer camera eye position in world coordinates."""
lookat: tuple[float, float, float] = (0.0, 0.0, 0.0)
"""Interactive visualizer camera look-at target in world coordinates."""
focal_length: float = 12.0
"""Camera focal length in millimeters for visualizer camera views."""
# ── Streaming view ────────────────────────────────────────────────────────
# Captures pixels from a camera sensor (existing or auto-created), tiles them
# across envs and GT types, and shows the result as an image panel in interactive
# visualizers (Newton GL, Kit) or pushes it per-step to sink-based ones (Rerun, Viser).
streaming_view: bool = False
"""Enable the streaming camera image view (opt-in, disabled by default)."""
# Source — existing sensor (takes priority when set)
streaming_sensor_prim_path: str | None = None
"""Prim path of an existing TiledCamera sensor to stream from.
When set, all ``streaming_cam_*`` fields are ignored. Should point to an
existing camera sensor, e.g. ``"/World/envs/*/Camera"``.
"""
# Source — auto-created camera (used when streaming_sensor_prim_path is None)
streaming_cam_target_prim_path: str | None = None
"""Target prim for the auto-created streaming camera (ignored when
:attr:`streaming_sensor_prim_path` is set).
When ``None`` (the default), the visualizer adopts the first scene camera
sensor it discovers dynamically at initialization time. If no scene camera
exists the streaming panel remains empty. Set this explicitly (e.g.
``"/World/envs/*/Robot"``) only when you need an auto-created follow-camera
and no suitable scene camera is present.
"""
streaming_cam_eye: tuple[float, float, float] = (4.0, -4.0, 3.0)
"""Eye offset [m] for the auto-created streaming camera relative to the target prim."""
streaming_cam_renderer: str | None = None
"""Renderer for the auto-created streaming camera.
One of ``"newton_warp"``, ``"ovrtx"``, or ``None`` (let each backend
choose its own default). Defaults to ``None`` so each backend selects
an appropriate renderer automatically. Ignored when
:attr:`streaming_sensor_prim_path` is set.
"""
# Shared settings
streaming_envs: int | list[int] = 32
"""Environments to capture.
* ``int`` — sample this many envs once at initialization (from all visible envs).
* ``list[int]`` — capture exactly these env indices.
"""
streaming_gt_types: tuple[str, ...] = ("rgb",)
"""GT data types displayed left-to-right per environment row.
Valid values: ``"rgb"``, ``"depth"``, ``"segmentation"``, ``"normals"``.
Validated against :data:`~isaaclab.envs.utils.camera_colorizer.SUPPORTED_GT_TYPES`
at initialization time (only when :attr:`streaming_view` is ``True``).
"""
streaming_depth_min: float = 0.1
"""Near-clip for the turbo depth colormap [m]. Used when ``"depth"`` is in
:attr:`streaming_gt_types`."""
streaming_depth_max: float = 10.0
"""Far-clip for the turbo depth colormap [m]. Used when ``"depth"`` is in
:attr:`streaming_gt_types`."""
# Partial visualization settings
max_visible_envs: int | None = None
"""Upper bound on how many envs are shown.
* If visible_env_indices is not None, then this field will apply also
to the explicit env indices set to the visible_env_indices.
"""
visible_env_indices: list[int] | None = None
"""env indices to visualize in order (out-of-range indices are dropped)."""
randomly_sample_visible_envs: bool = True
"""If ``max_visible_envs`` is provided, when enabled, selected visible envs are randomly sampled.
If disabled, the first ``max_visible_envs`` envs are selected.
* Note: ``visible_env_indices`` overrides this field.
"""
# Visualization Markers
enable_markers: bool = True
"""Enable visualization markers (debug drawing)."""
# Live Plots
enable_live_plots: bool = True
"""Stream per-step scalar data (manager terms, episode reward, episode length) into the visualizer.
Plot windows start hidden or collapsed by default and can be toggled open at runtime.
Set to ``False`` to disable live plots entirely and avoid any collection overhead.
"""
live_plots_update_interval: int = 5
"""Collect and push live plot data every ``N`` simulation steps (default: every 5 steps)."""
# Internal
visualizer_type: str | None = None
"""Type identifier (e.g., 'newton', 'rerun', 'viser', 'kit'). Must be overridden by subclasses."""
# Deprecated aliases kept for one-release compatibility. Remove in the next major release.
tiled_cam_view: bool | None = None
"""Deprecated. Use :attr:`streaming_view` instead."""
tiled_cam_num: int | None = None
"""Deprecated. Use :attr:`streaming_envs` (int) instead."""
tiled_cam_env_indices: list[int] | None = None
"""Deprecated. Use :attr:`streaming_envs` (list[int]) instead."""
tiled_cam_prim_path: str | None = None
"""Deprecated. Use :attr:`streaming_sensor_prim_path` instead."""
tiled_cam_eye: tuple[float, float, float] | None = None
"""Deprecated. Use :attr:`streaming_cam_eye` instead."""
tiled_cam_target_prim_path: str | None = None
"""Deprecated. Use :attr:`streaming_cam_target_prim_path` instead."""
tiled_cam_renderer: str | None = None
"""Deprecated. Use :attr:`streaming_cam_renderer` instead."""
def __post_init__(self) -> None:
import warnings
_simple = [
("tiled_cam_view", "streaming_view"),
("tiled_cam_prim_path", "streaming_sensor_prim_path"),
("tiled_cam_eye", "streaming_cam_eye"),
("tiled_cam_target_prim_path", "streaming_cam_target_prim_path"),
("tiled_cam_renderer", "streaming_cam_renderer"),
]
for old, new in _simple:
val = getattr(self, old)
if val is not None:
warnings.warn(f"{old!r} is deprecated; use {new!r} instead.", DeprecationWarning, stacklevel=3)
setattr(self, new, val)
setattr(self, old, None)
# tiled_cam_env_indices takes priority over tiled_cam_num
env_indices = getattr(self, "tiled_cam_env_indices")
if env_indices is not None:
warnings.warn(
"'tiled_cam_env_indices' is deprecated; use 'streaming_envs' instead.",
DeprecationWarning,
stacklevel=3,
)
self.streaming_envs = env_indices
self.tiled_cam_env_indices = None
self.tiled_cam_num = None
else:
num = getattr(self, "tiled_cam_num")
if num is not None:
warnings.warn(
"'tiled_cam_num' is deprecated; use 'streaming_envs' instead.",
DeprecationWarning,
stacklevel=3,
)
self.streaming_envs = num
self.tiled_cam_num = None
Viser streams the Newton Warp renderer to a local web server,
at http://localhost:8080 by default, with optional public share URLs via share=True and
.viser recording files for replay.
Isaac-Lift-KukaAllegro in Viser Visualizer
Each Kuka arm and Allegro hand lifts
its cube off the table
Table color shows success: red until the cube reaches its target pose, green
once it does.
Visualizer-specific features:
Public share URL for remote access, set
share=TruePause Rendering, Pause Simulation, and Reset Episode sidebar controls
Important
A URL is printed before training begins. Set open_browser=True to open it
automatically. For remote access, set display_address to the machine hostname or IP
and ensure the configured port is reachable from the browser.
╭────── viser (listening *:8080) ───────╮
│ URL │ http://localhost:8080 │
╰───────────────────────────────────────╯
Core configuration:
from isaaclab_visualizers.viser import ViserVisualizerCfg
visualizer_cfg = ViserVisualizerCfg(
port=8080,
bind_address="0.0.0.0", # use 0.0.0.0 for remote access
display_address="localhost", # hostname shown in the printed URL
open_browser=False,
share=False, # request a public share URL
record_to_viser=None, # set a path to save a .viser recording
)
For the full config reference, see the config classes below.
ViserVisualizerCfg source
@configclass
class ViserVisualizerCfg(VisualizerCfg):
"""Configuration for Viser visualizer (web-based visualization)."""
class_type: type[ViserVisualizer] | str = "{DIR}.viser_visualizer:ViserVisualizer"
"""Visualizer implementation class."""
visualizer_type: str = "viser"
"""Type identifier for Viser visualizer."""
port: int = 8080
"""Port of the local viser web server."""
bind_address: str = "0.0.0.0"
"""Host/interface for the Viser server to bind.
Use ``"0.0.0.0"`` to listen on all interfaces for remote access.
"""
display_address: str = "localhost"
"""Host name or IP address shown in the printed browser URL.
For remote access, set this to the hostname/IP reachable from your browser.
"""
open_browser: bool = False
"""Whether to attempt opening the viser web viewer URL in a browser.
The viewer URL is always logged during initialization. Set this to ``True`` to auto-launch it.
"""
verbose: bool = True
"""Whether to print viewer server startup information."""
share: bool = False
"""Whether to request a public share URL from viser."""
record_to_viser: str | None = None
"""Path to save a .viser recording file. None = no recording."""
show_particles: bool = True
"""Whether to render particle systems (MPM, VBD) in the Viser viewer.
Defaults to ``True`` so particle simulations (granular, cloth, soft-body) are
visible on startup. Can also be toggled at runtime via the Visualization Markers
panel in the Viser sidebar.
"""
VisualizerCfg source (shared base class)
@configclass
class VisualizerCfg:
"""Base configuration for all visualizer backends.
Note:
This is an abstract base class and should not be instantiated directly.
Use specific configs from isaaclab_visualizers: KitVisualizerCfg, NewtonGLVisualizerCfg,
RerunVisualizerCfg, or ViserVisualizerCfg (from isaaclab_visualizers.kit/.newton/.rerun/.viser).
"""
class_type: type[BaseVisualizer] | str | None = None
"""Visualizer implementation class. Concrete configs must set this field."""
# Primary interactive camera settings
eye: tuple[float, float, float] = (4.0, -4.0, 3.0)
"""Interactive visualizer camera eye position in world coordinates."""
lookat: tuple[float, float, float] = (0.0, 0.0, 0.0)
"""Interactive visualizer camera look-at target in world coordinates."""
focal_length: float = 12.0
"""Camera focal length in millimeters for visualizer camera views."""
# ── Streaming view ────────────────────────────────────────────────────────
# Captures pixels from a camera sensor (existing or auto-created), tiles them
# across envs and GT types, and shows the result as an image panel in interactive
# visualizers (Newton GL, Kit) or pushes it per-step to sink-based ones (Rerun, Viser).
streaming_view: bool = False
"""Enable the streaming camera image view (opt-in, disabled by default)."""
# Source — existing sensor (takes priority when set)
streaming_sensor_prim_path: str | None = None
"""Prim path of an existing TiledCamera sensor to stream from.
When set, all ``streaming_cam_*`` fields are ignored. Should point to an
existing camera sensor, e.g. ``"/World/envs/*/Camera"``.
"""
# Source — auto-created camera (used when streaming_sensor_prim_path is None)
streaming_cam_target_prim_path: str | None = None
"""Target prim for the auto-created streaming camera (ignored when
:attr:`streaming_sensor_prim_path` is set).
When ``None`` (the default), the visualizer adopts the first scene camera
sensor it discovers dynamically at initialization time. If no scene camera
exists the streaming panel remains empty. Set this explicitly (e.g.
``"/World/envs/*/Robot"``) only when you need an auto-created follow-camera
and no suitable scene camera is present.
"""
streaming_cam_eye: tuple[float, float, float] = (4.0, -4.0, 3.0)
"""Eye offset [m] for the auto-created streaming camera relative to the target prim."""
streaming_cam_renderer: str | None = None
"""Renderer for the auto-created streaming camera.
One of ``"newton_warp"``, ``"ovrtx"``, or ``None`` (let each backend
choose its own default). Defaults to ``None`` so each backend selects
an appropriate renderer automatically. Ignored when
:attr:`streaming_sensor_prim_path` is set.
"""
# Shared settings
streaming_envs: int | list[int] = 32
"""Environments to capture.
* ``int`` — sample this many envs once at initialization (from all visible envs).
* ``list[int]`` — capture exactly these env indices.
"""
streaming_gt_types: tuple[str, ...] = ("rgb",)
"""GT data types displayed left-to-right per environment row.
Valid values: ``"rgb"``, ``"depth"``, ``"segmentation"``, ``"normals"``.
Validated against :data:`~isaaclab.envs.utils.camera_colorizer.SUPPORTED_GT_TYPES`
at initialization time (only when :attr:`streaming_view` is ``True``).
"""
streaming_depth_min: float = 0.1
"""Near-clip for the turbo depth colormap [m]. Used when ``"depth"`` is in
:attr:`streaming_gt_types`."""
streaming_depth_max: float = 10.0
"""Far-clip for the turbo depth colormap [m]. Used when ``"depth"`` is in
:attr:`streaming_gt_types`."""
# Partial visualization settings
max_visible_envs: int | None = None
"""Upper bound on how many envs are shown.
* If visible_env_indices is not None, then this field will apply also
to the explicit env indices set to the visible_env_indices.
"""
visible_env_indices: list[int] | None = None
"""env indices to visualize in order (out-of-range indices are dropped)."""
randomly_sample_visible_envs: bool = True
"""If ``max_visible_envs`` is provided, when enabled, selected visible envs are randomly sampled.
If disabled, the first ``max_visible_envs`` envs are selected.
* Note: ``visible_env_indices`` overrides this field.
"""
# Visualization Markers
enable_markers: bool = True
"""Enable visualization markers (debug drawing)."""
# Live Plots
enable_live_plots: bool = True
"""Stream per-step scalar data (manager terms, episode reward, episode length) into the visualizer.
Plot windows start hidden or collapsed by default and can be toggled open at runtime.
Set to ``False`` to disable live plots entirely and avoid any collection overhead.
"""
live_plots_update_interval: int = 5
"""Collect and push live plot data every ``N`` simulation steps (default: every 5 steps)."""
# Internal
visualizer_type: str | None = None
"""Type identifier (e.g., 'newton', 'rerun', 'viser', 'kit'). Must be overridden by subclasses."""
# Deprecated aliases kept for one-release compatibility. Remove in the next major release.
tiled_cam_view: bool | None = None
"""Deprecated. Use :attr:`streaming_view` instead."""
tiled_cam_num: int | None = None
"""Deprecated. Use :attr:`streaming_envs` (int) instead."""
tiled_cam_env_indices: list[int] | None = None
"""Deprecated. Use :attr:`streaming_envs` (list[int]) instead."""
tiled_cam_prim_path: str | None = None
"""Deprecated. Use :attr:`streaming_sensor_prim_path` instead."""
tiled_cam_eye: tuple[float, float, float] | None = None
"""Deprecated. Use :attr:`streaming_cam_eye` instead."""
tiled_cam_target_prim_path: str | None = None
"""Deprecated. Use :attr:`streaming_cam_target_prim_path` instead."""
tiled_cam_renderer: str | None = None
"""Deprecated. Use :attr:`streaming_cam_renderer` instead."""
def __post_init__(self) -> None:
import warnings
_simple = [
("tiled_cam_view", "streaming_view"),
("tiled_cam_prim_path", "streaming_sensor_prim_path"),
("tiled_cam_eye", "streaming_cam_eye"),
("tiled_cam_target_prim_path", "streaming_cam_target_prim_path"),
("tiled_cam_renderer", "streaming_cam_renderer"),
]
for old, new in _simple:
val = getattr(self, old)
if val is not None:
warnings.warn(f"{old!r} is deprecated; use {new!r} instead.", DeprecationWarning, stacklevel=3)
setattr(self, new, val)
setattr(self, old, None)
# tiled_cam_env_indices takes priority over tiled_cam_num
env_indices = getattr(self, "tiled_cam_env_indices")
if env_indices is not None:
warnings.warn(
"'tiled_cam_env_indices' is deprecated; use 'streaming_envs' instead.",
DeprecationWarning,
stacklevel=3,
)
self.streaming_envs = env_indices
self.tiled_cam_env_indices = None
self.tiled_cam_num = None
else:
num = getattr(self, "tiled_cam_num")
if num is not None:
warnings.warn(
"'tiled_cam_num' is deprecated; use 'streaming_envs' instead.",
DeprecationWarning,
stacklevel=3,
)
self.streaming_envs = num
self.tiled_cam_num = None
The experimental Newton RTX visualizer, launched with --viz newton_rtx, uses the
OVRTX path-tracer for photorealistic rendering without a Kit process. It is slightly
slower than the Newton GL visualizer due to the cost of high-quality RTX rendering.
Isaac-Velocity-Rough-H1 in Newton RTX Visualizer
Each H1 humanoid climbs a
staircase sub-terrain
Visualizer-specific features:
OVRTX path-traced rendering for photorealistic, physically-based lighting
Note
The following features are not yet supported and will be added in a future release:
visualization markers, live plots, and pause rendering. All are available in the other
visualizers. The streaming camera panel’s live on-screen preview is also unavailable, but
headless streaming capture (e.g. for VideoRecorderCfg) works.
Core configuration:
from isaaclab_visualizers.newton import NewtonRTXVisualizerCfg
visualizer_cfg = NewtonRTXVisualizerCfg(
eye=(8.0, 8.0, 3.0),
lookat=(0.0, 0.0, 0.0),
)
For the full config reference, see the config classes below.
NewtonRTXVisualizerCfg source
@configclass
class NewtonRTXVisualizerCfg(NewtonVisualizerCfg):
"""Configuration for the Newton OVRTX path-tracer visualizer.
Selects Newton's OVRTX backend — photorealistic rendering using the same
``begin_frame / log_state / end_frame`` step interface as the GL backend.
.. note::
RTX render quality settings (fps, lighting environment, denoiser, etc.)
are not yet exposed here; ``ViewerRTX`` defaults are used. These will be
surfaced in a future revision in a way that is consistent across all
RTX-capable renderers.
``render_rgb_array()`` captures the path-traced LDR framebuffer at
:attr:`window_width` by :attr:`window_height`. The tiled camera panel remains
unsupported because ``ViewerRTX.log_image`` has no display sink.
"""
class_type: type[NewtonRTXVisualizer] | str = "{DIR}.newton_visualizer:NewtonRTXVisualizer"
"""Visualizer implementation class."""
visualizer_type: str = "newton_rtx"
"""Visualizer selector identifier. Do not change."""
rtx_environment: str = "default"
"""OVRTX lighting environment. One of ``"default"`` (dome + distant light),
``"studio"`` (three-point rig for cleaner highlights), or ``"none"``."""
render_settings: dict[str, Any] = dict()
"""RTX attributes to author on the OVRTX render product, as ``{name: (usd_type_name, value)}``.
``usd_type_name`` names an ``Sdf.ValueTypeNames`` member, as a string so the config stays
copyable. For example, ``{"omni:rtx:quality": ("Int", 100)}`` re-enables the path tracer's
quality convergence loop, which ``ViewerRTX`` otherwise disables to keep interactive latency
down."""
NewtonVisualizerCfg source (shared Newton base class)
@configclass
class NewtonVisualizerCfg(VisualizerCfg):
"""Shared configuration base for Newton visualizer backends.
.. deprecated::
:class:`NewtonVisualizerCfg` is deprecated. Use :class:`NewtonGLVisualizerCfg` for the
OpenGL rasterizer or :class:`NewtonRTXVisualizerCfg` for the OVRTX path tracer.
"""
class_type: type[NewtonGLVisualizer] | str = "{DIR}.newton_visualizer:NewtonGLVisualizer"
"""Deprecated alias for the Newton GL visualizer implementation."""
# Deprecated alias: "newton" routes to the GL backend via simulation_context._VISUALIZER_ALIASES.
visualizer_type: str = "newton_gl"
def __post_init__(self):
if type(self) is NewtonVisualizerCfg:
warnings.warn(
"NewtonVisualizerCfg is deprecated and will be removed in a future release. "
"Use NewtonGLVisualizerCfg (OpenGL rasterizer) or NewtonRTXVisualizerCfg (OVRTX path tracer) instead.",
DeprecationWarning,
stacklevel=3,
)
window_width: int = 1920
"""Window width in pixels."""
window_height: int = 1080
"""Window height in pixels."""
headless: bool = False
"""Run the Newton viewer without requiring a display server."""
update_frequency: int = 1
"""Visualizer update frequency (renders every N simulation frames)."""
world_spacing: tuple[float, float, float] = (0.0, 0.0, 0.0)
"""Visual spacing between simulation worlds along each axis [m].
Non-zero axes arrange visible worlds in a compact grid without changing their simulated poses.
"""
show_joints: bool = False
"""Show joint visualization."""
show_contacts: bool = False
"""Show contact visualization."""
show_collision: bool = False
"""Show collision visualization."""
show_springs: bool = False
"""Show spring visualization."""
show_inertia_boxes: bool = False
"""Show inertia box visualization."""
show_com: bool = False
"""Show center of mass visualization."""
show_particles: bool = False
"""Show particle visualization."""
particle_color: tuple[float, float, float] | None = None
"""Optional particle color RGB [0, 1]. Uses Newton viewer defaults when ``None``."""
enable_picking: bool = True
"""Enable right-click dragging with Newton rigid-body solvers.
Supported coupled solvers may expose dragging through a rigid-body entry.
Disabled automatically for headless viewers, standalone MPM, and non-Newton
physics. MPM particles are not pickable.
"""
enable_shadows: bool = True
"""Enable shadow rendering."""
enable_sky: bool = True
"""Enable sky rendering."""
enable_wireframe: bool = False
"""Enable wireframe rendering."""
sky_upper_color: tuple[float, float, float] = (0.2, 0.4, 0.6)
"""Sky upper color RGB [0, 1]."""
sky_lower_color: tuple[float, float, float] = (0.5, 0.6, 0.7)
"""Sky lower color RGB [0, 1]."""
light_color: tuple[float, float, float] = (1.0, 1.0, 1.0)
"""Light color RGB [0, 1]."""
VisualizerCfg source (shared base class)
@configclass
class VisualizerCfg:
"""Base configuration for all visualizer backends.
Note:
This is an abstract base class and should not be instantiated directly.
Use specific configs from isaaclab_visualizers: KitVisualizerCfg, NewtonGLVisualizerCfg,
RerunVisualizerCfg, or ViserVisualizerCfg (from isaaclab_visualizers.kit/.newton/.rerun/.viser).
"""
class_type: type[BaseVisualizer] | str | None = None
"""Visualizer implementation class. Concrete configs must set this field."""
# Primary interactive camera settings
eye: tuple[float, float, float] = (4.0, -4.0, 3.0)
"""Interactive visualizer camera eye position in world coordinates."""
lookat: tuple[float, float, float] = (0.0, 0.0, 0.0)
"""Interactive visualizer camera look-at target in world coordinates."""
focal_length: float = 12.0
"""Camera focal length in millimeters for visualizer camera views."""
# ── Streaming view ────────────────────────────────────────────────────────
# Captures pixels from a camera sensor (existing or auto-created), tiles them
# across envs and GT types, and shows the result as an image panel in interactive
# visualizers (Newton GL, Kit) or pushes it per-step to sink-based ones (Rerun, Viser).
streaming_view: bool = False
"""Enable the streaming camera image view (opt-in, disabled by default)."""
# Source — existing sensor (takes priority when set)
streaming_sensor_prim_path: str | None = None
"""Prim path of an existing TiledCamera sensor to stream from.
When set, all ``streaming_cam_*`` fields are ignored. Should point to an
existing camera sensor, e.g. ``"/World/envs/*/Camera"``.
"""
# Source — auto-created camera (used when streaming_sensor_prim_path is None)
streaming_cam_target_prim_path: str | None = None
"""Target prim for the auto-created streaming camera (ignored when
:attr:`streaming_sensor_prim_path` is set).
When ``None`` (the default), the visualizer adopts the first scene camera
sensor it discovers dynamically at initialization time. If no scene camera
exists the streaming panel remains empty. Set this explicitly (e.g.
``"/World/envs/*/Robot"``) only when you need an auto-created follow-camera
and no suitable scene camera is present.
"""
streaming_cam_eye: tuple[float, float, float] = (4.0, -4.0, 3.0)
"""Eye offset [m] for the auto-created streaming camera relative to the target prim."""
streaming_cam_renderer: str | None = None
"""Renderer for the auto-created streaming camera.
One of ``"newton_warp"``, ``"ovrtx"``, or ``None`` (let each backend
choose its own default). Defaults to ``None`` so each backend selects
an appropriate renderer automatically. Ignored when
:attr:`streaming_sensor_prim_path` is set.
"""
# Shared settings
streaming_envs: int | list[int] = 32
"""Environments to capture.
* ``int`` — sample this many envs once at initialization (from all visible envs).
* ``list[int]`` — capture exactly these env indices.
"""
streaming_gt_types: tuple[str, ...] = ("rgb",)
"""GT data types displayed left-to-right per environment row.
Valid values: ``"rgb"``, ``"depth"``, ``"segmentation"``, ``"normals"``.
Validated against :data:`~isaaclab.envs.utils.camera_colorizer.SUPPORTED_GT_TYPES`
at initialization time (only when :attr:`streaming_view` is ``True``).
"""
streaming_depth_min: float = 0.1
"""Near-clip for the turbo depth colormap [m]. Used when ``"depth"`` is in
:attr:`streaming_gt_types`."""
streaming_depth_max: float = 10.0
"""Far-clip for the turbo depth colormap [m]. Used when ``"depth"`` is in
:attr:`streaming_gt_types`."""
# Partial visualization settings
max_visible_envs: int | None = None
"""Upper bound on how many envs are shown.
* If visible_env_indices is not None, then this field will apply also
to the explicit env indices set to the visible_env_indices.
"""
visible_env_indices: list[int] | None = None
"""env indices to visualize in order (out-of-range indices are dropped)."""
randomly_sample_visible_envs: bool = True
"""If ``max_visible_envs`` is provided, when enabled, selected visible envs are randomly sampled.
If disabled, the first ``max_visible_envs`` envs are selected.
* Note: ``visible_env_indices`` overrides this field.
"""
# Visualization Markers
enable_markers: bool = True
"""Enable visualization markers (debug drawing)."""
# Live Plots
enable_live_plots: bool = True
"""Stream per-step scalar data (manager terms, episode reward, episode length) into the visualizer.
Plot windows start hidden or collapsed by default and can be toggled open at runtime.
Set to ``False`` to disable live plots entirely and avoid any collection overhead.
"""
live_plots_update_interval: int = 5
"""Collect and push live plot data every ``N`` simulation steps (default: every 5 steps)."""
# Internal
visualizer_type: str | None = None
"""Type identifier (e.g., 'newton', 'rerun', 'viser', 'kit'). Must be overridden by subclasses."""
# Deprecated aliases kept for one-release compatibility. Remove in the next major release.
tiled_cam_view: bool | None = None
"""Deprecated. Use :attr:`streaming_view` instead."""
tiled_cam_num: int | None = None
"""Deprecated. Use :attr:`streaming_envs` (int) instead."""
tiled_cam_env_indices: list[int] | None = None
"""Deprecated. Use :attr:`streaming_envs` (list[int]) instead."""
tiled_cam_prim_path: str | None = None
"""Deprecated. Use :attr:`streaming_sensor_prim_path` instead."""
tiled_cam_eye: tuple[float, float, float] | None = None
"""Deprecated. Use :attr:`streaming_cam_eye` instead."""
tiled_cam_target_prim_path: str | None = None
"""Deprecated. Use :attr:`streaming_cam_target_prim_path` instead."""
tiled_cam_renderer: str | None = None
"""Deprecated. Use :attr:`streaming_cam_renderer` instead."""
def __post_init__(self) -> None:
import warnings
_simple = [
("tiled_cam_view", "streaming_view"),
("tiled_cam_prim_path", "streaming_sensor_prim_path"),
("tiled_cam_eye", "streaming_cam_eye"),
("tiled_cam_target_prim_path", "streaming_cam_target_prim_path"),
("tiled_cam_renderer", "streaming_cam_renderer"),
]
for old, new in _simple:
val = getattr(self, old)
if val is not None:
warnings.warn(f"{old!r} is deprecated; use {new!r} instead.", DeprecationWarning, stacklevel=3)
setattr(self, new, val)
setattr(self, old, None)
# tiled_cam_env_indices takes priority over tiled_cam_num
env_indices = getattr(self, "tiled_cam_env_indices")
if env_indices is not None:
warnings.warn(
"'tiled_cam_env_indices' is deprecated; use 'streaming_envs' instead.",
DeprecationWarning,
stacklevel=3,
)
self.streaming_envs = env_indices
self.tiled_cam_env_indices = None
self.tiled_cam_num = None
else:
num = getattr(self, "tiled_cam_num")
if num is not None:
warnings.warn(
"'tiled_cam_num' is deprecated; use 'streaming_envs' instead.",
DeprecationWarning,
stacklevel=3,
)
self.streaming_envs = num
self.tiled_cam_num = None
Warning
Newton RTX (OVRTX) is a kitless renderer and cannot be used in the same process as Kit
(presets=isaacsim_physx). presets=ovphysx is itself kitless and works fine with
Newton RTX. Use presets=newton_mjwarp,ovrtx or presets=ovphysx,ovrtx with
--viz newton_rtx, or switch to --viz newton_gl, --viz viser, --viz rerun,
or --viz kit with a Kit-compatible physics backend.
Like Viser, Rerun streams simulation state to a local web server, for
remote monitoring, timeline playback, and recording to .rrd files.
Isaac-Reorient-Cube-Shadow-Direct in Rerun Visualizer
Each Shadow Hand reorients
its cube to match the target pose
Visualizer-specific features:
Timeline scrubbing and playback of
.rrdrecordingsPause Rendering and Reset Episode controls via the ImGui sidebar
Note
The native Play/Pause timeline controls in the Rerun visualizer UI do not work while
visualizing a live simulation or training run. They are hidden by default, but Rerun’s
dock panel UI can still be used to reveal them; when revealed, clicking them has no
effect. Use Isaac Lab’s own Pause Rendering / Reset Episode controls instead.
The timeline controls are only meaningful when replaying a saved .rrd recording.
Important
A highlighted URL is printed to the terminal before training begins. Ctrl-click it to
open the viewer, or set open_browser=True to open it automatically.
╭─────────────────────────── rerun (listening *:9090) ───────────────────────────╮
│ URL │ http://127.0.0.1:9090/?url=rerun%2Bhttp://127.0.0.1:9876/proxy │
╰────────────────────────────────────────────────────────────────────────────────╯
Core configuration:
from isaaclab_visualizers.rerun import RerunVisualizerCfg
visualizer_cfg = RerunVisualizerCfg(
eye=(8.0, 8.0, 3.0),
lookat=(0.0, 0.0, 0.0),
keep_historical_data=False, # enable for time scrubbing
keep_scalar_history=False, # enable for scalar time-series
record_to_rrd=None, # set a path to save a .rrd recording
open_browser=False,
)
For the full config reference, see the config classes below.
RerunVisualizerCfg source
@configclass
class RerunVisualizerCfg(VisualizerCfg):
"""Configuration for Rerun visualizer (web-based visualization)."""
class_type: type[RerunVisualizer] | str = "{DIR}.rerun_visualizer:RerunVisualizer"
"""Visualizer implementation class."""
visualizer_type: str = "rerun"
"""Type identifier for Rerun visualizer."""
app_id: str = "isaaclab-simulation"
"""Application identifier shown in viewer title."""
web_port: int = 9090
"""Port of the local rerun web viewer whose URL is logged during initialization."""
grpc_port: int = 9876
"""Port of the rerun gRPC server (used when serving web viewer externally)."""
bind_address: str | None = "0.0.0.0"
"""Host used for endpoint formatting and reuse checks.
Notes:
- If an existing rerun server is reachable on ``grpc_port``, it is reused.
- New server startup is managed by ``newton.viewer.ViewerRerun`` via the rerun Python SDK.
- Local browser links normalize common loopback/wildcard hosts to ``127.0.0.1``.
"""
open_browser: bool = False
"""Whether to attempt opening the rerun web viewer URL in a browser.
The viewer URL is always logged during initialization. Set this to ``True`` to auto-launch it.
"""
keep_historical_data: bool = False
"""Keep transform history for time scrubbing (False = constant memory for training)."""
keep_scalar_history: bool = False
"""Accumulate scalars as a time-series in the Rerun timeline (True = live plot history, False = constant memory).
When :attr:`~isaaclab.visualizers.VisualizerCfg.enable_live_plots` is ``True`` (the default),
this is automatically forced to ``True`` so that scalar values accumulate as a time series in
the Rerun viewer. Set to ``False`` explicitly to reduce memory usage when scalar history is
not needed, but note this will disable live plot curves.
"""
show_particles: bool = True
"""Whether to show model particles.
Disable this option to reduce streaming overhead for large particle clouds.
"""
record_to_rrd: str | None = None
"""Path to save .rrd recording file. None = no recording."""
VisualizerCfg source (shared base class)
@configclass
class VisualizerCfg:
"""Base configuration for all visualizer backends.
Note:
This is an abstract base class and should not be instantiated directly.
Use specific configs from isaaclab_visualizers: KitVisualizerCfg, NewtonGLVisualizerCfg,
RerunVisualizerCfg, or ViserVisualizerCfg (from isaaclab_visualizers.kit/.newton/.rerun/.viser).
"""
class_type: type[BaseVisualizer] | str | None = None
"""Visualizer implementation class. Concrete configs must set this field."""
# Primary interactive camera settings
eye: tuple[float, float, float] = (4.0, -4.0, 3.0)
"""Interactive visualizer camera eye position in world coordinates."""
lookat: tuple[float, float, float] = (0.0, 0.0, 0.0)
"""Interactive visualizer camera look-at target in world coordinates."""
focal_length: float = 12.0
"""Camera focal length in millimeters for visualizer camera views."""
# ── Streaming view ────────────────────────────────────────────────────────
# Captures pixels from a camera sensor (existing or auto-created), tiles them
# across envs and GT types, and shows the result as an image panel in interactive
# visualizers (Newton GL, Kit) or pushes it per-step to sink-based ones (Rerun, Viser).
streaming_view: bool = False
"""Enable the streaming camera image view (opt-in, disabled by default)."""
# Source — existing sensor (takes priority when set)
streaming_sensor_prim_path: str | None = None
"""Prim path of an existing TiledCamera sensor to stream from.
When set, all ``streaming_cam_*`` fields are ignored. Should point to an
existing camera sensor, e.g. ``"/World/envs/*/Camera"``.
"""
# Source — auto-created camera (used when streaming_sensor_prim_path is None)
streaming_cam_target_prim_path: str | None = None
"""Target prim for the auto-created streaming camera (ignored when
:attr:`streaming_sensor_prim_path` is set).
When ``None`` (the default), the visualizer adopts the first scene camera
sensor it discovers dynamically at initialization time. If no scene camera
exists the streaming panel remains empty. Set this explicitly (e.g.
``"/World/envs/*/Robot"``) only when you need an auto-created follow-camera
and no suitable scene camera is present.
"""
streaming_cam_eye: tuple[float, float, float] = (4.0, -4.0, 3.0)
"""Eye offset [m] for the auto-created streaming camera relative to the target prim."""
streaming_cam_renderer: str | None = None
"""Renderer for the auto-created streaming camera.
One of ``"newton_warp"``, ``"ovrtx"``, or ``None`` (let each backend
choose its own default). Defaults to ``None`` so each backend selects
an appropriate renderer automatically. Ignored when
:attr:`streaming_sensor_prim_path` is set.
"""
# Shared settings
streaming_envs: int | list[int] = 32
"""Environments to capture.
* ``int`` — sample this many envs once at initialization (from all visible envs).
* ``list[int]`` — capture exactly these env indices.
"""
streaming_gt_types: tuple[str, ...] = ("rgb",)
"""GT data types displayed left-to-right per environment row.
Valid values: ``"rgb"``, ``"depth"``, ``"segmentation"``, ``"normals"``.
Validated against :data:`~isaaclab.envs.utils.camera_colorizer.SUPPORTED_GT_TYPES`
at initialization time (only when :attr:`streaming_view` is ``True``).
"""
streaming_depth_min: float = 0.1
"""Near-clip for the turbo depth colormap [m]. Used when ``"depth"`` is in
:attr:`streaming_gt_types`."""
streaming_depth_max: float = 10.0
"""Far-clip for the turbo depth colormap [m]. Used when ``"depth"`` is in
:attr:`streaming_gt_types`."""
# Partial visualization settings
max_visible_envs: int | None = None
"""Upper bound on how many envs are shown.
* If visible_env_indices is not None, then this field will apply also
to the explicit env indices set to the visible_env_indices.
"""
visible_env_indices: list[int] | None = None
"""env indices to visualize in order (out-of-range indices are dropped)."""
randomly_sample_visible_envs: bool = True
"""If ``max_visible_envs`` is provided, when enabled, selected visible envs are randomly sampled.
If disabled, the first ``max_visible_envs`` envs are selected.
* Note: ``visible_env_indices`` overrides this field.
"""
# Visualization Markers
enable_markers: bool = True
"""Enable visualization markers (debug drawing)."""
# Live Plots
enable_live_plots: bool = True
"""Stream per-step scalar data (manager terms, episode reward, episode length) into the visualizer.
Plot windows start hidden or collapsed by default and can be toggled open at runtime.
Set to ``False`` to disable live plots entirely and avoid any collection overhead.
"""
live_plots_update_interval: int = 5
"""Collect and push live plot data every ``N`` simulation steps (default: every 5 steps)."""
# Internal
visualizer_type: str | None = None
"""Type identifier (e.g., 'newton', 'rerun', 'viser', 'kit'). Must be overridden by subclasses."""
# Deprecated aliases kept for one-release compatibility. Remove in the next major release.
tiled_cam_view: bool | None = None
"""Deprecated. Use :attr:`streaming_view` instead."""
tiled_cam_num: int | None = None
"""Deprecated. Use :attr:`streaming_envs` (int) instead."""
tiled_cam_env_indices: list[int] | None = None
"""Deprecated. Use :attr:`streaming_envs` (list[int]) instead."""
tiled_cam_prim_path: str | None = None
"""Deprecated. Use :attr:`streaming_sensor_prim_path` instead."""
tiled_cam_eye: tuple[float, float, float] | None = None
"""Deprecated. Use :attr:`streaming_cam_eye` instead."""
tiled_cam_target_prim_path: str | None = None
"""Deprecated. Use :attr:`streaming_cam_target_prim_path` instead."""
tiled_cam_renderer: str | None = None
"""Deprecated. Use :attr:`streaming_cam_renderer` instead."""
def __post_init__(self) -> None:
import warnings
_simple = [
("tiled_cam_view", "streaming_view"),
("tiled_cam_prim_path", "streaming_sensor_prim_path"),
("tiled_cam_eye", "streaming_cam_eye"),
("tiled_cam_target_prim_path", "streaming_cam_target_prim_path"),
("tiled_cam_renderer", "streaming_cam_renderer"),
]
for old, new in _simple:
val = getattr(self, old)
if val is not None:
warnings.warn(f"{old!r} is deprecated; use {new!r} instead.", DeprecationWarning, stacklevel=3)
setattr(self, new, val)
setattr(self, old, None)
# tiled_cam_env_indices takes priority over tiled_cam_num
env_indices = getattr(self, "tiled_cam_env_indices")
if env_indices is not None:
warnings.warn(
"'tiled_cam_env_indices' is deprecated; use 'streaming_envs' instead.",
DeprecationWarning,
stacklevel=3,
)
self.streaming_envs = env_indices
self.tiled_cam_env_indices = None
self.tiled_cam_num = None
else:
num = getattr(self, "tiled_cam_num")
if num is not None:
warnings.warn(
"'tiled_cam_num' is deprecated; use 'streaming_envs' instead.",
DeprecationWarning,
stacklevel=3,
)
self.streaming_envs = num
self.tiled_cam_num = None
The Kit visualizer embeds Isaac Lab inside a Kit process, providing access to the full Isaac Sim USD stage, RTX renderer, and GUI tooling. It has the highest startup and runtime overhead of the five visualizers.
Isaac-Reach-Franka in Kit Visualizer
Each Franka arm reaches its end-effector
toward a randomized target pose
Visualizer-specific features:
Direct access to the Isaac Sim USD stage for inspecting and editing prims at runtime
Full Isaac Sim GUI tooling (Property, Layers, and Stage panels)
Core configuration:
from isaaclab_visualizers.kit import KitVisualizerCfg
visualizer_cfg = KitVisualizerCfg(
eye=(8.0, 8.0, 3.0),
lookat=(0.0, 0.0, 0.0),
window_width=1280,
window_height=720,
enable_markers=True,
enable_live_plots=True,
)
For the full config reference, see the config classes below.
KitVisualizerCfg source
@configclass
class KitVisualizerCfg(VisualizerCfg):
"""Configuration for Kit visualizer using Isaac Sim viewport.
.. note::
The streaming camera panel (``streaming_view=True``) requires the
``--enable_cameras`` CLI flag. Without it, the streaming view is silently
skipped and no image panel is created. Set ``dock_position="RIGHT"`` so
the panel appears side-by-side with the Viewport instead of as a hidden tab.
"""
class_type: type[KitVisualizer] | str = "{DIR}.kit_visualizer:KitVisualizer"
"""Visualizer implementation class."""
visualizer_type: str = "kit"
"""Type identifier for Kit visualizer."""
viewport_name: str | None = None
"""Name for a new viewport window when :attr:`create_viewport` is ``True``.
If ``None``, a default name (``"Visualizer Viewport"``) is used.
"""
create_viewport: bool = False
"""If ``True``, create a new viewport window; if ``False``, use the active viewport window."""
headless: bool = False
"""Run without creating viewport windows when supported by the app."""
dock_position: str = "SAME"
"""Dock position for the streaming image panel and any new viewport window.
Options: ``'LEFT'``, ``'RIGHT'``, ``'BOTTOM'``, ``'SAME'``.
.. note::
``'SAME'`` (the default) places the streaming panel as a hidden tab in the
same dock group as the main Viewport — you must click the panel's tab to see it.
Use ``'RIGHT'`` to keep both the Viewport and the streaming panel visible
side-by-side.
"""
window_width: int = 1280
"""Viewport width in pixels (when :attr:`create_viewport` is ``True``)."""
window_height: int = 720
"""Viewport height in pixels (when :attr:`create_viewport` is ``True``)."""
origin_type: str = "world"
"""Frame in which :attr:`~isaaclab.visualizers.VisualizerCfg.eye` and
:attr:`~isaaclab.visualizers.VisualizerCfg.lookat` are interpreted.
Options:
* ``"world"``: global origin.
* ``"env"``: origin of the environment at :attr:`origin_env_index`.
* ``"asset"``: a scene asset (or body) specified by :attr:`origin_track_path`.
"""
origin_env_index: int = 0
"""Index of the environment used as the viewport camera origin.
Only meaningful when :attr:`origin_type` is ``"env"`` or ``"asset"``.
"""
origin_track_path: str | None = None
"""Asset tracking path for the viewport camera origin.
Format: ``"<asset_name>"`` to track the asset root, or ``"<asset_name>/<body_name>"``
to track a specific body on the asset. Required when :attr:`origin_type` is ``"asset"``.
Examples::
origin_track_path = "robot" # track robot root
origin_track_path = "robot/panda_hand" # track panda_hand body on robot
"""
VisualizerCfg source (shared base class)
@configclass
class VisualizerCfg:
"""Base configuration for all visualizer backends.
Note:
This is an abstract base class and should not be instantiated directly.
Use specific configs from isaaclab_visualizers: KitVisualizerCfg, NewtonGLVisualizerCfg,
RerunVisualizerCfg, or ViserVisualizerCfg (from isaaclab_visualizers.kit/.newton/.rerun/.viser).
"""
class_type: type[BaseVisualizer] | str | None = None
"""Visualizer implementation class. Concrete configs must set this field."""
# Primary interactive camera settings
eye: tuple[float, float, float] = (4.0, -4.0, 3.0)
"""Interactive visualizer camera eye position in world coordinates."""
lookat: tuple[float, float, float] = (0.0, 0.0, 0.0)
"""Interactive visualizer camera look-at target in world coordinates."""
focal_length: float = 12.0
"""Camera focal length in millimeters for visualizer camera views."""
# ── Streaming view ────────────────────────────────────────────────────────
# Captures pixels from a camera sensor (existing or auto-created), tiles them
# across envs and GT types, and shows the result as an image panel in interactive
# visualizers (Newton GL, Kit) or pushes it per-step to sink-based ones (Rerun, Viser).
streaming_view: bool = False
"""Enable the streaming camera image view (opt-in, disabled by default)."""
# Source — existing sensor (takes priority when set)
streaming_sensor_prim_path: str | None = None
"""Prim path of an existing TiledCamera sensor to stream from.
When set, all ``streaming_cam_*`` fields are ignored. Should point to an
existing camera sensor, e.g. ``"/World/envs/*/Camera"``.
"""
# Source — auto-created camera (used when streaming_sensor_prim_path is None)
streaming_cam_target_prim_path: str | None = None
"""Target prim for the auto-created streaming camera (ignored when
:attr:`streaming_sensor_prim_path` is set).
When ``None`` (the default), the visualizer adopts the first scene camera
sensor it discovers dynamically at initialization time. If no scene camera
exists the streaming panel remains empty. Set this explicitly (e.g.
``"/World/envs/*/Robot"``) only when you need an auto-created follow-camera
and no suitable scene camera is present.
"""
streaming_cam_eye: tuple[float, float, float] = (4.0, -4.0, 3.0)
"""Eye offset [m] for the auto-created streaming camera relative to the target prim."""
streaming_cam_renderer: str | None = None
"""Renderer for the auto-created streaming camera.
One of ``"newton_warp"``, ``"ovrtx"``, or ``None`` (let each backend
choose its own default). Defaults to ``None`` so each backend selects
an appropriate renderer automatically. Ignored when
:attr:`streaming_sensor_prim_path` is set.
"""
# Shared settings
streaming_envs: int | list[int] = 32
"""Environments to capture.
* ``int`` — sample this many envs once at initialization (from all visible envs).
* ``list[int]`` — capture exactly these env indices.
"""
streaming_gt_types: tuple[str, ...] = ("rgb",)
"""GT data types displayed left-to-right per environment row.
Valid values: ``"rgb"``, ``"depth"``, ``"segmentation"``, ``"normals"``.
Validated against :data:`~isaaclab.envs.utils.camera_colorizer.SUPPORTED_GT_TYPES`
at initialization time (only when :attr:`streaming_view` is ``True``).
"""
streaming_depth_min: float = 0.1
"""Near-clip for the turbo depth colormap [m]. Used when ``"depth"`` is in
:attr:`streaming_gt_types`."""
streaming_depth_max: float = 10.0
"""Far-clip for the turbo depth colormap [m]. Used when ``"depth"`` is in
:attr:`streaming_gt_types`."""
# Partial visualization settings
max_visible_envs: int | None = None
"""Upper bound on how many envs are shown.
* If visible_env_indices is not None, then this field will apply also
to the explicit env indices set to the visible_env_indices.
"""
visible_env_indices: list[int] | None = None
"""env indices to visualize in order (out-of-range indices are dropped)."""
randomly_sample_visible_envs: bool = True
"""If ``max_visible_envs`` is provided, when enabled, selected visible envs are randomly sampled.
If disabled, the first ``max_visible_envs`` envs are selected.
* Note: ``visible_env_indices`` overrides this field.
"""
# Visualization Markers
enable_markers: bool = True
"""Enable visualization markers (debug drawing)."""
# Live Plots
enable_live_plots: bool = True
"""Stream per-step scalar data (manager terms, episode reward, episode length) into the visualizer.
Plot windows start hidden or collapsed by default and can be toggled open at runtime.
Set to ``False`` to disable live plots entirely and avoid any collection overhead.
"""
live_plots_update_interval: int = 5
"""Collect and push live plot data every ``N`` simulation steps (default: every 5 steps)."""
# Internal
visualizer_type: str | None = None
"""Type identifier (e.g., 'newton', 'rerun', 'viser', 'kit'). Must be overridden by subclasses."""
# Deprecated aliases kept for one-release compatibility. Remove in the next major release.
tiled_cam_view: bool | None = None
"""Deprecated. Use :attr:`streaming_view` instead."""
tiled_cam_num: int | None = None
"""Deprecated. Use :attr:`streaming_envs` (int) instead."""
tiled_cam_env_indices: list[int] | None = None
"""Deprecated. Use :attr:`streaming_envs` (list[int]) instead."""
tiled_cam_prim_path: str | None = None
"""Deprecated. Use :attr:`streaming_sensor_prim_path` instead."""
tiled_cam_eye: tuple[float, float, float] | None = None
"""Deprecated. Use :attr:`streaming_cam_eye` instead."""
tiled_cam_target_prim_path: str | None = None
"""Deprecated. Use :attr:`streaming_cam_target_prim_path` instead."""
tiled_cam_renderer: str | None = None
"""Deprecated. Use :attr:`streaming_cam_renderer` instead."""
def __post_init__(self) -> None:
import warnings
_simple = [
("tiled_cam_view", "streaming_view"),
("tiled_cam_prim_path", "streaming_sensor_prim_path"),
("tiled_cam_eye", "streaming_cam_eye"),
("tiled_cam_target_prim_path", "streaming_cam_target_prim_path"),
("tiled_cam_renderer", "streaming_cam_renderer"),
]
for old, new in _simple:
val = getattr(self, old)
if val is not None:
warnings.warn(f"{old!r} is deprecated; use {new!r} instead.", DeprecationWarning, stacklevel=3)
setattr(self, new, val)
setattr(self, old, None)
# tiled_cam_env_indices takes priority over tiled_cam_num
env_indices = getattr(self, "tiled_cam_env_indices")
if env_indices is not None:
warnings.warn(
"'tiled_cam_env_indices' is deprecated; use 'streaming_envs' instead.",
DeprecationWarning,
stacklevel=3,
)
self.streaming_envs = env_indices
self.tiled_cam_env_indices = None
self.tiled_cam_num = None
else:
num = getattr(self, "tiled_cam_num")
if num is not None:
warnings.warn(
"'tiled_cam_num' is deprecated; use 'streaming_envs' instead.",
DeprecationWarning,
stacklevel=3,
)
self.streaming_envs = num
self.tiled_cam_num = None
Usage#
Common Recipes#
Headless training with video recording
Run without a window and record clips from a Newton GL or Kit visualizer kept alive as the capture source:
uv run isaaclab train --rl_library rsl_rl --task Isaac-Cartpole \
--viz newton_gl --headless --video
./isaaclab.sh train --rl_library rsl_rl --task Isaac-Cartpole \
--viz newton_gl --headless --video
See Recording Video for clip length, interval, and multi-source options.
Combining an interactive view with a headless recording source
Watch training live in Kit while recording from a separate headless Newton GL angle:
from isaaclab_visualizers.kit import KitVisualizerCfg
from isaaclab_visualizers.newton import NewtonGLVisualizerCfg
sim_cfg.visualizer_cfgs = [
KitVisualizerCfg(eye=(4.0, 4.0, 2.0)),
NewtonGLVisualizerCfg(eye=(12.0, 0.0, 6.0), headless=True),
]
See the “Recording from an independent camera angle” section of Recording Video for the full example.
Following a moving robot (Kit)
Lock the Kit camera to a moving asset instead of updating eye/lookat yourself every
step:
from isaaclab_visualizers.kit import KitVisualizerCfg
sim_cfg.visualizer_cfgs = [
KitVisualizerCfg(
origin_type="asset",
origin_track_path="robot", # or "robot/panda_hand" to track a specific body
eye=(4.0, 4.0, 2.0), # offset from the tracked asset
)
]
Sharing a live view with a remote teammate
Viser can request a public share URL for the running session, useful for remote pairing without screen-sharing:
from isaaclab_visualizers.viser import ViserVisualizerCfg
sim_cfg.visualizer_cfgs = [ViserVisualizerCfg(share=True, open_browser=True)]
The share URL is logged on startup. Rerun has no equivalent config field, but exposes its own share button in the native UI.
Resolution Rules#
Visualizers are resolved from --viz (comma-separated, e.g. --viz kit,newton_gl) or
SimulationCfg.visualizer_cfgs in code. If --viz is omitted, the config value is used;
--viz none always disables all visualizers, regardless of config.
Add --headless alongside --viz kit or --viz newton_gl to keep that visualizer
running without an on-screen window, e.g. as a --video recording source on a machine
without a display.
To configure visualizer settings in code, pass VisualizerCfg instances to
SimulationCfg:
from isaaclab.sim import SimulationCfg
from isaaclab_visualizers.kit import KitVisualizerCfg
from isaaclab_visualizers.newton import NewtonGLVisualizerCfg
sim_cfg = SimulationCfg(
visualizer_cfgs=[
KitVisualizerCfg(eye=(0.0, 0.0, 20.0)),
NewtonGLVisualizerCfg(eye=(5.0, 5.0, 5.0), show_joints=True),
]
)
CLI args |
|
Effective behavior |
|---|---|---|
no |
|
No visualizer launches; no window, no capture source. |
|
|
Launch default Kit and Newton GL visualizers. |
|
|
Launch Newton GL without a window, e.g. as a |
|
|
Launch default Kit and custom Newton GL; Rerun is not launched. |
no |
|
Launch custom Newton GL and Rerun from config. |
|
|
All visualizers disabled; no window, no capture source. |
For migration context, see Migrating To 3.0.
Performance#
Visualizer |
Tips |
|---|---|
Newton GL |
Lowest overhead; increase |
Viser |
Newton Warp renderer; use |
Newton RTX |
Path-traced; highest per-frame cost, use |
Rerun |
Web viewer may slow down with many environments; use |
Kit |
Highest overhead of the five visualizers; reduce |
Limitations#
Backend feature support:
Feature |
Newton GL |
Newton RTX |
Viser |
Rerun |
Kit |
|---|---|---|---|---|---|
Visualization markers |
✓ |
✗ |
✓ |
✓ |
✓ |
Live plots |
✓ |
✗ |
✓ |
✓ |
✓ |
Streaming camera panel |
✓ |
✗ |
✓ |
✓ |
✓ |
Video recording, |
✓ |
✓ |
✗ |
✗ |
✓ |
Pause rendering |
✓ |
✗ |
✓ |
✓ |
✓ |
Headless mode |
✓ |
✓ |
✓ |
✓ |
✓ |
Lighting differences across visualizers
Each backend lights the scene differently, so the same environment can look noticeably
different across visualizers. Kit renders the scene’s actual authored USD lights. Newton GL
uses a fixed sky-gradient and single directional light color
(sky_upper_color,
sky_lower_color, light_color), independent of scene USD lights. Newton RTX supports
only 3 lighting-environment presets
(rtx_environment: "default",
"studio", "none") and does not use any scene-authored USD lights. Viser uses a single
ambient light with no directional key light, so scenes tend to look darker and flatter than
the other backends. Rerun uses fixed built-in viewer shading with no scene-driven lighting.
Kit: incompatible with ovphysx / ovrtx presets
--viz kit cannot be used with presets=ovphysx or presets=ovrtx in the same process.
Use --viz newton_gl, --viz rerun, or --viz viser with those presets, or omit
--viz for headless execution.
Newton RTX: incompatible with Kit
--viz newton_rtx raises a RuntimeError at startup if the active physics backend is
isaacsim_physx (i.e. presets=isaacsim_physx), since OVRTX is a kitless renderer and cannot share
a process with Kit. presets=ovphysx is itself kitless and remains supported. Use
presets=newton_mjwarp,ovrtx or presets=ovphysx,ovrtx with --viz newton_rtx, or switch
to --viz newton_gl, --viz viser, --viz rerun, or --viz kit with a Kit-compatible
physics backend.
Rerun: large environment performance
The Rerun web viewer may slow down or crash with many environments. Reduce load with
--num_envs:
uv run isaaclab train --rl_library rsl_rl --task Isaac-Cartpole --viz rerun --num_envs 512
./isaaclab.sh train --rl_library rsl_rl --task Isaac-Cartpole --viz rerun --num_envs 512
Newton GL: CUDA/OpenGL interoperability warnings
In some configurations, the Newton GL visualizer emits warnings about CUDA/OpenGL interoperability:
Warning: Could not get MSAA config, falling back to non-AA.
Warp CUDA error 999: unknown error (in function wp_cuda_graphics_register_gl_buffer)
Warp UserWarning: Could not register GL buffer …
The visualizer still functions correctly but falls back to CPU copy operations, which reduces performance.
Newton GL: OpenGL context failures
If pyglet reports that glCreateShader is not exported or that OpenGL 2.0 is required, the
process is running without a GPU-backed display context (for example, in a service session or
a remote desktop without GPU acceleration). Run from a GPU-backed interactive display session,
or omit --viz newton_gl for headless execution.
Newton GL: Spark + conda
Conda-installed X11 libraries may conflict with pyglet on Spark, producing:
pyglet.window.xlib.XlibException: Could not create UTF8 text property
Remove the conflicting conda packages to use the system libraries instead:
conda remove --force xorg-libx11 libxcb
See Also#
Visualizer Streaming Camera View: full streaming camera panel guide and tutorial
Recording Video: recording MP4 clips from a visualizer or sensor
Creating Visualization Markers: creating and configuring custom visualization markers
Capturing sensor frames during training: saving per-frame sensor outputs during training
Renderers: renderer backends (RTX, Newton Warp, OVRTX)
Scene Data Provider: how scene data flows to visualizers
Newton Backend: Newton backend guide
Migrating To 3.0: visualizer migration reference