<!--
{
  "documentType" : "article",
  "framework" : "Metal",
  "identifier" : "/documentation/Metal/rendering-with-a-rasterization-rate-map",
  "metadataVersion" : "0.1.0",
  "role" : "article",
  "title" : "Rendering with a rasterization rate map"
}
-->

# Rendering with a rasterization rate map

Create offscreen textures to hold intermediate rasterized data.

## Discussion

You don’t render data directly to the final render destination using variable rasterization rates. Instead, you allocate textures to use as intermediate targets. You get the sizes for these textures from the rate map. For example, if you specified a rate of `0.5` everywhere, the intermediate texture is half the height and width of the final render target.

The [`MTLRasterizationRateMap`](/documentation/Metal/MTLRasterizationRateMap) protocol [`screenSize`](/documentation/Metal/MTLRasterizationRateMap/screenSize) property gives the dimensions of the final render target. Call the [`physicalSize(layer:)`](/documentation/Metal/MTLRasterizationRateMap/physicalSize(layer:)): method on the rate map object to get the size for each layer. Then allocate the textures you need. For example, the following code gets the physical size and allocates a color texture and a depth texture of that size:

```swift
// Get the size of each layer from the rate map object.
let textureSize = rateMap.physicalSize(layer: 0)

// Create a texture descriptor.
let colorTextureDescriptor = MTLTextureDescriptor()

// Configure the width and height from the rate map.
colorTextureDescriptor.width = textureSize.width
colorTextureDescriptor.height = textureSize.height

colorTextureDescriptor.pixelFormat = .bgra8Unorm_srgb

// Disable mipmapping for the texture(s).
colorTextureDescriptor.mipmapLevelCount = 1

// Configure the texture(s) as render target(s) that shaders can read.
colorTextureDescriptor.usage = [.renderTarget, .shaderRead]

// Create the color texture from the descriptor.
let colorTexture = device.makeTexture(descriptor: colorTextureDescriptor)

// Create a depth texture descriptor of the same size.
let depthTextureDescriptor = MTLTextureDescriptor.texture2DDescriptor(pixelFormat: .depth32Float,
                                width: textureSize.width, height: textureSize.height, mipmapped: false)
depthTextureDescriptor.usage = .renderTarget

// Create the depth texture from the descriptor.
let depthTexture = device.makeTexture(descriptor: depthTextureDescriptor)
```

To use variable rasterization rates, create a render pass, specifying the intermediate textures as the render targets. Set the [`rasterizationRateMap`](/documentation/Metal/MTLRenderPassDescriptor/rasterizationRateMap) property to the rate map you created, as shown below:

```swift
let firstPassDescriptor = MTLRenderPassDescriptor()

firstPassDescriptor.rasterizationRateMap = rateMap

firstPassDescriptor.colorAttachments[0].texture = colorTexture
firstPassDescriptor.colorAttachments[0].loadAction = MTLLoadAction.clear
firstPassDescriptor.colorAttachments[0].storeAction = MTLStoreAction.store

firstPassDescriptor.depthAttachment.texture = depthTexture
firstPassDescriptor.depthAttachment.loadAction = MTLLoadAction.clear
firstPassDescriptor.depthAttachment.storeAction = MTLStoreAction.dontCare

firstPassDescriptor.stencilAttachment.texture = depthTexture
firstPassDescriptor.stencilAttachment.loadAction = MTLLoadAction.clear
firstPassDescriptor.stencilAttachment.storeAction = MTLStoreAction.dontCare
```

After rendering with a rasterization rate map, you need to scale the intermediate textures to fill your destination texture.
To convert between screen space and physical fragment space in your shader, bind the rate map data buffer to the shader with type `rasterization_rate_map_data`, then construct `rasterization_rate_map_decoder` with the buffer data.
For more details, see the “Variable Rasterization Rate” section of the [Metal Shading Language Specification](https://developer.apple.com/metal/Metal-Shading-Language-Specification.pdf) and [Scaling variable rasterization rate content](/documentation/Metal/scaling-variable-rasterization-rate-content).

---

Copyright &copy; 2026 Apple Inc. All rights reserved. | [Terms of Use](https://www.apple.com/legal/internet-services/terms/site.html) | [Privacy Policy](https://www.apple.com/privacy/privacy-policy)