Skip to content

feat: Add onBefore and onAfter callbacks to all frame passes - #9788

Merged
mvaligursky merged 1 commit into
mainfrom
mv-pass-before-after-hooks
Oct 16, 2026
Merged

mvaligursky merged 1 commit into
mainfrom
mv-pass-before-after-hooks

Conversation

@mvaligursky

Copy link
Copy Markdown
Contributor

Every frame pass can now run code right before and right after it executes, using the onBefore and onAfter callbacks that ComputePass had.

Changes:

  • onBefore and onAfter move from ComputePass to FramePass, so render passes and custom frame passes have them too. onBefore is called after the pass's before(), and onAfter after its after(), with the pass as the argument. Like before() and after(), they are called even if executeEnabled is false, but not when the pass is disabled.
  • For a render pass, the callbacks run outside of its GPU render pass: the frame graph does not merge a pass with its neighbour into a single GPU render pass when a callback runs between them. onAfter can therefore read back what the pass rendered.
  • The auto exposure reads back its histogram in onAfter of its pass, instead of replacing the pass's after() method.

Examples:

// read back what a render pass rendered, once its GPU render pass has ended
renderPass.onAfter = () => {
    texture.read(0, 0, width, height).then(data => console.log(data));
};

The onBefore and onAfter callbacks of ComputePass move to FramePass, so
every frame pass can run code right before and after it executes. For
a render pass, they run outside of its GPU render pass: the frame graph
does not merge a pass with its neighbour when a callback runs between
them, so onAfter can read back what the pass rendered.

The luminance histogram of the auto exposure uses onAfter to read back
its histogram, instead of replacing the after method of its pass.
@github-actions

Copy link
Copy Markdown

Build size report

This PR changes the size of the minified bundles.

Bundle Minified Gzip Brotli
playcanvas.min.js 2664.5 KB (+50 B, +0.00%) 690.9 KB (+9 B, +0.00%) 535.8 KB (+107 B, +0.02%)
playcanvas.min.mjs 2661.3 KB (+50 B, +0.00%) 689.6 KB (+6 B, +0.00%) 535.2 KB (−79 B, −0.01%)

@mvaligursky mvaligursky left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated PR review by Codex (OpenAI AI agent), posted through the account holder's authorized automated review process.

Reviewed f7e6c9353 against f8a0540a2. No actionable findings.

The callback placement preserves before/after ordering and the existing ComputePass execution/view-selection behavior. The merge restriction applies at the callback boundary: first.onAfter and second.onBefore prevent merging, while first.onBefore and second.onAfter still allow it. Callback references are released by destruction, and the generated polymorphic this signatures preserve subclass-specific parameter types.

Validation:

  • Full unit suite: 4,396 passing, 43 pending.
  • Full WebGPU/Metal suite: 4,395 passing, 39 pending, including existing compute callback/view-selection coverage.
  • Declaration build, consumer type tests, and lint of all changed files passed.
  • Real WebGL2/WebGPU readback probes verified both boundary callbacks run outside a GPU render pass and receive the correct pass. A deferred read requested between a red clear and a green draw returned red, while the final target was green. Outer callbacks retained merging and also ran outside the GPU pass.
  • The auto-exposure histogram readback completed with exactly matching bins on base and head on both backends.
  • Runtime-inspection/pixel-verification checks of ordinary rendering and CameraFrame with a depth prepass at two camera poses found 0 / 16,384 differing pixels per backend; repeated baseline captures also matched exactly.

@mvaligursky
mvaligursky merged commit 69a535d into main Oct 16, 2026
11 checks passed
@mvaligursky
mvaligursky deleted the mv-pass-before-after-hooks branch October 16, 2026 20:54

This branch was successfully deployed

2 active deployments
Preview – engine — f7e6c935 Deployed Oct 16, 2026 by vercel[bot]
Preview – engine-api-docs — f7e6c935 Deployed Oct 16, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant