View in English

  • Apple Developer
    • Get Started

    Explore Get Started

    • Overview
    • Learn
    • Apple Developer Program

    Stay Updated

    • Latest News
    • Hello Developer
    • Platforms

    Explore Platforms

    • Apple Platforms
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    • App Store

    Featured

    • Design
    • Distribution
    • Games
    • Accessories
    • Web
    • Home
    • CarPlay
    • Technologies

    Explore Technologies

    • Overview
    • Xcode
    • Swift
    • SwiftUI

    Featured

    • Accessibility
    • App Intents
    • Apple Intelligence
    • Games
    • Machine Learning & AI
    • Security
    • Xcode Cloud
    • Community

    Explore Community

    • Overview
    • Meet with Apple events
    • Community-driven events
    • Developer Forums
    • Open Source

    Featured

    • WWDC
    • Swift Student Challenge
    • Developer Stories
    • App Store Awards
    • Apple Design Awards
    • Apple Developer Centers
    • Documentation

    Explore Documentation

    • Documentation Library
    • Technology Overviews
    • Sample Code
    • Human Interface Guidelines
    • Videos

    Release Notes

    • Featured Updates
    • iOS
    • iPadOS
    • macOS
    • watchOS
    • visionOS
    • tvOS
    • Xcode
    • Downloads

    Explore Downloads

    • All Downloads
    • Operating Systems
    • Applications
    • Design Resources

    Featured

    • Xcode
    • TestFlight
    • Fonts
    • SF Symbols
    • Icon Composer
    • Support

    Explore Support

    • Overview
    • Help Guides
    • Developer Forums
    • Feedback Assistant
    • Contact Us

    Featured

    • Account Help
    • App Review Guidelines
    • App Store Connect Help
    • Upcoming Requirements
    • Agreements and Guidelines
    • System Status
  • Quick Links

    • Events
    • News
    • Forums
    • Sample Code
    • Videos
 

Vidéos

Ouvrir le menu Fermer le menu
  • Collections
  • Toutes les vidéos
  • À propos

Plus de vidéos

  • À propos
  • Code
  • Enhance your app with Metal ray tracing

    Achieve photorealistic 3D scenes in your apps and games through ray tracing, a core part of the Metal graphics framework and Shading Language. We'll explore the latest improvements in implementing ray tracing and take you through upgrades to the production rendering process. Discover Metal APIs to help you create more detailed scenes, integrate natively-supported content with motion, and more.

    Ressources

    • Rendering reflections in real time using ray tracing
    • Applying realistic material and lighting effects to entities
    • Accelerating ray tracing using Metal
    • Managing groups of resources with argument buffers
    • Metal
    • Metal Shading Language Specification
      • Vidéo HD
      • Vidéo SD

    Vidéos connexes

    Tech Talks

    • Explore GPU advancements in M3 and A17 Pro

    WWDC23

    • Your guide to Metal ray tracing

    WWDC22

    • Go bindless with Metal 3

    WWDC21

    • Discover Metal debugging, profiling, and asset creation tools
    • Explore bindless rendering in Metal
    • Explore hybrid rendering with Metal ray tracing
    • Optimize high-end games for Apple GPUs
  • Rechercher dans cette vidéo…
    • 4:48 - Specify intersection functions on render pipeline state

      // Create and attach MTLLinkedFunctions object
      NSArray <id <MTLFunction>> *functions = @[ sphere, cone, torus ];
      
      MTLLinkedFunctions *linkedFunctions = [MTLLinkedFunctions linkedFunctions];
      linkedFunctions.functions = functions;
      
      pipelineDescriptor.fragmentLinkedFunctions = linkedFunctions;
      
      // Create pipeline
      id<MTLRenderPipelineState> rayPipeline;
      rayPipeline = [device newRenderPipelineStateWithDescriptor:pipelineDescriptor
                                                           error:&error];
    • 5:02 - Create intersection function table

      // Fill out intersection function table descriptor
      MTLIntersectionFunctionTableDescriptor *tableDescriptor =
          [MTLIntersectionFunctionTableDescriptor intersectionFunctionTableDescriptor];
      
      tableDescriptor.functionCount = functions.count;
      
      // Create intersection function table
      id<MTLIntersectionFunctionTable> table;
      table = [rayPipeline newIntersectionFunctionTableWithDescriptor:tableDescriptor
                                                                stage:MTLRenderStageFragment];
    • 5:14 - Populate intersection function table

      id<MTLFunctionHandle> handle;
      
      for (NSUInteger i = 0 ; i < functions.count ; i++) {
          // Get a handle to the linked intersection function in the pipeline state
          handle = [rayPipeline functionHandleWithFunction:functions[i]
                                                     stage:MTLRenderStageFragment];
      
          // Insert the function handle into the table
          [table setFunction:handle atIndex:i];
      }
    • 5:48 - Bind resources

      [renderEncoder setFragmentAccelerationStructure:accelerationStructure atBufferIndex:0];
      [renderEncoder setFragmentIntersectionFunctionTable:table atBufferIndex:1];
    • 5:57 - Intersect from fragment shader

      [[fragment]]
      float4 rayFragmentShader(vertex_output vo [[stage_in]],
                               primitive_acceleration_structure accelerationStructure,
                               intersection_function_table<triangle_data> functionTable,
                               /* ... */)
      {
          // generate ray, create intersector...
      
          intersection = intersector.intersect(ray, accelerationStructure, functionTable);
      
          // shading...
      }
    • 9:32 - Triangle intersection function

      [[intersection(triangle, triangle_data)]]
      bool alphaTestIntersectionFunction(uint primitiveIndex        [[primitive_id]],
                                         uint geometryIndex         [[geometry_id]],
                                         float2 barycentricCoords   [[barycentric_coord]],
                                         device Material *materials [[buffer(0)]])
      
      {
          texture2d<float> alphaTexture = materials[geometryIndex].alphaTexture;
      
          float2 UV = interpolateUVs(materials[geometryIndex].UVs,
              primitiveIndex, barycentricCoords);
      
          float alpha = alphaTexture.sample(sampler, UV).x;
      
          return alpha > 0.5f;
      }
    • 10:36 - Custom intersection with intersection query

      intersection_query<instancing, triangle_data> iq(ray, as, params);
      
      // Step 1: start traversing acceleration structure
      while (iq.next())
      {
          // Step 2: candidate was found. Check type and run custom intersection.
          switch (iq.get_candidate_intersection_type())
          {
      	    case intersection_type::triangle:
      	    { 
      	       bool alphaTestResult = alphaTest(iq.get_candidate_geometry_id(),
      	                                iq.get_candidate_primitive_id(),
      	                                iq.get_candidate_triangle_barycentric_coord());
          	   // Step 3: commit candidate or ignore
                 if (alphaTestResult) 
                     iq.commit_triangle_intersection()
        	  }
          }
      }
    • 10:39 - Custom intersection with intersection query 2

      switch (iq.get_committed_intersection_type())
      {
        // Miss case  
        case intersection_type::none:
        {
            missShading();
            break;
        } 
        
        // Triangle intersection was committed. Query some info and do shading.
        case intersection_type::triangle:
        {
            shadeHitTriangle(iq.get_committed_instance_id(),
                             iq.get_committed_distance(),
                             iq.get_committed_triangle_barycentric_coord());
            break;
        }
      }
    • 15:30 - Specifying user instance IDs

      // New instance descriptor type
      
      typedef struct {
          uint32_t userID;
          // Members from MTLAccelerationStructureInstanceDescriptor...
      } MTLAccelerationStructureUserIDInstanceDescriptor;
      
      // Specify instance descriptor type through acceleration structure descriptor
      
      accelDesc.instanceDescriptorType = MTLAccelerationStructureInstanceDescriptorTypeUserID;
    • 15:47 - Retrieving user instance IDs 1

      // Available in intersection functions
      
      [[intersection(bounding_box, instancing)]]
      IntersectionResult sphereInstanceIntersectionFunction(unsigned int userID[[user_instance_id]],
                                                            /** other args **/)
      {
          // ...
      }
    • 15:58 - Retrieving user instance IDs 2

      // Available from intersection result
      
      intersection_result<instancing> intersection = instanceIntersector.intersect(/* args */);
      
      if (intersection.type != intersection_type::none)
          instanceIndex = intersection.user_instance_id;
      
      // Available from intersection query
      
      intersection_query<instancing> iq(/* args */);
      
      iq.next()
      
      if (iq.get_committed_intersection_type() != intersection_type::none)
          instanceIndex = iq.get_committed_user_instance_id();
    • 16:36 - Instance transforms

      // Available in intersection functions
      
      [[intersection(bounding_box, instancing, world_space_data)]]
      IntersectionResult intersectionFunction(float4x3 objToWorld [[object_to_world_transform]],
                                              float4x3 worldToObj [[world_to_object_transform]],
                                              /** other args **/)
      {
          // ...
      }
    • 16:51 - Instance transforms 2

      // Available from intersection result
      
      intersection_result<instancing, world_space_data> result = 
          intersector.intersect(/* args */);
      
      if (result.type != intersection_type::none) {
          output.myObjectToWorldTransform = result.object_to_world_transform;
          output.myWorldToObjectTransform = result.world_to_object_transform;
      }
    • 17:03 - Instance transforms 3

      // Available from intersection query
      
      intersection_query<instancing> iq(/* args */);
      
      iq.next()
      
      if(iq.get_committed_intersection_type() != intersection_type::none){
          output.myObjectToWorldTransform = iq.get_committed_object_to_world_transform();
          output.myWorldToObjectTransform = iq.get_committed_world_to_object_transform();
      }
    • 19:17 - Extended limits

      // Specify through acceleration structure descriptor
      
      accelDesc.usage = MTLAccelerationStructureUsageExtendedLimits;
      
      // Specify intersector tag
      
      intersector<extended_limits> extendedIntersector;
    • 22:30 - Sampling time

      // Randomly sample time
      
      float time = random(exposure_start, exposure_end);
      
      result = intersector.intersect(ray, acceleration_structure, time);
    • 25:54 - Motion instance descriptor

      descriptor = [MTLInstanceAccelerationStructureDescriptor new];
      
      descriptor.instanceDescriptorType = MTLAccelerationStructureInstanceDescriptorTypeMotion;
      
      // Buffer containing motion instance descriptors
      descriptor.instanceDescriptorBuffer = instanceBuffer;
      descriptor.instanceCount = instanceCount;
      
      // Buffer containing MTLPackedFloat4x3 transformation matrices
      descriptor.motionTransformBuffer = transformsBuffer;
      descriptor.motionTransformCount = transformCount;
      
      descriptor.instancedAccelerationStructures = primitiveAccelerationStructures;
    • 26:33 - Instance motion

      // Specify intersector tag
      
      kernel void raytracingKernel(acceleration_structure<instancing, instance_motion> as,
                                   /* other args */)
      {
          intersector<instancing, instance_motion> intersector;
      
          // ...
      }
    • 27:24 - Primitive motion 1

      // Collect keyframe vertex buffers
      
      NSMutableArray<MTLMotionKeyframeData*> *vertexBuffers = [NSMutableArray new];
      
      for (NSUInteger i = 0 ; i < keyframeBuffers.count ; i++) {
          MTLMotionKeyframeData *keyframeData = [MTLMotionKeyframeData data];
      
          keyframeData.buffer = keyframeBuffers[i];
      
          [vertexBuffers addObject:keyframeData];
      }
    • 27:39 - Primitive motion 2

      // Create motion geometry descriptor
      
      MTLAccelerationStructureMotionTriangleGeometryDescriptor *geometryDescriptor =
          [MTLAccelerationStructureMotionTriangleGeometryDescriptor descriptor];
      
      geometryDescriptor.vertexBuffers = vertexBuffers;
      geometryDescriptor.triangleCount = triangleCount;
    • 27:57 - Primitive motion 3

      // Create acceleration structure descriptor
      
      MTLPrimitiveAccelerationStructureDescriptor *primitiveDescriptor =
          [MTLPrimitiveAccelerationStructureDescriptor descriptor];
      
      primitiveDescriptor.geometryDescriptors = @[ geometryDescriptor ];
      
      primitiveDescriptor.motionKeyframeCount = keyframeCount;
    • 28:10 - Primitive motion 4

      // Specify intersector tag
      
      kernel void raytracingKernel(acceleration_structure<primitive_motion> as,
                                   /* other args */)
      {
          intersector<primitive_motion> intersector;
      
          // ...
      }

Developer Footer

  • Vidéos
  • WWDC21
  • Enhance your app with Metal ray tracing
  • Open Menu Close Menu
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    • App Store
    Open Menu Close Menu
    • Swift
    • SwiftUI
    • Swift Playground
    • TestFlight
    • Xcode
    • Xcode Cloud
    • Icon Composer
    • SF Symbols
    Open Menu Close Menu
    • Accessibility
    • Accessories
    • Apple Intelligence
    • Audio & Video
    • Augmented Reality
    • Business
    • Design
    • Distribution
    • Education
    • Games
    • Health & Fitness
    • In-App Purchase
    • Localization
    • Maps & Location
    • Machine Learning & AI
    • Security
    • Safari & Web
    Open Menu Close Menu
    • Documentation
    • Downloads
    • Sample Code
    • Videos
    Open Menu Close Menu
    • Help Guides & Articles
    • Contact Us
    • Forums
    • Feedback & Bug Reporting
    • System Status
    Open Menu Close Menu
    • Apple Developer
    • App Store Connect
    • Certificates, IDs, & Profiles
    • Feedback Assistant
    Open Menu Close Menu
    • Apple Developer Program
    • Apple Developer Enterprise Program
    • App Store Small Business Program
    • MFi Program
    • Mini Apps Partner Program
    • News Partner Program
    • Video Partner Program
    • Security Bounty Program
    • Security Research Device Program
    Open Menu Close Menu
    • Meet with Apple
    • Apple Developer Centers
    • App Store Awards
    • Apple Design Awards
    • Apple Developer Academies
    • WWDC
    Read the latest news.
    Get the Apple Developer app.
    Copyright © 2026 Apple Inc. All rights reserved.
    Terms of Use Privacy Policy Agreements and Guidelines