<!--
{
  "availability" : [
    "iOS: 26.0.0 -",
    "iPadOS: 26.0.0 -",
    "macCatalyst: 26.0.0 -",
    "macOS: 26.0.0 -",
    "tvOS: 26.0.0 -"
  ],
  "documentType" : "symbol",
  "framework" : "RealityKit",
  "identifier" : "/documentation/RealityKit/PostProcessEffectContext",
  "metadataVersion" : "0.1.0",
  "role" : "Structure",
  "symbol" : {
    "kind" : "Structure",
    "modules" : [
      "RealityKit"
    ],
    "preciseIdentifier" : "s:17RealityFoundation24PostProcessEffectContextV"
  },
  "title" : "PostProcessEffectContext"
}
-->

# PostProcessEffectContext

An object RealityKit passes data to a post process effect method.

```
struct PostProcessEffectContext<CommandBuffer>
```

## Overview

You can register a method that applies
postprocessing effects to a scene RealityKit renders with a [`RealityView`](/documentation/RealityKit/RealityView).
Once every frame, RealityKit calls that function before displaying the scene.
You can use this to apply postprocess effects using
any APIs that can modify an image texture.
However, because RealityKit calls this method every
frame, prioritize using APIs that execute on the GPU, such as Metal compute functions,
<doc://com.apple.documentation/documentation/MetalPerformanceShaders>,
or <doc://com.apple.documentation/documentation/CoreImage>.
You can also render additional content on top of the frame buffer,
such as a SpriteKit scene.

> Note: For more information on implementing postprocess effects, see
> <doc://com.apple.documentation/documentation/RealityKit/implementing-special-rendering-effects-with-realitykit-postprocessing>,
> which demonstrates multiple postprocess techniques.

A postprocess method takes a single `PostProcessEffectContext` parameter, which contains
data the callback method needs to modify the rendered scene, including the frame buffer, depth
map, and a property for writing the image you modify.
The postprocess method in your [`PostProcessEffect`](/documentation/RealityKit/PostProcessEffect) type
needs to encode to the output texture, or the frame is never displayed.

A postprocess method looks like this:

```swift
func postProcess(context: borrowing PostProcessEffectContext<MTLCommandBuffer>) {
    // Handle postprocessing here.
}
```

To register a method as the postprocess render callback, add an implementation for
[`postProcess(context:)`](/documentation/RealityKit/PostProcessEffect/postProcess(context:)) in your
type that conforms to [`PostProcessEffect`](/documentation/RealityKit/PostProcessEffect):

```swift
class LaplacianPostProcess: PostProcessEffect {
    // Post process callback.
    func postProcess(context: borrowing PostProcessEffectContext<MTLCommandBuffer>) {
        let filter = MPSImageLaplacian()
        filter.encode(commandBuffer: context.commandBuffer,
                    sourceTexture: context.sourceColorTexture,
                    destinationTexture: context.compatibleTargetTexture)
    }
}
```

To stop postprocessing, you can set the [`customPostProcessing`](/documentation/RealityKit/RealityViewRenderingEffects/customPostProcessing)
property to [`none`](/documentation/RealityKit/RealityViewPostProcessEffect/none).

```swift
content.renderingEffects.customPostProcessing = .none
```

If your app turns postprocessing on and off frequently, another option for disabling postprocess
effects is to keep your callbacks registered, but use an <doc://com.apple.documentation/documentation/Metal/MTLBlitCommandEncoder>
to encode the unmodified frame buffer directly to the output texture whenever postprocess effects
aren’t active.

```swift
var isEnabled: Binding<Bool>

func postProcess(context: borrowing PostProcessEffectContext<MTLCommandBuffer>) {
    if isEnabled.wrappedValue {
        let filter = MPSImageLaplacian()
        filter.encode(commandBuffer: context.commandBuffer,
                    sourceTexture: context.sourceColorTexture,
                    destinationTexture: context.compatibleTargetTexture)
    } else {
        // Remove processing effects.
        let blitEncoder = context.commandBuffer.makeBlitCommandEncoder()
        blitEncoder?.copy(from: context.sourceColorTexture, to: context.targetColorTexture)
        blitEncoder?.endEncoding()
    }
}
```

## Topics

### Instance Properties

[`var commandBuffer: CommandBuffer`](/documentation/RealityKit/PostProcessEffectContext/commandBuffer)

The Metal command buffer for encoding the frame.

[`var device: any MTLDevice`](/documentation/RealityKit/PostProcessEffectContext/device)

The Metal device where the scene renders.

[`var projection: float4x4`](/documentation/RealityKit/PostProcessEffectContext/projection)

The projection matrix that renders the frame.

[`var sourceColorTexture: any MTLTexture`](/documentation/RealityKit/PostProcessEffectContext/sourceColorTexture)

The rendered frame buffer.

[`var sourceDepthTexture: any MTLTexture`](/documentation/RealityKit/PostProcessEffectContext/sourceDepthTexture)

The frame’s depth buffer.

[`var targetColorTexture: any MTLTexture`](/documentation/RealityKit/PostProcessEffectContext/targetColorTexture)

The output texture where the postprocess callback writes the
modified frame buffer.

[`var time: TimeInterval`](/documentation/RealityKit/PostProcessEffectContext/time)

The scene’s elapsed time.

---

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)