dubois
November 11, 2025, 10:15pm
3
Stencil does improve the performance
A long time ago we discussed this here:
dev ← pailhead:own-depthstencil-target-buffer
opened 08:23PM - 29 Dec 18 UTC
### Problem
Multiple `WebGLRenderTarget` can't share the same depth / stenci… l render buffer because `WebGLRenderer` creates them in a private cache. This is possible to do with webgl, [but not with three.js. ](https://github.com/mrdoob/three.js/issues/15440)
### Proposal
Have the `WebGLRenderer` attempt to use an existing buffer if one is provided. And allow the targets to be used so:
```
targetA.ownDepthBuffer = buffer
targetB.ownDepthBuffer = buffer
```
### Use case
This [depth peel example](https://raw.githack.com/pailhead/three.js/depth-peel-stencil/examples/webgl_materials_depthpeel.html), goes from not being interactive to working on phones when stencil masking is used ([video](https://www.youtube.com/watch?v=nMfQeotbN8s)).
### Argument for
There are a few things in three.js that already work like this i think. `defines`, `customDepthMaterial` are the two that pop to mind - you could set them, and they would make `WebGLRenderer` do certain things, but were not present in documentation for a long time. This does not change the behavior of the renderer in any way, and allows WebGL to be fully utilized.
### Optional
Document it:
> Sets the render buffer on the target. If one is not provided, three creates one internally for this target. You can share render buffers between targets:
```
const gl = renderer.getContext()
const buffer = gl.createRenderBuffer()
targetA.ownDepthBuffer = buffer
targetB.ownDepthBuffer = buffer
```
### Future (if accepted)
Make an API:
```
const buffer = new THREE.RenderBuffer(config)
targetA.depthBuffer = buffer
targetB.depthBuffer = buffer
```
I never figured out if you were in fact able to achieve this using textures, my conclusion was that without the proposed modification it was not possible.
Edit
dev ← gkjohnson:reassignable-depth
opened 12:43AM - 08 Jun 24 UTC
Related issue: #19447, #15490, other [depth peeling discussions](https://github.… com/mrdoob/three.js/issues?q=depth+peeling)
**Description**
This PR adjusts the `setRenderTarget` function to rebind the depth attachment so that it can be re assigned, unbound, and shared between multiple different render targets. If you set the render target and _then_ set `.depthTexture`, though, it will not take effect until `setRenderTarget` is called again.
This allows a lot more flexibility in the reuse of render targets and depth textures while avoiding texture read / write feedback loops. For example it allows for implementing depth peeling without having to manually copy data between textures to avoid this kind of feedback.
There's a demo [here](https://gkjohnson.github.io/depth-peeling-demo/) and [here](https://gkjohnson.github.io/depth-peeling-demo/#drone) demonstrating this PRs use for depth peeling:
| Before | After |
|---|---|
| <img width="300" alt="image" src="https://github.com/mrdoob/three.js/assets/734200/615febf6-8b21-4c4b-98d6-742df4971a06"> | <img width="300" alt="image" src="https://github.com/mrdoob/three.js/assets/734200/a7b3175b-7be1-4301-bb16-ec509f5aa4b5"> |
| <img width="300" alt="image" src="https://github.com/mrdoob/three.js/assets/734200/483a37a5-8770-4a0f-9ba6-68c280bf0e8f"> | <img width="300" alt="image" src="https://github.com/mrdoob/three.js/assets/734200/036e50ab-ee7b-4606-b4ee-c16ad2ab2a05"> |
| <img width="300" alt="image" src="https://github.com/mrdoob/three.js/assets/734200/6107b013-df7e-45f1-87a6-8ba5425f1c3c"> | <img width="300" alt="image" src="https://github.com/mrdoob/three.js/assets/734200/7d412a66-a904-4749-a900-3b99a75201e6"> |
cc @donmccurdy I know you've expressed interest in this kind of OIT previously.
Looks like it is possible now? Three has the API to do the proper setup?
1 Like