{ "$schema": "https://raw.githubusercontent.com/guitaripod/wwdc-sessions/master/schema/session.schema.json", "schemaVersion": 1, "id": "wwdc2026-279", "event": "wwdc2026", "eventName": "WWDC26", "year": 2026, "eventContentId": 279, "title": "Explore advances in RealityKit", "description": "Discover the latest advancements in RealityKit designed to make your apps and games more immersive and realistic than ever. Explore powerful new capabilities including interactive cloth simulations, NavMesh pathfinding, mixed reality lighting, and customizable reverb meshes for enhanced spatial audio. Elevate your visual fidelity with improved shadows, character rendering enhancements, and support for Gaussian splatting.", "url": "https://developer.apple.com/videos/play/wwdc2026/279", "sosumiURL": "https://sosumi.ai/videos/play/wwdc2026/279", "type": "Video", "publishedAt": "2026-06-08T14:00:00-07:00", "platforms": [ "iOS", "iPadOS", "macOS", "tvOS", "visionOS" ], "keywords": [ "3d content", "games", "gaussian splatting", "reality composer pro", "realitykit", "realitykit audio", "spatial computing", "visionos" ], "topics": [ "Graphics & Games", "Spatial Computing" ], "primaryTopic": "Spatial Computing", "duration": 1431, "hasTranscript": true, "transcriptWordCount": 3896, "availableLanguages": [ "eng", "fra", "jpn", "kor", "por", "spa", "zho" ], "media": { "hls": "https://devstreaming-cdn.apple.com/videos/wwdc/2026/279/4/ab575725-be7d-4348-a3ae-6595ef4070c4/cmaf.m3u8", "downloadHLS": "https://devstreaming-cdn.apple.com/videos/wwdc/2026/279/4/ab575725-be7d-4348-a3ae-6595ef4070c4/cmaf-download.m3u8", "downloadSD": "https://devstreaming-cdn.apple.com/videos/wwdc/2026/279/4/ab575725-be7d-4348-a3ae-6595ef4070c4/downloads/wwdc2026-279_sd.mp4", "downloadHD": "https://devstreaming-cdn.apple.com/videos/wwdc/2026/279/4/ab575725-be7d-4348-a3ae-6595ef4070c4/downloads/wwdc2026-279_hd.mp4", "duration": 1431 }, "codeSnippets": [ { "title": "Soft shadows", "language": "swift", "startTimeSeconds": 242, "code": "// Enable soft shadows for the hearth spotlight\n\nguard var shadow = hearthSpotlight.components[SpotLightComponent.Shadow.self] else {\n // handle error\n}\nshadow.lightSize = 0.7 // meters\n\nshadow.quality = .medium // or .high\n// shadow.quality = .low // will result in hard shadows\n\nhearthSpotlight.components.set(shadow)" }, { "title": "Projective textures", "language": "swift", "startTimeSeconds": 373, "code": "// Create one of the planetarium spotlights\n\nlet spotLightEntity = Entity()\nspotLightEntity.components.set(SpotLightComponent(\n color: .white,\n intensity: intensity,\n innerAngleInDegrees: innerAngle,\n outerAngleInDegrees: outerAngle,\n attenuationRadius: attenuationRadius,\n))\n\nlet projectiveTexture: TextureResource = generateStarsAndNebulaeTexture()\nspotLightEntity.components.set(SpotLightComponent.ProjectiveTexture(\n texture: projectiveTexture\n))" }, { "title": "Physical space lighting", "language": "swift", "startTimeSeconds": 433, "code": "// Enable physical space lighting\n\nspotLightEntity.components.set(SpotLightComponent.SurroundingsLight())" }, { "title": "Querying the navigation mesh", "language": "swift", "startTimeSeconds": 586, "code": "// Querying the navigation mesh in Chaparral Village\n\nextension Entity {\n public func navigate(/* ... */) async {\n let navigator = try! NavigationController(entity: self)\n guard let result = await navigator.computePath(from: fromPosition, to: toPosition) \n else {\n return\n }\n if result.isEmpty {\n return\n }\n for node in result {\n switch node.category {\n case .meshPoint:\n finalPath.append(node.position)\n case .offMeshConnection:\n // handle ladders\n }\n }\n }\n}" }, { "title": "Pinning cloth to anchor points", "language": "swift", "startTimeSeconds": 771, "code": "// Pin the curtains to the Alchemist's lab\n\nfor (pin, pinComponent) in pins {\n let position = pin.position(relativeTo: event.entity)\n let selectionSphere = ClothSphereShape(radius: pinComponent.radius)\n\n let vertices = clothMesh.vertices(in: .sphere(selectionSphere),\n center: position)\n clothBody.motionTypes.set(vertexIndices: vertices, value: .kinematic)\n}" }, { "title": "LOD by camera distance", "language": "swift", "startTimeSeconds": 882, "code": "// Create entity with LODs\n\nlet lod0 = [ModelEntity(mesh: lodMesh0)]\nlet lod1 = [ModelEntity(mesh: lodMesh1)]\nlet lod2 = [ModelEntity(mesh: lodMesh2)]\n\nlet entity = Entity()\n\nLevelOfDetailComponent.addByCameraDistance(to: entity, levels: [\n (entities: lod0, maxDistance: 1.0 /* meters */), // highest detail\n (entities: lod1, maxDistance: 5.0), // medium detail\n (entities: lod2, maxDistance: .infinity), // lowest detail\n])" }, { "title": "LOD by screen area", "language": "swift", "startTimeSeconds": 958, "code": "// Create entity with LODs\n\nlet lod0 = [ModelEntity(mesh: lodMesh0)]\nlet lod1 = [ModelEntity(mesh: lodMesh1)]\nlet lod2 = [ModelEntity(mesh: lodMesh2)]\n\nlet entity = Entity()\n\nLevelOfDetailComponent.addByScreenArea(to: entity, levels: [\n (entities: lod0, minArea: 0.2 /* fraction of screen area */), // highest detail\n (entities: lod1, minArea: 0.1), // medium detail\n (entities: lod2, minArea: 0.01), // lowest detail\n])" }, { "title": "Responding to thermal state changes", "language": "swift", "startTimeSeconds": 986, "code": "// Respond to changes in device thermal state\n\nNotificationCenter.default.addObserver(of: ProcessInfo.self,\n for: .thermalStateDidChange) {_ in\n switch ProcessInfo.processInfo.thermalState {\n case .nominal, .fair:\n // Stay the course\n case .serious, .critical:\n // Improve performance by:\n // More aggressive LOD switching\n // Lower shadow quality\n }\n}" }, { "title": "Creating a Gaussian splat", "language": "swift", "startTimeSeconds": 1124, "code": "// Create Gaussian splat resource and component\n\nlet resource = try GaussianSplatResource.BufferResource(count: splatCount,\n position: positionBuffer,\n scale: scaleBuffer,\n rotation: rotationBuffer,\n opacity: opacityBuffer,\n sphericalHarmonics:\n (sphericalHarmonicsBuffer, degree))\n\nlet splatResource = GaussianSplatResource(resource)\n\nlet splatComponent = GaussianSplatComponent(splatResource)\n\nsplatEntity.components.set(splatComponent)" }, { "title": "Creating a custom reverb mesh", "language": "swift", "startTimeSeconds": 1249, "code": "// Create and use custom reverb mesh\n\nlet mesh: ReverbMeshResource = .shoebox(size: [5, 4, 6])\n\nlet reverb: Reverb = .simulated(mesh: mesh, materials: [.dryWall])\n\nentity.components.set(ReverbComponent(reverb: reverb))" }, { "title": "Creating custom reverb materials", "language": "swift", "startTimeSeconds": 1293, "code": "// Create custom materials for custom reverb mesh\n\nlet thickCarpet: Audio.Material = .carpet.scalingAbsorption {freq in 0.1 }\n\nlet bookshelf: Audio.Material\n\n// Absorption coefficients by center frequency:\n// 31.5Hz, 63Hz, 125Hz, 250Hz, 500Hz, 1kHz, 2kHz, 4kHz, 8kHz, 16kHz\nlet bookshelfAbsorption = Audio.Absorption(\n [0.10, 0.15, 0.28, 0.20, 0.15, 0.10, 0.10, 0.07, 0.07, 0.05])\n\n// Scattering coefficients for: 500Hz, 1000Hz, 4000Hz\nlet bookshelfScattering = Audio.Scattering([500: 0.5, 1000: 0.6, 4000: 0.7])\n\nbookshelf = .init(absorption: bookshelfAbsorption,\n scattering: bookshelfScattering)" } ], "resources": [ { "title": "Gaussian splats on visionOS", "url": "https://developer.apple.com/documentation/visionOS/gaussian-splats-on-visionos", "type": "documentation", "description": "Use the new Gaussian splat APIs available in RealityKit in visionOS 27.", "sosumiURL": "https://sosumi.ai/documentation/visionOS/gaussian-splats-on-visionos", "doccJSON": "https://developer.apple.com/tutorials/data/documentation/visionOS/gaussian-splats-on-visionos.json" } ], "path": "sessions/wwdc2026/279-explore-advances-in-realitykit/", "files": { "metadata": "sessions/wwdc2026/279-explore-advances-in-realitykit/metadata.json", "readme": "sessions/wwdc2026/279-explore-advances-in-realitykit/README.md", "transcript": "sessions/wwdc2026/279-explore-advances-in-realitykit/transcript.md", "transcriptJSON": "sessions/wwdc2026/279-explore-advances-in-realitykit/transcript.json" } }