2021 Graphics & Games
WWDC21 · 21 min · Graphics & Games
Explore bindless rendering in Metal
Unleash the full potential of your shaders and implement modern rendering techniques by adding Argument Buffers to adopt bindless rendering. Learn how to make your entire scene and resources available to the GPU to make the most out of raytracing and rasterization pipelines.
Watch at developer.apple.com ↗Code shown on screen · 12 snippets
Simple Intersection Kernel 2
if(i.type == intersection_type::triangle)
{
constant Instance& inst = get_instance(i);
constant Mesh& mesh = get_mesh(inst, i);
constant Material& material = get_material(inst, i);
color = shade_pixel(mesh, material, i);
}
outImage.write(color, tid); PBR fragment shading requires several textures
fragment half4 pbrFragment(ColorInOut in [[stage_in]],
texture2d< float > albedo [[texture(0)]],
texture2d< float > roughness [[texture(1)]],
texture2d< float > metallic [[texture(2)]],
texture2d< float > occlusion [[texture(3)]])
{
half4 color = calculateShading(in, albedo, roughness, metallic, occlusion);
return color;
} Bindless makes all textures available via AB navigation
fragment half4 pbrFragmentBindless(ColorInOut in [[stage_in]],
device const Scene* pScene [[buffer(0)]])
{
device const Instance& instance = pScene->instances[in.instance_id];
device const Material& material = pScene->materials[instance.material_id];
half4 color = calculateShading(in, material);
return color;
} Simple Intersection Kernel 1
if (intersection.type == intersection_type::triangle)
{
// solid blue triangle
color = float4(0.0f, 0.0f, 1.0f, 1.0f);
}
outImage.write(color, tid); Encoder creation
struct Instance
{
constant Mesh* pMesh [[id(0)]];
constant Material* pMaterial [[id(1)]];
constant float4x4 modelTransform [[id(2)]];
}; Encoder via reflection
// Shader code references scene
kernel void RTReflections( constant Scene* pScene [[buffer(0)]] ); Argument Buffers referenced indirectly
MTLArgumentDescriptor* meshArg
= [MTLArgumentDescriptor argumentDescriptor];
meshArg.index = 0;
meshArg.dataType = MTLDataTypePointer;
meshArg.access = MTLArgumentAccessReadOnly;
// Declare all other arguments (material and transform)
id<MTLArgumentEncoder> instanceEncoder
= [device newArgumentEncoderWithArguments:@[meshArg,
materialArg,
transformArg]]; Navigation 1
// Instance and Mesh
constant Instance& instance = pScene->instances[intersection.instance_id];
constant Mesh& mesh = instance.mesh[intersection.geometry_id];
// Primitive indices
ushort3 indices; // assuming 16-bit indices, use uint3 for 32-bit
indices.x = mesh.indices[ intersection.primitive_id * 3 + 0 ];
indices.y = mesh.indices[ intersection.primitive_id * 3 + 1 ];
indices.z = mesh.indices[ intersection.primitive_id * 3 + 2 ]; Navigation 2
// Vertex data
packed_float3 n0 = mesh.normals[ indices.x ];
packed_float3 n1 = mesh.normals[ indices.y ];
packed_float3 n2 = mesh.normals[ indices.z ];
// Interpolate attributes
float3 barycentrics = calculateBarycentrics(intersection);
float3 normal = weightedSum(n0, n1, n2, barycentrics); Simple Intersection Kernel
if(i.type == intersection_type::triangle)
{
constant Instance& inst = get_instance(i);
constant Mesh& mesh = get_mesh(inst, i);
constant Material& material = get_material(inst, i);
color = shade_pixel(mesh, material, i);
}
outImage.write(color, tid); PBR fragment shading requires several textures
fragment half4 pbrFragment(ColorInOut in [[stage_in]],
texture2d< float > albedo [[texture(0)]],
texture2d< float > roughness [[texture(1)]],
texture2d< float > metallic [[texture(2)]],
texture2d< float > occlusion [[texture(3)]])
{
half4 color = calculateShading(in, albedo, roughness, metallic, occlusion);
return color;
} Bindless makes all textures available via AB navigation
fragment half4 pbrFragmentBindless(ColorInOut in [[stage_in]],
device const Scene* pScene [[buffer(0)]])
{
device const Instance& instance = pScene->instances[in.instance_id];
device const Material& material = pScene->materials[instance.material_id];
half4 color = calculateShading(in, material);
return color;
} Resources
Related sessions
-
34 min -
32 min -
30 min -
30 min