From 4054515bca5e3cc886af072ce434f7abb15c474d Mon Sep 17 00:00:00 2001 From: Matthew Taylor Date: Fri, 14 Aug 2026 19:53:13 -0400 Subject: [PATCH 1/2] Skip RTX scene partitioning without spectator-view support Per-environment scene partitioning is now on by default, and the Kit viewport relies on /rtx/scenePartitioning/showAllPartitionsByDefault to see partitioned geometry. That RTX setting arrived in Isaac Sim 6.1. Carb settings are schemaless, so the experience files create the key on every runtime and reading it back cannot tell an implementing renderer from one that ignores it. On Isaac Sim 6.0 the viewport camera therefore ended up with no partition token and no spectator fallback, matching no partition and rendering an empty image. Resolve the capability from the Isaac Sim version and leave the stage unpartitioned when the spectator view is requested but unsupported, rather than half-applying the feature. Setting show_all_partitions_by_default=False keeps partitioning on those runtimes, with the viewport bound to one environment. --- ...lor-scene-partition-spectator-fallback.rst | 11 +++ .../renderers/isaac_rtx_renderer.py | 23 +++++++ .../renderers/isaac_rtx_renderer_utils.py | 19 ++++++ ...t_isaac_rtx_renderer_scene_partitioning.py | 68 +++++++++++++++---- 4 files changed, 109 insertions(+), 12 deletions(-) create mode 100644 source/isaaclab_physx/changelog.d/mataylor-scene-partition-spectator-fallback.rst diff --git a/source/isaaclab_physx/changelog.d/mataylor-scene-partition-spectator-fallback.rst b/source/isaaclab_physx/changelog.d/mataylor-scene-partition-spectator-fallback.rst new file mode 100644 index 000000000000..ad270f761296 --- /dev/null +++ b/source/isaaclab_physx/changelog.d/mataylor-scene-partition-spectator-fallback.rst @@ -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. diff --git a/source/isaaclab_physx/isaaclab_physx/renderers/isaac_rtx_renderer.py b/source/isaaclab_physx/isaaclab_physx/renderers/isaac_rtx_renderer.py index 6aa8066b0ce7..49ade5de40d2 100644 --- a/source/isaaclab_physx/isaaclab_physx/renderers/isaac_rtx_renderer.py +++ b/source/isaaclab_physx/isaaclab_physx/renderers/isaac_rtx_renderer.py @@ -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__) @@ -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, diff --git a/source/isaaclab_physx/isaaclab_physx/renderers/isaac_rtx_renderer_utils.py b/source/isaaclab_physx/isaaclab_physx/renderers/isaac_rtx_renderer_utils.py index ae09028ac234..4e8980fcb1d5 100644 --- a/source/isaaclab_physx/isaaclab_physx/renderers/isaac_rtx_renderer_utils.py +++ b/source/isaaclab_physx/isaaclab_physx/renderers/isaac_rtx_renderer_utils.py @@ -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", diff --git a/source/isaaclab_physx/test/renderers/test_isaac_rtx_renderer_scene_partitioning.py b/source/isaaclab_physx/test/renderers/test_isaac_rtx_renderer_scene_partitioning.py index 0c25ee6b31e3..9b7a60f37d7f 100644 --- a/source/isaaclab_physx/test/renderers/test_isaac_rtx_renderer_scene_partitioning.py +++ b/source/isaaclab_physx/test/renderers/test_isaac_rtx_renderer_scene_partitioning.py @@ -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 @@ -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) @@ -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) @@ -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 From f322cf79796066d0a8d47b94dc1472e86f7a7bb8 Mon Sep 17 00:00:00 2001 From: Matthew Taylor Date: Fri, 14 Aug 2026 20:17:47 -0400 Subject: [PATCH 2/2] Document the Isaac Sim requirement for the RTX spectator view Record that /rtx/scenePartitioning/showAllPartitionsByDefault needs Isaac Sim 6.1 or newer, and that Isaac Lab skips scene-partition authoring on older releases so the Kit viewport keeps showing every environment. --- docs/source/overview/core-concepts/renderers.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/source/overview/core-concepts/renderers.rst b/docs/source/overview/core-concepts/renderers.rst index 05730874b87f..8854de407385 100644 --- a/docs/source/overview/core-concepts/renderers.rst +++ b/docs/source/overview/core-concepts/renderers.rst @@ -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.