Agent Skills › isaac-sim/IsaacSim › isaac-sim-rendering

isaac-sim-rendering

GitHub

用于在 Isaac Sim 中执行无头渲染、帧捕获及渲染质量验证的技能,支持 RT2/PathTracing 和 ACES 色调映射,提供仓库灯光配方及量化校验工具。

.claude/skills/isaac-sim-rendering/SKILL.md isaac-sim/IsaacSim

触发场景

需要生成高质量渲染帧 验证渲染器输出质量 配置无头渲染管线

安装

npx skills add isaac-sim/IsaacSim --skill isaac-sim-rendering -g -y
更多选项

非标准路径

npx skills add https://github.com/isaac-sim/IsaacSim/tree/develop/.claude/skills/isaac-sim-rendering -g -y

不安装直接使用

npx skills use isaac-sim/IsaacSim@isaac-sim-rendering

指定 Agent (Claude Code)

npx skills add isaac-sim/IsaacSim --skill isaac-sim-rendering -a claude-code -g -y

安装 repo 全部 skill

npx skills add isaac-sim/IsaacSim --all -g -y

预览 repo 内 skill

npx skills add isaac-sim/IsaacSim --list

SKILL.md

Frontmatter
{
    "name": "isaac-sim-rendering",
    "license": "Apache-2.0",
    "metadata": {
        "author": "Renato Gasoto <info@nvidia.com>"
    },
    "description": "Headless RT2\/PathTracing production rendering with ACES tuning. Use when capturing frames or validating render quality."
}

Isaac Sim Headless Rendering (Kit 110 / Isaac Sim 6.0+)

Purpose

Capture production-quality headless frames with RT2 or PathTracing, ACES tone mapping, warehouse lighting patterns, and quantitative validation thresholds.

Prerequisites

  • Built Isaac Sim ($ISAAC_SIM_DIR or _build/linux-x86_64/release).
  • NVIDIA GPU with a current driver (nvidia-smi).
  • Shell env contract from isaac-sim-orchestrator: $ISAAC_SIM_DIR, $ISAAC_LAB_DIR, $WORKSPACE_DIR.

Limitations

  • Targets Isaac Sim 6 / Kit 110 unless a section states otherwise.
  • Does not replace official NVIDIA documentation for unsupported edge cases.

Troubleshooting

Error / symptom Cause Solution
Extension or import not found Wrong $ISAAC_SIM_DIR or stale build Point env vars at _build/linux-x86_64/release or rebuild
Black or empty frames Missing lights or non-RTX render mode Add dome/key light; confirm RTX / PathTracing settings
Hang on stage load or first render MDL compile or oversized stage Follow isolation steps in isaac-sim-troubleshooting

Capture pipeline, lighting recipes, ACES calibration, camera math, validation. Host-agnostic; adapt paths to your environment.

Available Scripts

Script Purpose Arguments
scripts/capture_pipeline.py Standard Kit 110 / Isaac Sim 6.0+ headless capture pipeline see script --help
scripts/look_at_camera.py Look-at camera math for USD cameras (Z-up, USD -Z forward convention) see script --help
scripts/warehouse_lighting.py Multi-layer warehouse lighting recipes for headless Isaac Sim rendering see script --help

Running scripts

From agent runtimes that expose skill execution helpers, invoke helpers with run_script():

run_script("scripts/capture_pipeline.py", args=["--help"])

From a built Isaac Sim tree, run the same file with ./python.sh (Linux) or python.bat (Windows) from _build/*/release, or execute shell helpers directly when they do not require the simulator.

Read first

  • navigation-primitives: look-at chase camera math (cross-referenced).

Capture: SimulationApp + Replicator RGB Annotator

Standard Kit 110 / Isaac Sim 6.0+ capture pipeline. Works headless including on ARM64 / GB10 Spark (the older 5.1.0 black-frame bug is resolved).

setup_capture_pipeline(stage_path, width, height, renderer, settle_frames) — open stage, define camera, attach RGB annotator, settle, return (app, rgb_annot, render_product). capture_frame(rgb_annot) — step replicator and return (H, W, 3) uint8 RGB array.

See scripts/capture_pipeline.py.

For live controller demos where simulation remains the time authority, disable Replicator capture-on-play and capture snapshots without pausing the timeline. See scripts/capture_pipeline.py for the executable pattern.

Inside a Python-server file that is otherwise synchronous, avoid the sync rep.orchestrator.step() call in live Kit. Schedule step_async(...) and pump app_utils.update_app() until the task completes; this prevents event-loop reentrancy failures while still advancing the render product.

Capture method choice:

  • omni.replicator.core RGB annotator -> reliable, supports any resolution.
  • RtxCamera + CameraSensor (from isaacsim.sensors.experimental.rtx) for tick-rate control, OpenCV / fisheye lens distortion, ISP, tiled multi-view, or stereo depth (see isaac-camera).
  • Swapchain capture -> also works on Kit 110 if you explicitly set window size matching the render resolution.
  • Replicator render products may return empty arrays for Gaussian splat scenes; fall back to swapchain capture in that case.

RT2 vs PathTracing

settings.set("/rtx/rendermode", "RayTracedLighting")  # RT2 — real-time
# settings.set("/rtx/rendermode", "PathTracing")      # offline only
Mode Convergence Per-frame time Use for
RayTracedLighting (RT2) ~200 settle frames (~10-15s) 10-15s All iterative work, warehouse scenes, training data
PathTracing converges over many subframes 5-30 min Final hero shots only, when explicitly requested

Default to RT2. Switch to PathTracing only after RT2 has been calibrated and the user asks for hero quality.

Headless Lighting — Add Explicit Lights

Headless Isaac Sim has NO default lighting. Without explicit lights, frames are black (RGB=0). Always inject at least a DomeLight + DistantLight baseline.

from pxr import UsdLux, UsdGeom, Gf

dome = UsdLux.DomeLight.Define(stage, "/World/DomeLight")
dome.GetIntensityAttr().Set(400.0)

sun = UsdLux.DistantLight.Define(stage, "/World/Sun")
sun.GetIntensityAttr().Set(1500.0)
UsdGeom.Xformable(sun.GetPrim()).AddRotateXYZOp().Set(Gf.Vec3f(-50, 20, 0))

Baseline Intensity Guide

Scene Type DomeLight DistantLight Notes
Warehouse (default) 400 1500 Good general balance
Close-up robot 300 1200 Slightly softer
Outdoor 500 2000 Brighter sun
Dark/moody 100 800 Dramatic shadows

ACES Tone Mapping — The Single Biggest Quality Lever

Without ACES, no amount of intensity tuning produces balanced indoor renders. This is the single most impactful render setting after lighting.

import carb
s = carb.settings.get_settings()

s.set("/rtx/post/tonemap/op", 4)            # ACES
s.set("/rtx/post/tonemap/filmIso", 600.0)   # key parameter (see table)
s.set("/rtx/post/tonemap/whitepoint", 6500.0)
s.set("/rtx/post/tonemap/enabled", True)
s.set("/rtx/post/aa/op", 3)                 # TAA for RT2

filmIso Calibration (validated on warehouse interiors)

Scene filmIso Notes
General warehouse RT2 200 Photorealistic starting point
Deep-aisle indoor (hero camera) 600 Best balance across hero/overview/aisle/topdown
Aerial/overview-heavy 400 Avoid overexposure on open views

Anti-Recipes (don't waste time on these)

  • Wide rect lights (width=5+) → flat, no light pools
  • High dome intensity (400+) with ACES filmIso 600 → washes out shadows
  • Reinhard tonemapping → muddy, low contrast
  • PathTracing for iterative work → 5-30 min per frame, kills velocity

Warehouse Lighting Recipe (proven 7/10 → 9/10)

The biggest single quality improvement came from this lighting + fog recipe.

add_warehouse_lighting(stage, n_lights, settings) — low-ambient dome + focused rect lights + optional fog. Pass settings=carb.settings.get_settings() to enable fog.

See scripts/warehouse_lighting.py.

For 40m warehouse: fog density 0.003 adds depth without murk.

Deep-Aisle Indoor Lighting

Problem

Ground-level camera in narrow aisle = black frame (82KB / mean_RGB < 5). Ceiling rect lights at Z=10m can't illuminate a 3.5m-wide × 8m-tall aisle to ground level — RT2 struggles with deep occlusion.

Solution: Multi-Layer Lighting

# Layer 1: dense ceiling grid (6×12 across facility)
# Rect lights at ceil_z-0.3, pointing down
# intensity=200000, width=4.0, height=3.0  (wide coverage)

# Layer 2: low sphere lights IN each aisle at Z=3.5m (head-height)
# Directly in camera FOV between tier 1 and ground
for aisle_y, lx in aisle_light_positions:
    lt = UsdLux.SphereLight.Define(stage, lp)
    lt.GetRadiusAttr().Set(0.15)
    lt.GetIntensityAttr().Set(100000.0)
  • 500 settle frames for indoor aisle scenes (not 200-300)
  • Dome at 300 intensity is optional ambient fill — don't go higher or open views wash out

Dome vs Deep-Aisle Tension (fundamental conflict in enclosed scenes)

  • High dome → overview/topdown overexpose (mean > 220)
  • Low/no dome → deep aisle underexpose (mean < 10)
  • Best balance: no dome + sphere lights in aisles + 500K rect grids + 500 settle frames
    • Hero aisle: mean ~60
    • Overview (elevated 3/4): mean ~140-175
    • Cross-aisle: mean ~230

Validated ACES filmIso=600 Light Intensities

  • Ceiling rect lights: 70,000 intensity, 2.5×1.5m, warm white (1.0, 0.97, 0.92)
  • Aisle sphere lights: 15,000 intensity, radius=0.1, at Z=3.5m
  • Grid: 8×14 ceiling panels
  • No dome light — ACES handles exposure
  • Result: mean 60–155 across all view types

Camera tip: place "hero" camera at cross-aisle intersections, not deep in narrow aisles. The junction has more open space for light to reach.

Frame Quality Validation

Always validate captured frames before delivery. Don't ship black/overexposed frames.

Indicator Meaning Action
File ~82KB Black frame (RGBA padding only) Add explicit lights
File 200–500KB Partial render / very simple scene Check settle frames
File 1–2MB Full rendered frame OK
rgb.max() == 0 No lighting reaching camera Add DomeLight + DistantLight
rgb.max() > 200, mean 60–180 Good render OK
rgb.mean() > 220 Overexposed Reduce light intensity or filmIso
rgb.mean() < 10 Underexposed Add aisle-level lights or raise filmIso
import numpy as np
def validate_frame(rgb_array):
    """Returns (ok: bool, reason: str)."""
    if rgb_array.max() == 0:
        return False, "no light reaches camera — add DomeLight + DistantLight"
    if rgb_array.mean() > 220:
        return False, f"overexposed (mean={rgb_array.mean():.0f}) — reduce intensity"
    if rgb_array.mean() < 10:
        return False, f"underexposed (mean={rgb_array.mean():.0f}) — add aisle lights"
    return True, f"ok (mean={rgb_array.mean():.0f}, max={rgb_array.max()})"

Look-At Camera Math

For chase/POV/overview cameras pointing at a target, always use a look-at matrix. Don't hand-tune Euler angles — they're brittle and you'll waste hours on sign flips.

look_at_matrix(eye, target, up) — returns Gf.Matrix4d for a USD camera at eye looking at target. Handles degenerate up-vector (straight down/up).

See scripts/look_at_camera.py.

Third-Person Camera Offsets (Z-up, robot facing +X at yaw=0)

Direction Vector
Behind robot -X
Right of robot -Y
Left of robot +Y
Above robot +Z
import math

behind_dir_x = -math.cos(yaw)
behind_dir_y = -math.sin(yaw)
right_dir_x  = -math.sin(yaw)
right_dir_y  =  math.cos(yaw)

cam_x = robot_x + behind_dist * behind_dir_x + side_offset * right_dir_x
cam_y = robot_y + behind_dist * behind_dir_y + side_offset * right_dir_y
cam_z = height
  • side_offset = -2.5 → camera on robot's right
  • side_offset = +2.5 → camera on robot's left
  • Flip the offset value to change sides, NOT the trig signs.

Dynamic Camera Height (Obstacle Avoidance)

When tracking through cluttered environments, the chase camera will clip into tall geometry. Pre-compute obstacle bboxes, then raise the camera each frame as needed.

# Build obstacle lookup from USD geometry once at startup
obstacles = []
for prim in stage.Traverse():
    if prim.IsA(UsdGeom.Cube):
        # ... extract (xmin, xmax, ymin, ymax, height) ...
        obstacles.append((xmin, xmax, ymin, ymax, height))

def cam_max_height_at(cx, cy, margin=0.5):
    """Highest obstacle near (cx, cy). Camera must clear this."""
    return max((h for xmn, xmx, ymn, ymx, h in obstacles
                if xmn-margin <= cx <= xmx+margin and ymn-margin <= cy <= ymx+margin),
               default=0.0)

# Per-frame:
target_h = max(base_height, cam_max_height_at(cam_x, cam_y) + 1.0)
smooth_h = smooth_h * 0.95 + target_h * 0.05   # smooth transitions

Robot XformOp Discipline

URDF-imported robots (Spot, Carter, etc.) already have authored translate + orient + scale xformOps on the root prim.

  • Use xf.ClearXformOpOrder(); xf.MakeMatrixXform() on the root prim only for initial placement.
  • Never add ops to child body/link prims — physics drives those.

Video Assembly

ffmpeg -y -framerate 30 -i frames/frame_%05d.png \
  -c:v libx264 -pix_fmt yuv420p -crf 18 output.mp4

Frame numbering must be sequential (frame_0000.png, frame_0001.png, …) — ffmpeg skips gaps.

Session Management

For batch/iterative rendering, keep the Kit app running and switch stages in-place rather than restarting:

  • Cold start = 5-7 min wasted
  • Persistent session = 10-15s per render
  • Use stage_utils.open_stage(path) (isaacsim.core.experimental.utils.stage) to switch scenes
  • Only restart Kit if it crashes or hits OOM

Implementation is up to you (REPL, command file, IPC, etc.) — the principle is "don't pay the cold-start cost more than once."

Checklist Before Delivering Renders

  1. RT2 enabled (/rtx/rendermode = RayTracedLighting)
  2. ACES tone mapping enabled (/rtx/post/tonemap/op = 4)
  3. filmIso calibrated for scene type (200 general / 400 aerial-heavy / 600 deep-aisle)
  4. Explicit DomeLight + DistantLight (or scene-specific multi-layer setup)
  5. Settle frames sufficient (200 standard / 500 deep-aisle)
  6. Frame validation passed (rgb.mean() in 30-200 range, file size > 200KB)
  7. Frame sequence is gapless for ffmpeg

Integration Points

  • RECEIVES from: urdf-mjcf-to-usd-conversion, usd-articulation, mobility-gen, isaac-sim-robot-navigation — populated stages to render
  • PRODUCES for: data-collection-sim — validated frame sequences for SDG
  • PRODUCES for: isaac-sim-validator — outputs for final QA gate

版本历史

  • 2469084 当前 2026-09-22 15:45

同 Skill 集合

.claude/skills/action-and-event-data-generation/SKILL.md
.claude/skills/actor-sdg-generate-lighting-variations/SKILL.md
.claude/skills/actor-sdg-sweep-config/SKILL.md
.claude/skills/behavior-tree-generation/SKILL.md
.claude/skills/calibrate-metropolis-camera/SKILL.md
.claude/skills/data-collection-sim/SKILL.md
.claude/skills/generate-incident-config/SKILL.md
.claude/skills/isaac-camera/SKILL.md
.claude/skills/isaac-sim-assets/SKILL.md
.claude/skills/isaac-sim-headless-deployment/SKILL.md
.claude/skills/isaac-sim-installation/SKILL.md
.claude/skills/isaac-sim-migration/SKILL.md
.claude/skills/isaac-sim-orchestrator/SKILL.md
.claude/skills/isaac-sim-remote/SKILL.md
.claude/skills/isaac-sim-robot-navigation/SKILL.md
.claude/skills/isaac-sim-ros-workspaces/SKILL.md
.claude/skills/isaac-sim-ros2-bridge/SKILL.md
.claude/skills/isaac-sim-sensor/SKILL.md
.claude/skills/isaac-sim-troubleshooting/SKILL.md
.claude/skills/isaac-sim-validator/SKILL.md
.claude/skills/isaac-sim-workflow/SKILL.md
.claude/skills/manipulation-ik/SKILL.md
.claude/skills/meta-skills/SKILL.md
.claude/skills/mobility-gen/SKILL.md
.claude/skills/motion-generation/SKILL.md
.claude/skills/navigation-primitives/SKILL.md
.claude/skills/object-bin-packing/SKILL.md
.claude/skills/occupancy-map/SKILL.md
.claude/skills/physics-simulation/SKILL.md
.claude/skills/place-camera-aim-at/SKILL.md
.claude/skills/place-camera-max-coverage/SKILL.md
.claude/skills/profile-isaac-sim/SKILL.md
.claude/skills/run-incident-events/SKILL.md
.claude/skills/skill-distillation/SKILL.md
.claude/skills/skills-eval-triage/SKILL.md
.claude/skills/spatial-reasoning/SKILL.md
.claude/skills/urdf-mjcf-to-usd-conversion/SKILL.md
.claude/skills/usd-articulation/SKILL.md
.claude/skills/usd-composition-architecture/SKILL.md
.claude/skills/usd-pipeline/SKILL.md
.claude/skills/validation-diff-gifs/SKILL.md
.claude/skills/vlm-scene-captioning/SKILL.md
skills/action-and-event-data-generation/SKILL.md
skills/actor-sdg-generate-lighting-variations/SKILL.md
skills/actor-sdg-sweep-config/SKILL.md
skills/behavior-tree-generation/SKILL.md
skills/calibrate-metropolis-camera/SKILL.md
skills/data-collection-sim/SKILL.md
skills/generate-incident-config/SKILL.md

元信息

文件数
0
版本
2469084
Hash
39dae5b2
收录时间
2026-09-22 15:45

首页 - Wiki
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-09-26 03:38
浙ICP备14020137号-1