I am developing with WebGPU and have two scenes. For specific reasons, I need to split them into two separate passes and then merge them. However, I want the second pass to share the depth from the first pass. Is there a convenient way to handle this using TSL?
Can you please how your code setup? Are you working with RenderPipeline?
Yes, I do have a scene. I want to apply post-processing to only part of the elements, while leaving the rest unprocessed.
So I split it into two passes:
-
The first pass handles rendering + post-processing.
-
The second pass builds on top of the first pass and mainly needs to inherit (reuse) the depth from the first pass.
After that, I merge the two passes into a final result.
That’s roughly the idea. The problem is that I don’t know how to share the depth buffer between different passes.
Can you please share a minimal live example that demonstrates the setup? You can use three.js dev template - module - JSFiddle - Code Playground as a starter template.
This will make it easier for us to understand the use case and see what’s going wrong.
Like this scene. I just wan to share depthbuffer between to passes
with webglrender is easy to get.
How did you do the setup with `EffectComposer` and `RenderPass`? Did you have two render passes and set `clearDepth` to `false` on the second render pass?
is there a function 'clearDepth’ on PassNode ?
with webglrender I create two renderTargets and share same depthbuffer
and I implement myself `EffectComposer` with pingpong renderTargets.
but with webgpu I donot know how to work with `PassNode` and `Pipeline`
How do you do this? This wasn’t possible at one point, because the buffers were created on private objects inside the renderer.
To clarify: If you setup multiple render passes with effect composer, they render into the same render target. If you set the clear property of a render pass to false, the render pass can render “on top” of the previous one and properly depth test. I realized now setting clearDepth to false isn’t sufficient since the color buffer would be cleared.
AFAICT, what you are looking for has not been implemented in the WebGPU examples so far. I think this is technically not possible yet. You can however access the depth of the previous pass and implement a custom masking that potentially has the same effect as a depth test.
Do you mind describing your use case in more detail?
Thanks for your patient reply.
Currently, I’ve moved away from the WebGPU pipeline implementation. Instead, I’m calling the renderer’s render function directly, using a ping-pong (double buffering) approach.
/* eslint-disable no-undef */
/* eslint-disable no-unused-vars */
import * as THREE from 'three/webgpu';
/**
*
* 模拟双缓冲
*
* @export
* @class RenderBuffers
*/
export default class RenderBuffers {
/**
* 缓冲
*/
#r;
#w;
#t;
/**
* 尺寸
*/
#size_w = 0;
#size_h = 0;
/**
* getter
*/
get r() {
return this.#r;
}
/**
* getter
*/
get w() {
return this.#w;
}
/**
* ćž„é€
*/
constructor() {
this.#r = new THREE.RenderTarget(1, 1);
this.#r.depthTexture = new THREE.DepthTexture();
this.#w = new THREE.RenderTarget(1, 1);
this.#w.depthTexture = new THREE.DepthTexture();
}
/**
* 交换
*/
swap() {
this.#t = this.#r;
this.#r = this.#w;
this.#w = this.#t;
}
/**
* 交换
*/
swapbuffers() {
this.swap();
}
/**
* 更新尺寸
*/
updateSizeIfNeed() {
this.#r.setSize(this.#size_w, this.#size_h);
this.#w.setSize(this.#size_w, this.#size_h);
}
/**
*
* 重置
*
* @param {*} w
* @param {*} h
*/
resize(pixel_ratio, width, height) {
this.#size_w = Math.floor(pixel_ratio * width );
this.#size_h = Math.floor(pixel_ratio * height);
}
}
First, I render the scene into RenderTarget A. Then, I run post-processing using two other RenderTargets in a ping-pong setup. Finally, I copy the post-processed result back to RenderTarget A without touching the depth buffer. This perfectly meets my requirements.
I don’t quite understand what you mean.
I didn’t know about the .depthTexture property. I don’t know if this is exactly the same as the actual depth buffer, but it probably acts the same. Thanks for sharing.