{"$schema": "https://raw.githubusercontent.com/guitaripod/wwdc-sessions/master/schema/transcript.schema.json", "id": "wwdc2026-320", "language": "eng", "source": "https://developer.apple.com/videos/play/wwdc2026/320", "wordCount": 2966, "segments": [{"start": 6.0, "text": "Bonjour, I'm Jean, I'm an Engineer on the visionOS Safari team."}, {"start": 11.0, "text": "In this session, I'm going to show you how you can elevate your websites"}, {"start": 15.0, "text": "with immersive environments."}, {"start": 17.0, "text": "A whole new way to tell stories to your audience"}, {"start": 20.0, "text": "and engage your customers like never before."}, {"start": 23.0, "text": "Take this ticket sales website."}, {"start": 26.0, "text": "As the visitors choose their seats,"}, {"start": 28.0, "text": "they get an inline preview of their selection."}, {"start": 31.0, "text": "But more than that, they can enter the theater"}, {"start": 33.0, "text": "as an immersive environment,"}, {"start": 35.0, "text": "and literally stand at their chosen spot."}, {"start": 38.0, "text": "And all of this from a webpage, in Safari!"}, {"start": 43.0, "text": "Well, this is one experience that I'll show you how to build today!"}, {"start": 47.0, "text": "But not the only one…"}, {"start": 49.0, "text": "Check this out."}, {"start": 50.0, "text": "This is a marketing website for a visionOS escape game app."}, {"start": 54.0, "text": "Transporting visitors into one of the game's escape rooms -"}, {"start": 58.0, "text": "a dimly lit chamber, with a TV screen showing a mysterious video."}, {"start": 62.0, "text": "As it plays, it will invite the visitors to discover what's behind this door,"}, {"start": 68.0, "text": "encouraging them to download the app and find out for themselves."}, {"start": 72.0, "text": "In the next few minutes, you'll learn everything you need to know"}, {"start": 75.0, "text": "to start building your first website environment."}, {"start": 78.0, "text": "I'll start by giving you a high-level overview of the immersive API for the web."}, {"start": 83.0, "text": "Then, I'll cover how to preview environments inline in the page."}, {"start": 87.0, "text": "After which, I'll show you how to go immersive"}, {"start": 90.0, "text": "and enter the theater from the inline preview,"}, {"start": 93.0, "text": "as well as the escape room."}, {"start": 95.0, "text": "And finally, I will guide you through how you can optimize your experience"}, {"start": 99.0, "text": "with video, animations, and shadow casting,"}, {"start": 103.0, "text": "while maintaining excellent runtime performance."}, {"start": 106.0, "text": "Alright, let me introduce you to this immersive API."}, {"start": 112.0, "text": "It all starts with the HTML model element,"}, {"start": 114.0, "text": "which allows you to display 3D models on your website."}, {"start": 118.0, "text": "To use it, you need to specify your 3D asset resource."}, {"start": 122.0, "text": "Here, a USDZ file representing a teapot."}, {"start": 125.0, "text": "And maybe an environment map."}, {"start": 127.0, "text": "Which is a 360-degree image"}, {"start": 129.0, "text": "that captures the lighting around your scene."}, {"start": 131.0, "text": "With an environment map, you can add dramatic reflections"}, {"start": 134.0, "text": "and lighting on shiny objects like this teapot."}, {"start": 138.0, "text": "The 3D model and the environment map assets"}, {"start": 140.0, "text": "can be created through a large variety of tools."}, {"start": 143.0, "text": "I'll be using Blender later in the session,"}, {"start": 146.0, "text": "but you can use any tool that exports a USDZ file."}, {"start": 150.0, "text": "If you later want to know more about this HTML element,"}, {"start": 153.0, "text": "you can check out the session \"Get started with the HTML Model Element\""}, {"start": 157.0, "text": "which dives deeper in the element itself and its behaviors on all platforms."}, {"start": 162.0, "text": "Now, let's get to the immersive part!"}, {"start": 165.0, "text": "If you're familiar with the JavaScript Fullscreen API,"}, {"start": 168.0, "text": "you'll feel right at home."}, {"start": 170.0, "text": "And if you're not,"}, {"start": 171.0, "text": "well, you will be soon,"}, {"start": 173.0, "text": "because the immersive API follows"}, {"start": 175.0, "text": "the already widely used Fullscreen API pattern."}, {"start": 179.0, "text": "The same way you'd request a video to go fullscreen"}, {"start": 182.0, "text": "through the requestFullscreen JavaScript API,"}, {"start": 185.0, "text": "you request a model element to go immersive"}, {"start": 187.0, "text": "through the requestImmersive JavaScript API."}, {"start": 190.0, "text": "And very similarly,"}, {"start": 192.0, "text": "you can exit the immersive presentation,"}, {"start": 194.0, "text": "detect if the feature is available,"}, {"start": 197.0, "text": "check if there currently is an immersive element,"}, {"start": 201.0, "text": "listen to changes,"}, {"start": 202.0, "text": "and error events,"}, {"start": 204.0, "text": "and even customize your layout directly in your stylesheet with a CSS pseudo-class."}, {"start": 210.0, "text": "But unlike the Fullscreen API,"}, {"start": 212.0, "text": "which replaces the web page content with the provided element,"}, {"start": 215.0, "text": "the immersive API transports the model element beyond"}, {"start": 219.0, "text": "the browser bounds while keeping the page visible."}, {"start": 222.0, "text": "And both APIs can be active simultaneously, so you can have a fullscreen video player"}, {"start": 228.0, "text": "while being immersed in a virtual environment."}, {"start": 231.0, "text": "What I find beautiful with this API, is that I can either use it very simply"}, {"start": 236.0, "text": "with just one request call on a model element,"}, {"start": 238.0, "text": "or use its full depth and combine it with other APIs"}, {"start": 242.0, "text": "to create incredible experiences."}, {"start": 244.0, "text": "Like those immersive websites that I've showed you earlier,"}, {"start": 247.0, "text": "and in which I'll dive in right now."}, {"start": 249.0, "text": "Starting with the venue ticket sales website,"}, {"start": 252.0, "text": "which provides an inline preview of the environment,"}, {"start": 256.0, "text": "inline previews are a great way to introduce"}, {"start": 259.0, "text": "an environment to visitors as a first step."}, {"start": 262.0, "text": "So I'll show you how to create a compelling one now."}, {"start": 266.0, "text": "Here is my website, running locally on the simulator."}, {"start": 269.0, "text": "When the visitor selects a seat,"}, {"start": 271.0, "text": "this model appears, but I left it empty so far."}, {"start": 275.0, "text": "And I'd like to add my Inline preview in there!"}, {"start": 277.0, "text": "So, in this empty HTML div,"}, {"start": 280.0, "text": "I'll add the model element."}, {"start": 283.0, "text": "I provide the theater model USDZ file, and its lighting map."}, {"start": 288.0, "text": "The inline preview now shows the whole theater model from the outside."}, {"start": 293.0, "text": "This is because, by default, the model is scaled to fit the element's bounds."}, {"start": 297.0, "text": "In this case, this not a very interesting view to show,"}, {"start": 301.0, "text": "we'd rather show the theater from the inside!"}, {"start": 304.0, "text": "So, to get rid of this default fitting behavior,"}, {"start": 307.0, "text": "I'll need to customize the entity transform -"}, {"start": 310.0, "text": "which controls the model's position, rotation, and scale."}, {"start": 314.0, "text": "In my code, after retrieving the model element,"}, {"start": 317.0, "text": "and waiting for it to be loaded and ready,"}, {"start": 320.0, "text": "I create an identity matrix."}, {"start": 322.0, "text": "And set it to my model's entity transform."}, {"start": 325.0, "text": "This effectively removes all transformations from the model."}, {"start": 329.0, "text": "Now the floor of the model currently sits at the center of the layer."}, {"start": 333.0, "text": "That's because the origin of the theater model is on its floor."}, {"start": 337.0, "text": "But the goal here is to show the environment at a human eye level."}, {"start": 341.0, "text": "So, I'll translate the model down by 1 meter,"}, {"start": 345.0, "text": "which is the measured eye level height of my roommate seating on a regular chair."}, {"start": 351.0, "text": "This looks better!"}, {"start": 353.0, "text": "But right now, this is showing the view from the stage."}, {"start": 357.0, "text": "Which, honestly, looks quite nice,"}, {"start": 359.0, "text": "but I'd like the preview's point of view to match the actual seat selection."}, {"start": 363.0, "text": "To help with that,"}, {"start": 364.0, "text": "I've created a JSON file that maps each seat to its location in the theater."}, {"start": 369.0, "text": "Each entry contains the translation from the model's origin"}, {"start": 372.0, "text": "to the bottom of the seat,"}, {"start": 374.0, "text": "as well as an angle representing the seat's orientation towards the stage."}, {"start": 379.0, "text": "The values are expressed in the right handed Y-up coordinate system,"}, {"start": 383.0, "text": "which is the convention used on the web."}, {"start": 386.0, "text": "So back to my website's code,"}, {"start": 388.0, "text": "I've created a new function just to build the correct transform."}, {"start": 392.0, "text": "It currently contains the translation for previewing the model at eye level."}, {"start": 396.0, "text": "And I can now add the current selected seat as a parameter."}, {"start": 399.0, "text": "And apply the corresponding seat rotation,"}, {"start": 402.0, "text": "and translation to match the seat's point of view."}, {"start": 406.0, "text": "And here we go — as a seat is selected,"}, {"start": 409.0, "text": "the model shows the point of view from that exact seat's location."}, {"start": 412.0, "text": "And this inline preview also works on other platforms like macOS and iOS!"}, {"start": 418.0, "text": "I think it is a really nice experience already."}, {"start": 421.0, "text": "But the real magic truly begins now,"}, {"start": 424.0, "text": "when the ticket buyer can step inside the theater!"}, {"start": 427.0, "text": "This is where we unlock the full potential of spatial platforms"}, {"start": 432.0, "text": "like visionOS, so let's go immersive!"}, {"start": 436.0, "text": "First, I'm checking whether the immersive API is available."}, {"start": 440.0, "text": "This property tells me whether the current browser supports immersive presentations."}, {"start": 445.0, "text": "With this checked, I can confidently show my Immersive Preview button,"}, {"start": 450.0, "text": "and it will only appear where the feature is actually supported."}, {"start": 454.0, "text": "Then, I'll want to request an immersive transition on the model."}, {"start": 458.0, "text": "This must happen in response to a user interaction."}, {"start": 462.0, "text": "In my case, the tap of the immersive button."}, {"start": 465.0, "text": "Now, one important thing to note is that an inline model"}, {"start": 468.0, "text": "and an immersive model have different reference frames."}, {"start": 471.0, "text": "They have different origins and different scales."}, {"start": 475.0, "text": "When inline, as I just showed you,"}, {"start": 477.0, "text": "the origin of the model element is at the center of the inline layer,"}, {"start": 481.0, "text": "and the scale is following CSS conventions."}, {"start": 485.0, "text": "But when immersive, the origin is at the person's feet, on the floor,"}, {"start": 489.0, "text": "and the scale is true to the real world."}, {"start": 492.0, "text": "Additionally, keep in mind that the immersive environment"}, {"start": 495.0, "text": "will open from behind Safari's window."}, {"start": 497.0, "text": "So try to keep the main focus of your model visible,"}, {"start": 501.0, "text": "without needing to reposition the window."}, {"start": 504.0, "text": "So, for my use case, back in the build transform function,"}, {"start": 507.0, "text": "I add a second parameter,"}, {"start": 509.0, "text": "letting me know whether the model is displayed immersively"}, {"start": 512.0, "text": "as opposed to inline in the page."}, {"start": 515.0, "text": "When immersive, I add a slight rotation,"}, {"start": 518.0, "text": "so that the stage, which is my main focus here,"}, {"start": 520.0, "text": "is not hidden behind Safari's window."}, {"start": 524.0, "text": "Additionally, I make sure that the eye level translation"}, {"start": 527.0, "text": "is only performed when presenting the model inline in the page."}, {"start": 531.0, "text": "Now because the entity transform depends on the immersive state of the model,"}, {"start": 536.0, "text": "it needs to be updated every time the model goes in and out of immersive."}, {"start": 542.0, "text": "Listening to the immersive change event"}, {"start": 544.0, "text": "on the model element is the right way to do this."}, {"start": 547.0, "text": "Here, I check the current document immersive state"}, {"start": 550.0, "text": "and re-compute the entity transform with the right flag."}, {"start": 553.0, "text": "And, while I'm here, I'll also update the page layout"}, {"start": 556.0, "text": "to reflect the current state."}, {"start": 558.0, "text": "In my case, when going immersive,"}, {"start": 561.0, "text": "I'm adjusting the model interface,"}, {"start": 562.0, "text": "and displaying an exit button."}, {"start": 565.0, "text": "It's always good to present a clear exit affordance"}, {"start": 568.0, "text": "for your immersive experiences."}, {"start": 570.0, "text": "But also keep in mind that a visitor using an Apple Vision Pro"}, {"start": 574.0, "text": "can use the Digital Crown at any time to dismiss the immersive environment."}, {"start": 579.0, "text": "That's why, if your UI depends on the immersive state,"}, {"start": 583.0, "text": "it's critical to listen to immersive state changes"}, {"start": 586.0, "text": "and update your layout accordingly."}, {"start": 589.0, "text": "And just like that, I've built an experience"}, {"start": 592.0, "text": "that transports the ticket buyer inside the theater,"}, {"start": 595.0, "text": "sitting right in the seat they picked."}, {"start": 597.0, "text": "They can look around, check the view of the stage,"}, {"start": 601.0, "text": "lean over the balcony…"}, {"start": 602.0, "text": "Oh wow! This is quite high, you don't want to fall down there."}, {"start": 607.0, "text": "Make sure to hold the safety railing……."}, {"start": 608.0, "text": "What?!"}, {"start": 609.0, "text": "What happened with the safety railing here?"}, {"start": 611.0, "text": "Ugh.. sorry, I'm getting off topic."}, {"start": 614.0, "text": "This experience is way too immersive."}, {"start": 617.0, "text": "Alright, let's switch gears"}, {"start": 619.0, "text": "and dive into something a little more mysterious."}, {"start": 622.0, "text": "Say you've built a visionOS escape game app."}, {"start": 625.0, "text": "You've poured hours into crafting incredible environments for this game."}, {"start": 630.0, "text": "Well, with the immersive API,"}, {"start": 632.0, "text": "you can use those same environment models"}, {"start": 634.0, "text": "to create an unforgettable marketing experience,"}, {"start": 637.0, "text": "right from your website, in Safari."}, {"start": 640.0, "text": "Let me show you how I built this."}, {"start": 642.0, "text": "I was surprised how little code it takes."}, {"start": 645.0, "text": "So here, even though the model element would make it easy"}, {"start": 648.0, "text": "to create an inline preview,"}, {"start": 650.0, "text": "I prefer to keep the surprise."}, {"start": 653.0, "text": "When adding the model element in my HTML code,"}, {"start": 656.0, "text": "I simply set display to none."}, {"start": 658.0, "text": "Doing this, hides the inline layer from the page,"}, {"start": 662.0, "text": "but doesn't prevent me from requesting the model as immersive."}, {"start": 666.0, "text": "And there's a practical benefit to hiding the inline preview this way."}, {"start": 669.0, "text": "Indeed, the asset won't be downloaded or decoded"}, {"start": 673.0, "text": "until the immersive request actually happens."}, {"start": 676.0, "text": "For heavy environment models,"}, {"start": 678.0, "text": "that can save significant bandwidth and memory"}, {"start": 680.0, "text": "if the visitor doesn't actually enter the environment."}, {"start": 684.0, "text": "The next thing to do, is simply to request the escape room model"}, {"start": 688.0, "text": "as immersive on the button's click event."}, {"start": 691.0, "text": "Since the model isn't pre-loaded inline, the immersive request may take a moment."}, {"start": 696.0, "text": "Especially for heavier and more complex assets."}, {"start": 700.0, "text": "I'll show you later how you can reduce this loading time"}, {"start": 702.0, "text": "by optimizing your asset."}, {"start": 704.0, "text": "But for now,"}, {"start": 705.0, "text": "I'll at least give visitors feedback that something is happening,"}, {"start": 709.0, "text": "with an intriguing loading animation."}, {"start": 712.0, "text": "In the code, I'm showing it before the immersive request,"}, {"start": 716.0, "text": "and hiding it once it completed."}, {"start": 719.0, "text": "And that's about it for getting into the environment!"}, {"start": 722.0, "text": "Pretty straightforward!"}, {"start": 724.0, "text": "Alright, now, I'll talk about the features"}, {"start": 727.0, "text": "that make this escape room come alive on visionOS."}, {"start": 730.0, "text": "All the little things, that make one simple experience go a long way."}, {"start": 736.0, "text": "I'll start with videos."}, {"start": 738.0, "text": "Instead of having your video playing inline in your website."}, {"start": 741.0, "text": "The video docking feature elevates your video,"}, {"start": 744.0, "text": "and places it directly inside the environment,"}, {"start": 747.0, "text": "on a TV screen, a projector, or a billboard,"}, {"start": 750.0, "text": "whatever surface fits your story best."}, {"start": 753.0, "text": "Additionally, you can add materials that diffuse,"}, {"start": 756.0, "text": "or reflect the light coming from the video."}, {"start": 760.0, "text": "Which makes it feel part of the scene."}, {"start": 762.0, "text": "To create this experience,"}, {"start": 764.0, "text": "you'll need to add some custom RealityKit annotations to your USDZ file."}, {"start": 769.0, "text": "These are not yet standards, but I'm a big fan of Blender,"}, {"start": 773.0, "text": "so I made a little plugin to add those components"}, {"start": 776.0, "text": "directly while creating my environment."}, {"start": 779.0, "text": "Here, I am using it to tag the TV screen,"}, {"start": 781.0, "text": "to be the video docking region of my scene."}, {"start": 784.0, "text": "And I'm also using this same Blender extension"}, {"start": 787.0, "text": "to facilitate the baking of the video light spill onto my materials."}, {"start": 792.0, "text": "Now, once I exported my assets with these new properties,"}, {"start": 796.0, "text": "the next thing to do, is to request a fullscreen transition on the video."}, {"start": 801.0, "text": "Here, I'm requesting this on the click of the demoButton."}, {"start": 806.0, "text": "This automatically transports the video to the right location in my environment,"}, {"start": 810.0, "text": "and hides Safari's window!"}, {"start": 813.0, "text": "The video is fully integrated into the environment."}, {"start": 817.0, "text": "The light from the TV spills onto the floor and walls,"}, {"start": 820.0, "text": "dramatically increasing the realism of the space."}, {"start": 824.0, "text": "Now, for the twist,"}, {"start": 826.0, "text": "let me show you how I can make this mysterious door slide open."}, {"start": 831.0, "text": "I've created this door opening animation in Blender,"}, {"start": 834.0, "text": "right before exporting the model."}, {"start": 836.0, "text": "So really the only thing left to do is play it at the right time."}, {"start": 841.0, "text": "With these few lines, I listen for the video's ended event,"}, {"start": 845.0, "text": "then exit the fullscreen video,"}, {"start": 847.0, "text": "which will undock the video and bring back the website."}, {"start": 850.0, "text": "And finally, I play the model animation."}, {"start": 854.0, "text": "Here you go, the room transforms, the door slides open,"}, {"start": 858.0, "text": "and the mystery keeps on growing."}, {"start": 862.0, "text": "Model animations can be quite powerful."}, {"start": 865.0, "text": "You could create an entire timeline of animations."}, {"start": 868.0, "text": "And you'd be able use the model's currentTime property"}, {"start": 871.0, "text": "to navigate through the timeline,"}, {"start": 873.0, "text": "and transform your environment through multiple stages."}, {"start": 877.0, "text": "If you want to know more about that,"}, {"start": 879.0, "text": "I'd encourage you to check out the session \"What's new for the spatial web\","}, {"start": 882.0, "text": "which dives a bit deeper into these possibilities."}, {"start": 886.0, "text": "Ok, let's have some fun with just one more thing."}, {"start": 889.0, "text": "I want to show you how Safari's window is casting its shadow on the environment."}, {"start": 894.0, "text": "I personally find this detail so important,"}, {"start": 896.0, "text": "because this shadow helps people understand"}, {"start": 899.0, "text": "the positioning of the window inside the space,"}, {"start": 902.0, "text": "and makes it feel like part of the environment."}, {"start": 905.0, "text": "Enabling this also requires a RealityKit annotation."}, {"start": 909.0, "text": "Here, with my same Blender extension,"}, {"start": 912.0, "text": "I'm tagging the meshes that should receive these shadows"}, {"start": 915.0, "text": "with the Scene Understanding component."}, {"start": 918.0, "text": "I made sure to create a dedicated low poly mesh, optimized just for this,"}, {"start": 922.0, "text": "as computing shadows on a complex mesh can consume a lot of resources."}, {"start": 927.0, "text": "Alright, now I'll end this session with a quick note on performance."}, {"start": 932.0, "text": "Environment models tend to be heavier and more complex to render"}, {"start": 935.0, "text": "than simpler object models."}, {"start": 937.0, "text": "Let me show you what you can do to optimize your asset,"}, {"start": 940.0, "text": "making it smoother to render and faster to download."}, {"start": 944.0, "text": "First off, reduce your asset vertex count."}, {"start": 948.0, "text": "In my escape room, I made sure that I'm not exporting any mesh"}, {"start": 951.0, "text": "that would be invisible to the viewer standing at the origin."}, {"start": 954.0, "text": "Doing this, I've drastically reduced the number of vertices,"}, {"start": 958.0, "text": "without anyone noticing."}, {"start": 960.0, "text": "Then reduce the entity count."}, {"start": 963.0, "text": "In my case, I've merged the desk with all its decorations"}, {"start": 967.0, "text": "to avoid having too many separate entities."}, {"start": 970.0, "text": "Use low poly meshes when appropriate."}, {"start": 972.0, "text": "Like the one I used for the scene understanding component"}, {"start": 975.0, "text": "to get shadow casting at a low cost."}, {"start": 978.0, "text": "Keep your shaders as simple as possible."}, {"start": 981.0, "text": "For the escape room, I've baked all the lighting in the materials."}, {"start": 985.0, "text": "Which means that I painted the light and shadows onto the textures,"}, {"start": 990.0, "text": "allowing me to make them unlit materials"}, {"start": 992.0, "text": "and skip heavy shading computations at runtime."}, {"start": 996.0, "text": "Finally, use the usdcrush tool to compress your USDZ's textures."}, {"start": 1001.0, "text": "It's available as a command line tool on any Mac,"}, {"start": 1004.0, "text": "and can help you reduce the size of your model quite a lot,"}, {"start": 1007.0, "text": "which directly translates to faster loading time"}, {"start": 1010.0, "text": "for people on a slower connection."}, {"start": 1012.0, "text": "I'd recommend to check out the WWDC session,"}, {"start": 1014.0, "text": "\"Optimize your custom environments for visionOS\""}, {"start": 1017.0, "text": "that goes way deeper into 3D asset optimization."}, {"start": 1021.0, "text": "Alright, here we are."}, {"start": 1023.0, "text": "You're now ready to create your own experiences."}, {"start": 1026.0, "text": "To transport your customers into your environments."}, {"start": 1030.0, "text": "With just a model element and a handful of API calls,"}, {"start": 1033.0, "text": "you can redefine the way your visitors interact with your website."}, {"start": 1037.0, "text": "And I've only scratched the surface here."}, {"start": 1039.0, "text": "There are so many other APIs you can combine"}, {"start": 1042.0, "text": "to bring an immersive dimension to your website."}, {"start": 1045.0, "text": "One of them is the image controls API."}, {"start": 1048.0, "text": "By simply adding the controls attribute on my image element here,"}, {"start": 1053.0, "text": "the browser will offer native controls."}, {"start": 1055.0, "text": "Providing a relevant User Interface for platform specific features."}, {"start": 1059.0, "text": "Like on visionOS, where this allows people to make this panorama fullscreen,"}, {"start": 1064.0, "text": "which will wrap it around them in their space."}, {"start": 1067.0, "text": "And this also works for spatial photos."}, {"start": 1070.0, "text": "Which can be captured directly from your Apple Vision Pro, or your iPhone."}, {"start": 1074.0, "text": "Just like with the model element and the immersive API,"}, {"start": 1078.0, "text": "with image controls,"}, {"start": 1079.0, "text": "one little thing in your code goes a long way."}, {"start": 1083.0, "text": "Creativity is the only limit."}, {"start": 1086.0, "text": "Here's what I encourage you to do next."}, {"start": 1089.0, "text": "Try the online demos on webkit.org with your Apple Vision Pro,"}, {"start": 1093.0, "text": "there's no better way to understand the impact of the feature"}, {"start": 1097.0, "text": "than experiencing it yourself."}, {"start": 1099.0, "text": "Create your first website environment."}, {"start": 1102.0, "text": "I have attached resources to this session to further help you,"}, {"start": 1106.0, "text": "like the API specifications, check them out!"}, {"start": 1110.0, "text": "And finally, while you'll be building your own experiences,"}, {"start": 1114.0, "text": "file feature requests or bug reports at bugs.webkit.org."}, {"start": 1118.0, "text": "Oh and also, check out this session"}, {"start": 1121.0, "text": "called \"Design immersive environments for visionOS apps and the spatial web\"."}, {"start": 1126.0, "text": "It explores the high level principles"}, {"start": 1128.0, "text": "of creating great photorealistic environments."}, {"start": 1131.0, "text": "I'll personally be on the lookout for what immersive experiences you'll create."}, {"start": 1135.0, "text": "Thank you so much for joining this session,"}, {"start": 1138.0, "text": "hope you enjoyed it!"}, {"start": 1139.0, "text": "Have a great WWDC!"}]}