Skip to content

Commit 849d328

Browse files
authored
TSL: Add RenderPipeline for TSL Spec (#32928)
1 parent a5a4b62 commit 849d328

File tree

1 file changed

+108
-12
lines changed

1 file changed

+108
-12
lines changed

wiki/TSL.md

Lines changed: 108 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,11 @@ An Approach to Productive and Maintainable Shader Creation.
4444
- [Oscillator](#oscillator)
4545
- [Timer](#timer)
4646
- [Packing](#packing)
47-
- [Post-Processing](#post-processing)
48-
- [Render Pass](#render-pass)
49-
- [Compute](#compute)
47+
- [Render Pipeline](#render-pipeline)
48+
- [Multiple Render Targets](#multiple-render-targets-mrt)
49+
- [Post-Processing](#post-processing)
50+
- [Render Pass](#render-pass)
51+
- [Compute](#compute)
5052
- [Storage](#storage)
5153
- [Struct](#struct)
5254
- [Flow Control](#flow-control)
@@ -1134,7 +1136,102 @@ const matcap = texture( matcapMap, matcapUV );
11341136
| `directionToColor( value )` | Converts direction vector to color. | `color` |
11351137
| `colorToDirection( value )` | Converts color to direction vector. | `vec3` |
11361138

1137-
## Post-Processing
1139+
## Render Pipeline
1140+
1141+
The `RenderPipeline` provides full control over the rendering process. It enables developers to build complex multi-pass rendering pipelines entirely in JavaScript, combining scene rendering, post-processing, and compute operations in a unified, composable workflow.
1142+
1143+
#### Basic Usage
1144+
1145+
```js
1146+
import * as THREE from 'three/webgpu';
1147+
import { pass } from 'three/tsl';
1148+
1149+
// Create the render pipeline
1150+
const renderPipeline = new THREE.RenderPipeline( renderer );
1151+
1152+
// Create a scene pass
1153+
const scenePass = pass( scene, camera );
1154+
1155+
// Set the output
1156+
renderPipeline.outputNode = scenePass;
1157+
1158+
// In the animation loop
1159+
function animate() {
1160+
1161+
renderPipeline.render();
1162+
1163+
}
1164+
```
1165+
1166+
### Multiple Render Targets (MRT)
1167+
1168+
MRT allows capturing multiple outputs from a single render pass. Instead of rendering the scene multiple times to get different data (color, normals, depth, velocity), MRT captures all of them in one draw call—significantly improving performance.
1169+
1170+
#### Setting up MRT
1171+
1172+
Use `setMRT()` with the `mrt()` function to define which outputs to capture:
1173+
1174+
```js
1175+
import { pass, mrt, output, normalView, velocity, directionToColor } from 'three/tsl';
1176+
1177+
const scenePass = pass( scene, camera );
1178+
1179+
scenePass.setMRT( mrt( {
1180+
output: output, // Final color output
1181+
normal: directionToColor( normalView ), // View-space normals encoded as colors
1182+
velocity: velocity // Motion vectors for temporal effects
1183+
} ) );
1184+
```
1185+
1186+
Each MRT entry accepts any TSL node, allowing you to customize outputs using formulas, encoders, or material accessors. For example, `directionToColor( normalView )` encodes view-space normals into RGB values. You can use any TSL function to transform, combine, or encode data before writing to the render target.
1187+
1188+
Within a TSL function `Fn( ( { material, object } ) => { ... } )`, you have complete access to the current material and object being rendered, enabling full customization of outputs.
1189+
1190+
#### Accessing MRT Buffers
1191+
1192+
Each MRT output becomes available as a texture node via `getTextureNode()`:
1193+
1194+
```js
1195+
// Access individual buffers as texture nodes
1196+
const colorTexture = scenePass.getTextureNode( 'output' );
1197+
const normalTexture = scenePass.getTextureNode( 'normal' );
1198+
const velocityTexture = scenePass.getTextureNode( 'velocity' );
1199+
1200+
// Depth is always available, even without MRT
1201+
const depthTexture = scenePass.getTextureNode( 'depth' );
1202+
```
1203+
1204+
These texture nodes can be sampled, transformed, and passed to post-processing effects or other passes.
1205+
1206+
#### Optimizing MRT Textures
1207+
1208+
You can access the textures to optimize memory usage and bandwidth. Using smaller data types reduces GPU memory transfers, which is critical for performance on bandwidth-limited devices:
1209+
1210+
```js
1211+
// Use 8-bit format for encoded normals, default is 16-bit
1212+
const normalTexture = scenePass.getTexture( 'normal' );
1213+
normalTexture.type = THREE.UnsignedByteType;
1214+
```
1215+
1216+
#### Dynamic Pipeline Updates
1217+
1218+
The pipeline can be updated at runtime:
1219+
1220+
```js
1221+
if ( showNormals ) {
1222+
1223+
renderPipeline.outputNode = prePass;
1224+
1225+
} else {
1226+
1227+
renderPipeline.outputNode = traaPass;
1228+
1229+
}
1230+
1231+
renderPipeline.needsUpdate = true;
1232+
```
1233+
1234+
### Post-Processing
11381235

11391236
TSL utilities for post-processing effects. They can be used in materials or post-processing passes.
11401237

@@ -1165,30 +1262,29 @@ TSL utilities for post-processing effects. They can be used in materials or post
11651262
| `ao( depthNode, normalNode, camera )` | Creates a Ground Truth Ambient Occlusion (GTAO) effect. |
11661263
| `transition( nodeA, nodeB, mixTextureNode, mixRatio, threshold, useTexture )` | Creates a transition effect between two scenes. |
11671264
| `traa( beautyNode, depthNode, velocityNode, camera )` | Creates a TRAA temporal anti-aliasing effect. |
1265+
| `renderOutput( node, targetColorSpace, targetToneMapping )` | Apply the renderer output settings in the node. |
11681266

11691267
Example:
11701268

11711269
```js
1172-
import { gaussianBlur, grayscale, pass } from 'three/tsl';
1270+
import { grayscale, pass } from 'three/tsl';
1271+
import { gaussianBlur } from 'three/addons/tsl/display/GaussianBlurNode.js';
11731272

11741273
// Post-processing
11751274
const scenePass = pass( scene, camera );
1176-
const beauty = scenePass.getTextureNode();
1275+
const output = scenePass.getTextureNode(); // default parameter is 'output'
11771276

1178-
postProcessing.outputNode = grayscale( gaussianBlur( beauty, 4 ) );
1277+
renderPipeline.outputNode = grayscale( gaussianBlur( output, 4 ) );
11791278
```
11801279

1181-
## Render Pass
1280+
### Render Pass
11821281

11831282
Functions for creating and managing render passes.
11841283

11851284
| Name | Description |
11861285
| -- | -- |
11871286
| `pass( scene, camera, options = {} )` | Creates a pass node for rendering a scene. |
1188-
| `passTexture( pass, texture )` | Creates a pass texture node. |
1189-
| `depthPass( scene, camera, options = {} )` | Creates a depth pass node. |
11901287
| `mrt( outputNodes )` | Creates a Multiple Render Targets (MRT) node. |
1191-
| `renderOutput( node, targetColorSpace, targetToneMapping )` | Creates a render output node. |
11921288

11931289
Example:
11941290

@@ -1207,7 +1303,7 @@ const outputNode = scenePass.getTextureNode( 'output' );
12071303
const emissiveNode = scenePass.getTextureNode( 'emissive' );
12081304
```
12091305

1210-
## Compute
1306+
### Compute
12111307

12121308
Compute shaders allow general-purpose GPU computations. TSL provides functions for creating and managing compute operations.
12131309

0 commit comments

Comments
 (0)