Skip to content

[Native] MultiRenderTarget, reverse-Z clear, applyStates, OIT alpha modes#18568

Draft
bkaradzic-microsoft wants to merge 1 commit into
masterfrom
native-multi-render-target
Draft

[Native] MultiRenderTarget, reverse-Z clear, applyStates, OIT alpha modes#18568
bkaradzic-microsoft wants to merge 1 commit into
masterfrom
native-multi-render-target

Conversation

@bkaradzic-microsoft

@bkaradzic-microsoft bkaradzic-microsoft commented Jun 11, 2026

Copy link
Copy Markdown
Member

Paired native PR: BabylonJS/BabylonNative#1754

What

Foundational native-engine surface so MultiRenderTarget, the reverse depth buffer, and the
order-independent-transparency (depth-peeling) renderer stop dereferencing the null _gl context.
This removes several distinct crash classes. It does not by itself turn the MRT/OIT/FrameGraph
validation tests green — those need further work (see Follow-ups).

Changes (packages/dev/core/src/Engines)

  • thinNativeEngine.pure.ts
    • createMultipleRenderTarget + the MRT helper overrides: bindAttachments, buildTextureLayout,
      restoreSingleAttachment/restoreSingleAttachmentForRenderTarget, generateMipMapsMultiFramebuffer,
      resolveMultiFramebuffer, unBindMultiColorAttachmentFramebuffer,
      updateMultipleRenderTargetTextureSampleCount. bgfx writes every color attachment of the bound
      framebuffer, so the WebGL drawBuffers / MSAA-resolve plumbing becomes no-ops on Native. Reports
      drawBuffersExtension = true.
    • clear(): implement the reverse depth buffer (clear depth to 0 + GEQUAL) instead of throwing.
    • applyStates(): override so it flushes the depth-culling state through the native command path —
      the base implementation drives the null _gl directly, which crashed callers that mutate
      engine.depthCullingState then call applyStates() (e.g. the OIT depth-peeling renderer).
  • Native/nativeHelpers.ts / nativeInterfaces.ts: map alpha modes ALPHA_ONEONE_ONEONE and
    ALPHA_LAYER_ACCUMULATE to the native engine; declare createMultiFrameBuffer.

Paired native PR

Requires the matching BabylonNative C++ change (NativeEngine::CreateMultiFrameBuffer + the two alpha
blend modes).

Follow-ups (not in this PR)

  • OIT depth-peeling (thinDepthPeelingRenderer) still faults inside the D3D11 driver on submit
    (a multi-output / SRV↔RTV ping-pong state the driver rejects); needs interactive GPU debugging.
  • The blend equation (e.g. MAX) is not yet applied on Native (setAlphaEquation is a no-op),
    so OIT blending would still be incorrect once the crash is resolved.

Testing

Built babylon.max.js and ran the BabylonNative Playground suite (D3D11). MRT, reverse-Z, and the
depth-peeling setup no longer crash with COLOR_ATTACHMENT0 / reverse depth buffer /
depthMask of undefined / Unsupported alpha mode. No regressions in existing 2D render-target tests.


Related PRs & landing order

These two are co-dependent and land in this order:

  1. Babylon.js [Native] MultiRenderTarget, reverse-Z clear, applyStates, OIT alpha modes #18568 first — it only adds native-engine TS overrides, changes no WebGL behavior, and re-enables no validation tests on its own, so it can merge independently.
  2. A babylonjs npm release ships that TS change.
  3. BabylonNative check animations all stop bug. #1754 last — after bumping the bundled babylonjs to that release. (This foundational pair does not yet turn the MRT/OIT/FrameGraph tests green — that is separate follow-up work.)

@bjsplat

bjsplat commented Jun 11, 2026

Copy link
Copy Markdown
Collaborator

Please make sure to label your PR with "bug", "new feature" or "breaking change" label(s).
To prevent this PR from going to the changelog marked it with the "skip changelog" label.

@bjsplat

bjsplat commented Jun 11, 2026

Copy link
Copy Markdown
Collaborator

Snapshot stored with reference name:
refs/pull/18568/merge

Test environment:
https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/refs/pull/18568/merge/index.html

To test a playground add it to the URL, for example:

https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/refs/pull/18568/merge/index.html#WGZLGJ#4600

Links to test your changes to core in the published versions of the Babylon tools (does not contain changes you made to the tools themselves):

https://playground.babylonjs.com/?snapshot=refs/pull/18568/merge
https://sandbox.babylonjs.com/?snapshot=refs/pull/18568/merge
https://gui.babylonjs.com/?snapshot=refs/pull/18568/merge
https://nme.babylonjs.com/?snapshot=refs/pull/18568/merge

To test the snapshot in the playground with a playground ID add it after the snapshot query string:

https://playground.babylonjs.com/?snapshot=refs/pull/18568/merge#BCU1XR#0

If you made changes to the sandbox or playground in this PR, additional comments will be generated soon containing links to the dev versions of those tools.

@bjsplat

bjsplat commented Jun 11, 2026

Copy link
Copy Markdown
Collaborator

@bjsplat

bjsplat commented Jun 11, 2026

Copy link
Copy Markdown
Collaborator

🟢 Memory Leak Test Results

13 passed, 0 leaked out of 13 scenarios

🟢 All memory leak tests passed — no leaks detected.

Passed Scenarios (13)
Scenario Package
Core Feature Stack @babylonjs/core
Core Rendering Materials Shadows Stack @babylonjs/core
Core Textures Render Targets PostProcess Stack @babylonjs/core
GUI Fullscreen UI Controls @babylonjs/gui
GUI Mesh ADT Controls @babylonjs/gui
Loaders Boombox Import @babylonjs/loaders
Loaders OBJ Direct Load @babylonjs/loaders
Loaders STL Direct Load @babylonjs/loaders
Materials Library Stack @babylonjs/materials
Serializers glTF Export @babylonjs/serializers
Serializers GLB Export @babylonjs/serializers
PostProcesses Digital Rain Stack @babylonjs/post-processes
Procedural Textures Stack @babylonjs/procedural-textures

@bjsplat

bjsplat commented Jun 11, 2026

Copy link
Copy Markdown
Collaborator

@bjsplat

bjsplat commented Jun 11, 2026

Copy link
Copy Markdown
Collaborator

@bjsplat

bjsplat commented Jun 11, 2026

Copy link
Copy Markdown
Collaborator

⚡ Performance Test Results

🟢 All performance tests passed — no regressions detected.

…odes

Foundational native-engine surface so MultiRenderTarget, the reverse depth
buffer, and the order-independent-transparency renderer stop dereferencing the
null _gl context. Removes several crash classes; does not by itself land the
dependent validation tests.

- createMultipleRenderTarget + the MRT helper overrides (bindAttachments,
  buildTextureLayout, restoreSingleAttachment[ForRenderTarget],
  generateMipMapsMultiFramebuffer, resolveMultiFramebuffer,
  unBindMultiColorAttachmentFramebuffer,
  updateMultipleRenderTargetTextureSampleCount). bgfx writes every color
  attachment of the bound framebuffer, so the WebGL drawBuffers / MSAA-resolve
  plumbing becomes no-ops on Native. Reports drawBuffersExtension = true.
- clear(): implement the reverse depth buffer (clear depth to 0 + GEQUAL)
  instead of throwing.
- applyStates(): override so it flushes the depth-culling state through the
  native command path (the base implementation drives the null _gl directly),
  fixing callers that mutate engine.depthCullingState then call applyStates()
  (e.g. the OIT depth-peeling renderer).
- Map alpha modes ALPHA_ONEONE_ONEONE and ALPHA_LAYER_ACCUMULATE to the native
  engine.

Pairs with the BabylonNative change (createMultiFrameBuffer + native alpha
modes). Known follow-ups: OIT depth-peeling still faults in the D3D11 driver on
submit; the blend equation (MAX) is not yet applied natively.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@bkaradzic-microsoft bkaradzic-microsoft force-pushed the native-multi-render-target branch from 5e7e85e to c5da3b6 Compare June 16, 2026 17:04
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.

3 participants