A Swift package for Apple-native 3D viewport UI built on RealityKit.
What is RealityKit?
RealityKit is Apple's high-performance 3D rendering framework designed for AR and spatial computing experiences. It runs natively across iOS, iPadOS, macOS, and visionOS, providing:
- Real-time physically-based rendering (PBR)
- AR-specific features (anchoring, occlusion, plane detection)
- Entity-Component-System (ECS) architecture
- Tight integration with SwiftUI and Reality Composer Pro
About This Package
StageView provides the RealityKit implementation and shared overlay layer used by RealityKit-based stage viewers. It owns viewport-specific affordances such as procedural grids, overlays, IBL controls, scale indicators, and RealityKit pick remapping.
OpenUSD inspection, editing, validation, and material semantics belong in OpenUSDKit and SwiftUsdShell. StageView stays focused on the viewport experience and can be used without linking the OpenUSDKit product surface.
- Dynamic Grid: Scale-aware grid that extends based on scene size (1 meter = 1 meter always)
- Viewport Material Assets: Shader graph recipes for RealityKit viewport affordances such as the generated grid material
- IBL Support: Environment lighting with EV-style exposure control
- Scale Indicator: Auto-switching scale reference (cm/m/km) based on scene size
- Colored Axes: Visual axis indicators (X=red, Y=green, Z=blue)
- Selection Remapping Hooks: Upgrade coarse imported pick results to semantic scene paths
Shared SwiftUI overlay primitives with no RealityKit dependency:
ViewportOverlayCollection- Anchored overlay items for viewport chromeScaleIndicatorView- SwiftUI scale referenceOrientationGizmoView- Camera-aware orientation indicatorStageViewOverlayContext- Shared overlay context passed to built-in and custom overlay views
RealityKit implementation:
RealityKitStageView- Full RealityKit viewport viewRealityKitProvider- Observable runtime owner for loaded entities, camera state, and selectionRealityKitGrid- Dynamic grid with metersPerUnit supportRealityKitIBL- IBL handling with proper exposure conversionViewportGridMaterialSpec/ViewportGridMaterialAssetRecipe- Generated USDA shader graph assets for the RealityKit viewport grid
When to Use This Package:
- Building AR experiences on Apple platforms
- Need tight SwiftUI integration
- Want Apple-native performance and features
- Working with Reality Composer Pro content
When to Consider Hydra Instead:
- Need high-fidelity OpenUSD rendering
- Require viewport features like Storm/HdRpr renderers
- Working with complex USD pipelines from DCC tools
- Need pixel-accurate USD preview
For OpenUSD rendering with Hydra, see the companion package: StageViewHydra
Hydra is Pixar's rendering architecture from OpenUSD that provides production-quality viewport rendering. StageViewHydra owns the Hydra viewport, including viewport reload preparation for Hydra-compatible USD stages. It has a heavier dependency stack (SwiftUsd, SwiftUsdShell, and OpenUSD), while StageView stays lightweight for RealityKit use cases.
Add to your Package.swift:
dependencies: [
.package(url: "https://github.com/Reality2713/StageView.git", from: "0.3.23"),
]Then add the products to your target:
.target(
name: "YourTarget",
dependencies: [
.product(name: "StageViewOverlay", package: "StageView"),
.product(name: "RealityKitStageView", package: "StageView"),
]
),import RealityKitStageView
let grid = await RealityKitGrid.createProceduralGridEntity(
metersPerUnit: 0.01, // Scene in centimeters
worldExtent: 10.0, // Scene size
isZUp: false, // Y-up coordinate system
appearance: .dark
)import RealityKitStageView
let spec = ViewportGridMaterialSpec(theme: .dark)
let asset = try ViewportGridMaterialAssetRecipe().makeAsset(from: spec)
try asset.contents.write(to: outputURL, atomically: true, encoding: .utf8)The generated asset is a viewport concern. It intentionally lives in StageView rather than OpenUSDKit because it describes RealityKit viewport chrome, not reusable USD material authoring semantics.
import StageViewOverlay
ScaleIndicatorView(
referenceDepthMeters: 2.0,
viewportWidthPoints: 900
)import RealityKitStageView
var configuration = RealityKitConfiguration()
configuration.environmentMapURL = URL(fileURLWithPath: "/path/to/studio.hdr")
configuration.environmentExposure = 0.0 // EV-style: 0 = neutral
configuration.showEnvironmentBackground = trueIf RealityKit collapses imported geometry into generic entities such as
merged_1, consumers can provide stronger scene-aware remapping:
import RealityKitStageView
let provider = RealityKitProvider()
provider.setPickPathOverrides([
"/RootNode/merged_1": "/RootNode/Forklift"
])
provider.setPickPathResolver { directPath, entity, provider in
guard directPath == "/RootNode/merged_1" else { return nil }
return "/RootNode/Forklift/Body"
}StageView applies consumer overrides first, then its built-in generic merged
node fallback, then the direct imported mapping.
For the full mapping model used by RealityKitStageView, including:
- duplicate
_1/_2suffix handling - generic importer bucket names such as
merged_1 - the distinction between direct mapping, selection mapping, and pick mapping
- why visibility projection must be more conservative than selection
see:
- macOS 15.0+
- iOS 18.0+
- iPadOS 18.0+
- visionOS 2.0+
- Swift 6.0+
- StageViewHydra - Hydra/OpenUSD viewport implementation
- OpenUSDKit - USD capability layer for inspection, editing, validation, variants, materials, and asset workflows
- SwiftUsdShell - Typed shell over SwiftUsd/OpenUSD primitives
- RealityKit - Apple's 3D rendering framework
- Reality Composer Pro - Apple's USD authoring tool
MIT License
