Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions docs/source/overview/core-concepts/renderers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,13 @@ environments to remain spatially separated; overlapping partition bounds can mak
content leak into another environment or disappear. Set the field to ``False`` to
prioritize partition isolation and show only the selected environment in the Kit viewport.

The RTX spectator view requires Isaac Sim 6.1 or newer. On older releases the renderer
ignores ``rtx.scenePartitioning.showAllPartitionsByDefault``, and an unpartitioned
spectator camera matches no partition and renders an empty viewport. Isaac Lab therefore
skips scene-partition authoring altogether on those releases and logs a warning, leaving
every environment visible. Set ``show_all_partitions_by_default=False`` to keep partition
isolation there, with the Kit viewport bound to a single environment.

Prims outside the environment hierarchies remain in the shared background partition.
Environment-owned ``PointInstancer`` markers can carry one matching scene-partition
token per instance; markers without that ownership information remain shared.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
Fixed
^^^^^

* Fixed an empty Kit viewport when per-environment scene partitioning ran on an Isaac Sim
release whose RTX renderer does not implement the all-partitions spectator view
(``/rtx/scenePartitioning/showAllPartitionsByDefault``, added in Isaac Sim 6.1). Interactive
viewport cameras inherit no ``omni:scenePartition`` token, so on those runtimes they matched
no partition and rendered nothing. :meth:`~isaaclab_physx.renderers.IsaacRtxRenderer.prepare_stage`
now leaves the stage unpartitioned when the spectator view is requested but unsupported. Set
``IsaacRtxRendererCfg.global_settings.show_all_partitions_by_default`` to ``False`` to keep
per-environment isolation on those runtimes; the viewport is then bound to a single environment.
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,12 @@
from isaaclab.utils.warp.warp_math import clamp_depth_to_inf_wp, replace_inf_depth_wp

from .isaac_rtx_renderer_utils import (
SHOW_ALL_PARTITIONS_MIN_ISAAC_SIM_VERSION,
apply_isaac_rtx_determinism_settings,
apply_isaac_rtx_global_settings,
ensure_isaac_rtx_render_update,
ensure_rtx_hydra_engine_attached,
show_all_partitions_supported,
)

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -205,11 +207,32 @@ def prepare_stage(self, stage: Usd.Stage, num_envs: int) -> None:
non-primvar ``omni:scenePartition`` token on every :class:`UsdGeom.Camera` descendant.
RTX honors primvar inheritance, so the env-root primvar propagates to all descendant
geometry and isolates each env's render tile.

Authoring is also skipped when the all-partitions spectator view is requested but the
running RTX renderer does not implement it, because partitioning every env root would
then leave interactive viewports with nothing to render.
See :meth:`~isaaclab.renderers.base_renderer.BaseRenderer.prepare_stage`."""

if not self.cfg.enable_scene_partitioning:
return

# Kit viewport cameras live outside ``/World/envs``, so they inherit no partition token and
# depend on the spectator view to see partitioned geometry. On a renderer that ignores the
# spectator setting such a camera matches no partition and the viewport renders black, so
# leave the stage unpartitioned rather than half-applying the feature. Setting
# ``show_all_partitions_by_default=False`` keeps partitioning on these runtimes; the
# visualizer then binds the viewport to a single environment.
if self.cfg.global_settings.show_all_partitions_by_default and not show_all_partitions_supported():
logger.warning(
"Skipping RTX scene partitioning: the all-partitions spectator view requires Isaac Sim %s or"
" newer, but %s is running. Partitioning without it renders an empty Kit viewport. Set"
" IsaacRtxRendererCfg.global_settings.show_all_partitions_by_default=False to partition anyway"
" and view a single environment, or upgrade Isaac Sim.",
SHOW_ALL_PARTITIONS_MIN_ISAAC_SIM_VERSION,
get_isaac_sim_version(),
)
return

logger.debug(
"Per-environment RTX scene partitioning is enabled. Authoring primvars:omni:scenePartition on %d env(s).",
num_envs,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,34 @@
import time
from typing import Any

from packaging.version import Version

import omni.usd

import isaaclab.sim as sim_utils
from isaaclab.app.settings_manager import SettingsManager, get_settings_manager
from isaaclab.utils.version import get_isaac_sim_version

from .isaac_rtx_renderer_cfg import IsaacRtxRendererGlobalSettingsCfg

logger = logging.getLogger(__name__)

SHOW_ALL_PARTITIONS_MIN_ISAAC_SIM_VERSION = Version("6.1")
"""First Isaac Sim release whose RTX renderer implements the all-partitions spectator view."""


def show_all_partitions_supported() -> bool:
"""Return whether the running RTX renderer implements the all-partitions spectator view.

``/rtx/scenePartitioning/showAllPartitionsByDefault`` makes a camera that carries no
``omni:scenePartition`` token render every partition. Carb settings are schemaless, so the
experience files set the key on every runtime and reading it back cannot distinguish a
renderer that honors it from one that ignores it. Older renderers cull such a camera down to
nothing, so the capability is resolved from the Isaac Sim version instead.
"""
return get_isaac_sim_version() >= SHOW_ALL_PARTITIONS_MIN_ISAAC_SIM_VERSION


_RTX_FIELD_TO_SETTING = {
"enable_translucency": "/rtx/translucency/enabled",
"enable_reflections": "/rtx/reflections/enabled",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@

import os

import isaaclab_physx.renderers.isaac_rtx_renderer as isaac_rtx_renderer_module
import pytest
import torch
import warp as wp
Expand All @@ -57,17 +58,28 @@ def _isolation_renderer_cfg() -> IsaacRtxRendererCfg:
return IsaacRtxRendererCfg(global_settings=IsaacRtxRendererGlobalSettingsCfg(show_all_partitions_by_default=False))


def _stage_with_one_env():
"""Build an in-memory stage holding a single environment root."""
from pxr import Usd

stage = Usd.Stage.CreateInMemory()
stage.DefinePrim("/World", "Xform")
stage.DefinePrim("/World/envs/env_0", "Xform")
return stage


def _force_spectator_support(monkeypatch: pytest.MonkeyPatch, supported: bool) -> None:
"""Pin the RTX spectator-view capability so authoring does not depend on the running Isaac Sim."""
monkeypatch.setattr(isaac_rtx_renderer_module, "show_all_partitions_supported", lambda: supported)


@pytest.mark.isaacsim_ci
def test_partitioning_enabled_by_default(monkeypatch):
"""``primvars:omni:scenePartition`` must be authored when the environment variable is absent."""
from pxr import Usd

monkeypatch.delenv(_ENV_VAR, raising=False)
_force_spectator_support(monkeypatch, True)

stage = Usd.Stage.CreateInMemory()
world = stage.DefinePrim("/World", "Xform") # noqa: F841
env0 = stage.DefinePrim("/World/envs/env_0", "Xform") # noqa: F841

stage = _stage_with_one_env()
renderer = object.__new__(IsaacRtxRenderer)
renderer.cfg = IsaacRtxRendererCfg()
renderer.prepare_stage(stage, num_envs=1)
Expand All @@ -82,14 +94,10 @@ def test_partitioning_enabled_by_default(monkeypatch):
@pytest.mark.parametrize(("cfg_enabled", "environment_value"), [(True, "0"), (False, "1")])
def test_partitioning_cfg_overrides_legacy_environment_variable(monkeypatch, cfg_enabled: bool, environment_value: str):
"""The renderer configuration should take precedence over the legacy environment variable."""
from pxr import Usd

monkeypatch.setenv(_ENV_VAR, environment_value)
_force_spectator_support(monkeypatch, True)

stage = Usd.Stage.CreateInMemory()
world = stage.DefinePrim("/World", "Xform") # noqa: F841
env0 = stage.DefinePrim("/World/envs/env_0", "Xform") # noqa: F841

stage = _stage_with_one_env()
renderer = object.__new__(IsaacRtxRenderer)
renderer.cfg = IsaacRtxRendererCfg(enable_scene_partitioning=cfg_enabled)
renderer.prepare_stage(stage, num_envs=1)
Expand All @@ -98,6 +106,42 @@ def test_partitioning_cfg_overrides_legacy_environment_variable(monkeypatch, cfg
assert prim.HasAttribute("primvars:omni:scenePartition") is cfg_enabled


@pytest.mark.isaacsim_ci
def test_partitioning_skipped_when_spectator_view_unsupported(monkeypatch: pytest.MonkeyPatch):
"""A renderer that ignores the spectator setting must be left unpartitioned.

Partitioning every env root on such a runtime culls the Kit viewport camera -- which carries no
``omni:scenePartition`` token -- down to an empty image.
"""
monkeypatch.delenv(_ENV_VAR, raising=False)
_force_spectator_support(monkeypatch, False)

stage = _stage_with_one_env()
renderer = object.__new__(IsaacRtxRenderer)
renderer.cfg = IsaacRtxRendererCfg()
renderer.prepare_stage(stage, num_envs=1)

prim = stage.GetPrimAtPath("/World/envs/env_0")
assert not prim.HasAttribute("primvars:omni:scenePartition"), (
"Partitioning must be skipped when the spectator view is requested but unsupported."
)


@pytest.mark.isaacsim_ci
def test_partitioning_kept_without_spectator_view_on_unsupported_runtime(monkeypatch: pytest.MonkeyPatch):
"""Opting out of the spectator view keeps per-env isolation on renderers that lack it."""
monkeypatch.delenv(_ENV_VAR, raising=False)
_force_spectator_support(monkeypatch, False)

stage = _stage_with_one_env()
renderer = object.__new__(IsaacRtxRenderer)
renderer.cfg = _isolation_renderer_cfg()
renderer.prepare_stage(stage, num_envs=1)

prim = stage.GetPrimAtPath("/World/envs/env_0")
assert prim.GetAttribute("primvars:omni:scenePartition").Get() == "env_0"


@pytest.mark.isaacsim_ci
def test_partitioning_isolates_rigid_object(monkeypatch: pytest.MonkeyPatch):
"""Per-env :class:`~isaaclab.assets.RigidObject` instances at unique world positions render
Expand Down
Loading