Skip to content
Open
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
8c785ff
Add transmission example
Popov72 May 20, 2025
9ecbff3
Add doc for the motion blur post-process
Popov72 May 24, 2025
3c5c872
Add geometry texture VAT example to frame graph doc
Popov72 Jun 10, 2025
26e9d11
Merge branch 'master' of https://github.com/BabylonJS/Documentation i…
Popov72 Jun 10, 2025
cc09ab9
Merge branch 'master' of https://github.com/BabylonJS/Documentation i…
Popov72 Oct 21, 2025
ed8ee83
Update the TAA block doc
Popov72 Oct 22, 2025
1b19cf8
Add an example to create a custom post-process
Popov72 Oct 24, 2025
0ed481d
Merge branch 'master' of https://github.com/BabylonJS/Documentation i…
Popov72 Oct 24, 2025
0fd6516
Add doc about the class framework
Popov72 Oct 28, 2025
feaba5c
Merge branch 'master' of https://github.com/BabylonJS/Documentation i…
Popov72 Oct 28, 2025
3fa9015
Merge branch 'master' of https://github.com/BabylonJS/Documentation i…
Popov72 Nov 1, 2025
e8410aa
Add more frame graph doc
Popov72 Nov 1, 2025
a050dc2
More update
Popov72 Nov 5, 2025
520b8f8
More docs
Popov72 Nov 8, 2025
b3fa17a
Merge branch 'master' of https://github.com/BabylonJS/Documentation i…
Popov72 Nov 8, 2025
2e340f7
Fix typo
Popov72 Nov 9, 2025
cc8534a
Change structure
Popov72 Nov 10, 2025
5bb36b7
Add description for new properties
Popov72 Nov 12, 2025
0d9058c
Fix doc wrt cull passes
Popov72 Nov 13, 2025
6f2d6a4
Address comments
Popov72 Nov 13, 2025
cb09614
Address comments
Popov72 Nov 13, 2025
e571de1
Fix PG
Popov72 Nov 13, 2025
84062d5
Revert change
Popov72 Nov 17, 2025
a6de89a
Fix PGs
Popov72 Nov 18, 2025
c91e7a9
Fix pg
Popov72 Nov 18, 2025
8fef068
Update doc according to latest changes in code
Popov72 Nov 20, 2025
df5a72f
More updates
Popov72 Nov 20, 2025
b827750
Fix VAT PGs
Popov72 Nov 21, 2025
2a1d7e9
Fix doc VAT
Popov72 Nov 21, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 18 additions & 2 deletions configuration/structure.json
Original file line number Diff line number Diff line change
Expand Up @@ -659,16 +659,32 @@
},
"content": "features/featuresDeepDive/frameGraph/frameGraphBasicConcepts"
},
"frameGraphClassFramework": {
"friendlyName": "Frame Graph Framework Description",
"children": {
"frameGraphClassOverview": {
"friendlyName": "Introduction to Frame Graph classes",
"children": {},
"content": "features/featuresDeepDive/frameGraph/frameGraphClassFramework/frameGraphClassOverview"
},
"frameGraphTaskList": {
"friendlyName": "Frame Graph Task List",
"children": {},
"content": "features/featuresDeepDive/frameGraph/frameGraphClassFramework/frameGraphTaskList"
}
},
"content": "features/featuresDeepDive/frameGraph/frameGraphClassFramework"
},
"frameGraphBlocks": {
"friendlyName": "Render Graph Blocks",
"friendlyName": "Node Render Graph Blocks",
"children": {
"frameGraphBlocksGeneralNotes": {
"friendlyName": "General notes about Render Graph Blocks",
"children": {},
"content": "features/featuresDeepDive/frameGraph/frameGraphBlocks/frameGraphBlocksGeneralNotes"
},
"frameGraphBlocksDescription": {
"friendlyName": "Description of the Render Graph Blocks",
"friendlyName": "Render Graph Blocks Description",
"children": {},
"content": "features/featuresDeepDive/frameGraph/frameGraphBlocks/frameGraphBlocksDescription"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,23 @@ Each task declares its input and output resources.

The resources can be textures, a list of renderable meshes, cameras, lights. As for the textures, they are allocated and managed by the frame graph subsystem and not directly by the tasks. This allows us to optimize the allocation of textures and reuse them during the execution of a graph, thus saving GPU memory.

By default, there is no persistence of resources between each execution of a rendering graph, unless a resource is specifically labeled as “persistent” (think of a texture that must be reused from one frame to the next). In our implementation, persistent textures are used to implement “ping-pong” textures, where we change the read and write textures with each frame (used to implement the temporal antialiasing task, for example).
By default, there is no persistence of resources between each execution of a render graph, unless a resource is specifically labeled as “persistent” (think of a texture that must be reused from one frame to the next). In our implementation, persistent textures are used to implement “ping-pong” textures, where we change the read and write textures with each frame (used to implement the temporal antialiasing task, for example).

To clarify the ideas, here is a simple graph:

![Basic graph](/img/frameGraph/basic_graph.jpg)

The “Color Texture”, “Depth Texture”, “Camera” and “Object List” nodes are input resources (respectively, of the texture, depth texture, camera and object list type). “Clear” and “Main Rendering” are two tasks, the first clears a texture/depth texture and the second renders objects in a texture. “Output” is the output buffer (think of it as the screen output).

As a user, the process of creating and using a frame graph is as follows:
* Create a frame graph, either by using the `FrameGraphXXX` classes (see [Frame Graph Framework Description](/features/featuresDeepDive/frameGraph/frameGraphClassFramework)), or by loading a node render graph (see [Node Render Graph Blocks](/features/featuresDeepDive/frameGraph/frameGraphBlocks)).
* Build the frame graph (`FrameGraph.build()` or `NodeRenderGraph.build()`).
* Wait until all frame graph tasks + internal states are ready: `await FrameGraph.whenReadyAsync()` or `await NodeRenderGraph.whenReadyAsync()`.
<br/>
At this point, the frame graph can be safely executed: call `FrameGraph.execute()`, or simply set `scene.frameGraph = myFrameGraph`, in which case the call to `execute` will be performed by the scene's rendering loop.

Note that in this scenario, you never have to manage passes: you will only need to create passes when you create your own tasks. As a user, you simply use the existing tasks (see [Frame Graph Task List](/features/featuresDeepDive/frameGraph/frameGraphClassFramework/frameGraphTaskList) for the list of existing tasks in the framework), creating an instance of the task, setting its input parameters to reasonable values, and adding the task to the frame graph. See [Introduction to Frame Graph classes](/features/featuresDeepDive/frameGraph/frameGraphClassFramework/frameGraphClassOverview) for more information.

### Benefits

A frame graph allows a high-level knowledge of the whole frame to be acquired, which:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,16 +100,24 @@ You can also call `await FrameGraph.whenReadyAsync()` to make sure that all the

Finally, you must manage the resizing of the screen, so simply call `frameGraph.build()` when the engine resizes:
```javascript
engine.onResizeObservable.add(() => {
const buildGraph = async () => {
frameGraph.build();
});

frameGraph.build();
frameGraph.pausedExecution = true;
await frameGraph.whenReadyAsync();
frameGraph.pausedExecution = false;
};

engine.onResizeObservable.add(async () => {
await buildGraph();
});

await frameGraph.whenReadyAsync();
await buildGraph();
```

Here's the PG corresponding to this example: <Playground id="#9YU4C5#12" title="Frame Graph basic example" description="Basic frame graph example in replacement of the scene render loop (manual use of the frame graph classes)"/>
Here's the PG corresponding to this example: <Playground id="#9YU4C5#109" image="/img/playgroundsAndNMEs/pg-9YU4C5-12.png" title="Frame Graph basic example" description="Basic frame graph example in replacement of the scene render loop (manual use of the frame graph classes)"/>

Note that we pause the execution of the frame graph before calling `whenReadyAsync()` and then resume it, because this call is asynchronous, which means that the scene rendering loop will potentially be executed several times before the frame graph is ready. Since we don't want the graph to run before it is fully ready, we need to pause it by setting the **pausedExecution** property to *true*.

## Using a node render graph

Expand All @@ -132,6 +140,8 @@ That's all you need to make it work with a node render graph!

The full PG: <Playground id="#9YU4C5#11" title="Frame Graph basic example" description="Basic frame graph example in replacement of the scene render loop (node render graph)"/>

Note that this time, we don't have to manage the **pausedExecution** property ourselves, as it is managed automatically by `NodeRenderGraph.whenReadyAsync`.

For more complicated examples, you may need to pass a third parameter to `NodeRenderGraph.ParseFromSnippetAsync()` to configure the node render graph:
```javascript
const nrg = await BABYLON.NodeRenderGraph.ParseFromSnippetAsync("#CCDXLX", scene, {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,10 @@ Once again, the inputs and outputs are self-explanatory: **target** is the textu

## Misc blocks

<H3Image title="ComputeShader" image="/img/frameGraph/block_computeshader.jpg" alt="ComputeShader node"/>

This block allows you to execute a compute shader (WebGPU only - doesn't do anything in WebGL). The compute shader must be configured programmatically. See the NRG playground in [FrameGraphComputeShaderTask](/features/featuresDeepDive/frameGraph/frameGraphClassFramework/frameGraphTaskList#framegraphcomputeshadertask) for an example of how to use this block.

<H3Image title="Cull" image="/img/frameGraph/block_cull.jpg" alt="Cull node"/>

This block allows you to cull a list of objects against a camera frustum: you must provide the camera via the **camera** input, and the list of objects via the **objects** input. The result of this block is provided by the **output**: the list of objects that are (at least partially) inside the camera frustum.
Expand All @@ -244,8 +248,6 @@ executeBlock.task.func = (_context) => {
};
```

In WebGPU, you can use this block to execute a compute shader at a specific moment in the execution of the frame graph, for example.

<H3Image title="GUI" image="/img/frameGraph/block_gui.jpg" alt="GUI node"/>

This block allows you to apply a full-screen GUI over a frame graph texture.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
title: Frame Graph Framework Description
image:
description: Learn all about the Babylon.js Frame Graph system.
keywords: diving deeper, frame graph, rendering, node editor, framework
---

See the [Basic Concepts and Getting Started](/features/featuresDeepDive/frameGraph/frameGraphBasicConcepts) section for general information on nomenclature and an overview of the frame graph concept.

This section describes the frame graph class framework:
* [Overview of the frame graph framework](/features/featuresDeepDive/frameGraph/frameGraphClassFramework/frameGraphClassOverview) describes the main classes that are part of the framework
* [List of task classes in the frame graph framework](/features/featuresDeepDive/frameGraph/frameGraphClassFramework/frameGraphTaskList) describes all the tasks that can be used with a frame graph.
<br/>
Note that the implementation of the framework is inspired by Unity's [Render Graph System](https://docs.unity3d.com/6000.2/Documentation/Manual/urp/render-graph-introduction.html).

Loading