agentsclimarketplace

Axiom scenekit ref

Skill ComeOnOliver/skillshub/skills/CharlesWiltgen/Axiom/axiom-scenekit-ref

SceneKit → RealityKit concept mapping, complete API cross-reference for migration, scene graph API, materials, lighting, camera, physics, animation, constraintsFrom its SKILL.md

Install
npx -y skills add ComeOnOliver/skillshub --skill axiom-scenekit-ref

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

What its file declares

Copied from the file, not written here

The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.

SKILL.md

13.1 KB, ~3.4k tokens by cl100k_base, as published. Nobody here has run it

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<Float>
node.eulerAnglesentity.orientation (quaternion)RealityKit prefers quaternions
node.scaleentity.scaleBoth SIMD3<Float>
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

What ships with it

Read from the repository

Just SKILL.md. No reference files, no scripts.

Keep looking

Skills are one crate of 325,949. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.