mcpField
A
axiom-scenekit-ref

axiom-scenekit-ref

github.com/charleswiltgenDevelopment1.2k130 installsUpdated today
Repository

About axiom-scenekit-ref

An API reference for SceneKit developers, with mappings to RealityKit concepts and coverage of major APIs. It supports migration planning by showing equivalents as well as areas that require a different implementation.

Key features

  1. 01SceneKit-to-RealityKit concept mapping
  2. 02Scene graph and transform reference
  3. 03Material and lighting comparisons
  4. 04Physics API mappings
  5. 05Animation and interaction references
  6. 06AR integration mappings

Use cases

  1. 01Finding RealityKit equivalents during migration
  2. 02Checking SceneKit class properties and methods
  3. 03Planning replacements for SceneKit features
  4. 04Comparing scene graph and ECS designs

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/charleswiltgen/axiom --skill axiom-scenekit-ref

After installing, type/axiom-scenekit-refin Claude Code to confirm it loaded.

Details

From the project README

SceneKit API Reference & Migration Mapping

Complete API reference for SceneKit with RealityKit equivalents for every major concept.

When to Use This Reference

Use this reference when:

  • Looking up SceneKit → RealityKit API equivalents during migration
  • Checking specific SceneKit class properties or methods
  • Planning which SceneKit features have direct RealityKit counterparts
  • Understanding architectural differences between scene graph and ECS

Part 1: SceneKit → RealityKit Concept Mapping

Core Architecture
SceneKitRealityKitNotes
SCNSceneRealityViewContent / Entity (root)RealityKit scenes are entity hierarchies
SCNNodeEntityLightweight container in both
SCNViewRealityView (SwiftUI)ARView for UIKit on iOS
SceneView (SwiftUI)RealityViewSceneView deprecated iOS 26
SCNRendererRealityRendererLow-level Metal rendering
Node propertiesComponentsECS separates data from hierarchy
SCNSceneRendererDelegateSystem / SceneEvents.UpdateFrame-level updates
.scn files.usdz / .usda filesConvert with xcrun scntool
Geometry & Rendering
SceneKitRealityKitNotes
SCNGeometryMeshResourceRealityKit generates from code or loads USD
SCNBox, SCNSphere, etc.MeshResource.generateBox(), .generateSphere()Similar built-in shapes
SCNMaterialSimpleMaterial, PhysicallyBasedMaterialPBR-first in RealityKit
SCNMaterial.lightingModel = .physicallyBasedPhysicallyBasedMaterialDefault in RealityKit
SCNMaterial.diffusePhysicallyBasedMaterial.baseColorDifferent property name
SCNMaterial.metalnessPhysicallyBasedMaterial.metallicDifferent property name
SCNMaterial.roughnessPhysicallyBasedMaterial.roughnessSame concept
SCNMaterial.normalPhysicallyBasedMaterial.normalSame concept
Shader modifiersShaderGraphMaterial / CustomMaterialNo direct port — must rewrite
SCNProgram (custom shaders)CustomMaterial with Metal functionsDifferent API surface
SCNGeometrySourceMeshResource.ContentsLow-level mesh data
Transforms & Hierarchy
SceneKitRealityKitNotes
node.positionentity.positionBoth SCNVector3 / SIMD3
node.eulerAnglesentity.orientation (quaternion)RealityKit prefers quaternions
node.scaleentity.scaleBoth SIMD3
node.transformentity.transform4×4 matrix
node.worldTransformentity.transform(relativeTo: nil)World-space transform
node.addChildNode(_:)entity.addChild(_:)Same hierarchy concept
node.removeFromParentNode()entity.removeFromParent()Same concept
node.childNodesentity.childrenChildren collection
node.parententity.parentParent reference
node.childNode(withName:recursively:)entity.findEntity(named:)Named lookup
Lighting
SceneKitRealityKitNotes
SCNLight (.omni)PointLightComponentPoint light
SCNLight (.directional)DirectionalLightComponentSun/directional light
SCNLight (.spot)SpotLightComponentCone light
SCNLight (.area)No direct equivalentUse multiple point lights
SCNLight (.ambient)EnvironmentResource (IBL)Image-based lighting preferred
SCNLight (.probe)EnvironmentResourceEnvironment probes
SCNLight (.IES)No direct equivalentUse light intensity profiles
Camera
SceneKitRealityKitNotes
SCNCameraPerspectiveCamera entityEntity with camera component
camera.fieldOfViewPerspectiveCameraComponent.fieldOfViewInDegreesSame concept
camera.zNear / camera.zFarPerspectiveCameraComponent.near / .farClipping planes
camera.wantsDepthOfFieldPost-processing effectsDifferent mechanism
camera.motionBlurIntensityPost-processing effectsDifferent mechanism
allowsCameraControlCustom gesture handlingNo built-in orbit camera
Physics
SceneKitRealityKitNotes
SCNPhysicsBodyPhysicsBodyComponentComponent-based
.dynamic.dynamicSame mode
.static.staticSame mode
.kinematic.kinematicSame mode
SCNPhysicsShapeCollisionComponent / ShapeResourceSeparate from body in RealityKit
categoryBitMaskCollisionGroupNamed groups vs raw bitmasks
collisionBitMaskCollisionFilterFilter-based
contactTestBitMaskCollisionEvents.Began subscriptionEvent-based contacts
SCNPhysicsContactDelegatescene.subscribe(to: CollisionEvents.Began.self)Combine-style events
SCNPhysicsFieldPhysicsBodyComponent forcesApply forces directly
SCNPhysicsJointPhysicsJointSimilar joint types
Animation
SceneKitRealityKitNotes
SCNActionentity.move(to:relativeTo:duration:)Transform animation
SCNAction.sequenceAnimation chainingLess declarative in RealityKit
SCNAction.groupParallel animationsApply to different entities
SCNAction.repeatForeverAnimationPlaybackController repeatDifferent API
SCNTransaction (implicit)No direct equivalentExplicit animations only
CAAnimation bridgeentity.playAnimation()Load from USD
SCNAnimationPlayerAnimationPlaybackControllerPlayback control
Morph targetsBlend shapes in USDLoad via USD files
Interaction
SceneKitRealityKitNotes
hitTest(_:options:)RealityViewContent.entities(at:)Different API
Gesture recognizers on SCNViewManipulationComponentBuilt-in drag/rotate/scale
allowsCameraControlCustom implementationNo built-in orbit
AR Integration
SceneKitRealityKitNotes
ARSCNViewRealityView + AnchorEntityLegacy → modern
ARSCNViewDelegateAnchorEntity auto-trackingEvent-driven
renderer(_:didAdd:for:)AnchorEntity(.plane)Declarative anchoring
ARWorldTrackingConfigurationSpatialTrackingSessioniOS 18+

Part 2: Scene Graph API

SCNScene
// Loading
let scene = SCNScene(named: "scene.usdz")!
let scene = try SCNScene(url: url, options: [
    .checkConsistency: true,
    .convertToYUp: true
])

// Properties
scene.rootNode                    // Root of node hierarchy
scene.background.contents        // Skybox (UIImage, UIColor, MDLSkyCubeTexture)
scene.lightingEnvironment.contents // IBL environment map
scene.fogStartDistance            // Fog near
scene.fogEndDistance              // Fog far
scene.fogColor                   // Fog color
scene.isPaused                   // Pause simulation
SCNNode
// Creation
let node = SCNNode()
let node = SCNNode(geometry: SCNBox(width: 1, height: 1, length: 1, chamferRadius: 0))

// Transform
node.position = SCNVector3(x, y, z)
node.eulerAngles = SCNVector3(pitch, yaw, roll)
node.scale = SCNVector3(1, 1, 1)
node.simdPosition = SIMD3<Float>(x, y, z)  // SIMD variants available
node.pivot = SCNMatrix4MakeTranslation(0, -0.5, 0) // Offset pivot point

// Visibility
node.isHidden = false
node.opacity = 1.0
node.castsShadow = true
node.renderingOrder = 0   // Lower = rendered first

// Hierarchy
node.addChildNode(child)
node.removeFromParentNode()
node.childNodes
node.childNode(withName: "name", recursively: true)
node.enumerateChildNodes { child, stop in }

Part 3: Materials

Lighting Models
ModelDescriptionUse Case
.physicallyBasedPBR metallic-roughnessRealistic rendering (recommended)
.blinnBlinn-Phong specularSimple shiny surfaces
.phongPhong specularClassic specular highlight
.lambertDiffuse only, no specularMatte surfaces
.constantUnlit, flat colorUI elements, debug visualization
.shadowOnlyInvisible, receives shadowsAR ground plane
Material Properties
let mat = SCNMaterial()
mat.lightingModel = .physicallyBased

// Textures or scalar values
mat.diffuse.contents = UIImage(named: "albedo")    // Base color
mat.metalness.contents = 0.0                        // 0 = dielectric, 1 = metal
mat.roughness.contents = 0.5                        // 0 = mirror, 1 = rough
mat.normal.contents = UIImage(named: "normal")      // Normal map
mat.ambientOcclusion.contents = UIImage(named: "ao") // AO map
mat.emission.contents = UIColor.blue                // Glow
mat.displacement.contents = UIImage(named: "height") // Height map

// Options
mat.isDoubleSided = false        // Render both sides
mat.writesToDepthBuffer = true
mat.readsFromDepthBuffer = true
mat.blendMode = .alpha           // .add, .subtract, .multiply, .screen
mat.transparencyMode = .aOne     // .rgbZero for pre-multiplied alpha

Part 4: Physics

Body Types and Properties
// Dynamic body with custom shape
let shape = SCNPhysicsShape(geometry: SCNSphere(radius: 0.5), options: nil)
let body = SCNPhysicsBody(type: .dynamic, shape: shape)
body.mass = 1.0
body.friction = 0.5
body.restitution = 0.3       // Bounciness
body.damping = 0.1            // Linear damping
body.angularDamping = 0.1     // Angular damping
body.isAffectedByGravity = true
body.allowsResting = true     // Sleep optimization
node.physicsBody = body

// Compound shapes
let compound = SCNPhysicsShape(shapes: [shape1, shape2],
    transforms: [transform1, transform2])

// Concave (static only)
let concave = SCNPhysicsShape(geometry: mesh, options: [
    .type: SCNPhysicsShape.ShapeType.concavePolyhedron
])
Joint Types
JointDescription
SCNPhysicsHingeJointSingle-axis rotation (door)
SCNPhysicsBallSocketJointFree rotation around point (pendulum)
SCNPhysicsSliderJointLinear movement along axis (drawer)
SCNPhysicsConeTwistJointLimited rotation (ragdoll limb)

Part 5: Animation API

SCNAction Catalog
CategoryActions
Movementmove(by:duration:), move(to:duration:)
Rotationrotate(by:around:duration:), rotateTo(x:y:z:duration:)
Scalescale(by:duration:), scale(to:duration:)
FadefadeIn(duration:), fadeOut(duration:), fadeOpacity(to:duration:)
Visibilityhide(), unhide()
AudioplayAudio(source:waitForCompletion:)
Customrun { node in }, customAction(duration:action:)
Compositionsequence([]), group([]), repeat(_:count:), repeatForever(_:)
Controlwait(duration:), removeFromParentNode()
Timing Functions
action.timingMode = .linear        // Default
action.timingMode = .easeIn        // Slow start
action.timingMode = .easeOut       // Slow end
action.timingMode = .easeInEaseOut // Slow start and end
action.timingFunction = { t in     // Custom curve
    return t * t  // Quadratic ease-in
}

Part 6: Constraints

ConstraintPurpose
SCNLookAtConstraintNode always faces target
SCNBillboardConstraintNode always faces camera
SCNDistanceConstraintMaintains min/max distance
SCNReplicatorConstraintCopies transform of target
SCNAccelerationConstraintSmooths transform changes
SCNSliderConstraintLocks to axis
SCNIKConstraintInverse kinematics chain
let lookAt = SCNLookAtConstraint(target: targetNode)
lookAt.isGimbalLockEnabled = true  // Prevent roll
lookAt.influenceFactor = 0.8       // Partial constraint
node.constraints = [lookAt]

In RealityKit: No direct constraint system. Implement with System update logic or entity.look(at:from:relativeTo:).


Part 7: Scene Configuration

SCNView Configuration
PropertyDefaultDescription
antialiasingMode.multisampling4XMSAA level
preferredFramesPerSecond60Target frame rate
allowsCameraControlfalseBuilt-in orbit/pan/zoom
autoenablesDefaultLightingfalseAdd default light if none
showsStatisticsfalseFPS/node/draw count overlay
isTemporalAntialiasingEnabledfalseTAA smoothing
isJitteringEnabledfalseTemporal jitter for TAA
debugOptions[].showPhysicsShapes, .showBoundingBoxes, .renderAsWireframe

Resources

WWDC: 2014-609, 2014-610, 2017-604, 2019-612

Docs: /scenekit, /scenekit/scnscene, /scenekit/scnnode, /scenekit/scnmaterial, /scenekit/scnphysicsbody, /scenekit/scnaction

Skills: axiom-scenekit, axiom-realitykit, axiom-realitykit-ref

Comments

Markdown supported