首页 > 解决方案 > Three.js 后处理:如何保持多遍的深度纹理?

问题描述

我正在使用需要多个后处理通道的 three.js 渲染场景。这些步骤中的大多数都需要深度缓冲区。我的计划是首先渲染所有可见对象以获得颜色和深度,然后使用 2 个交替读取和写入帧缓冲区的帧缓冲区渲染所有后处理通道。通行证只是示例:

  1. 渲染对象 -> FB0
  2. DistortionPass,以 FB0 作为输入 -> FB1
  3. GodrayPass,以 FB1 作为输入 -> FB0
  4. SSAOPass,以 FB0 作为输入 -> 屏幕

GodrayPass 需要读取第一个渲染通道的深度,因此我需要绑定深度纹理,它不应该是绑定到 FB0 的纹理,否则会导致反馈循环,因为该着色器正在写入 FB0。

我认为在渲染对象后将深度复制到单独的纹理中是有意义的,因此我可以在需要时绑定此纹理,而无需担心反馈循环。

然而,

这里的最佳做法是什么?我在正确的道路上吗?

我可以使用 WebGL 2.0 (OpenGL ES 3.0),但想避免使用不受欢迎的扩展。

标签: three.jsshaderdepth-buffer

解决方案


Three.js 不称他们为 FB,而是称他们为RenderTargets。对于 webgl,它们是WebGLRenderTarget

https://threejs.org/docs/#api/en/renderers/WebGLRenderTarget

此示例显示使用渲染目标设置深度纹理

target = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight );
target.texture.format = THREE.RGBFormat;
target.texture.minFilter = THREE.NearestFilter;
target.texture.magFilter = THREE.NearestFilter;
target.texture.generateMipmaps = false;
target.stencilBuffer = false;
target.depthBuffer = true;
target.depthTexture = new THREE.DepthTexture();
target.depthTexture.format = THREE.DepthFormat;
target.depthTexture.type = THREE.UnsignedShortType;

这篇文章展示了渲染目标。这篇文章展示了使用和EffectComposerthree.js对象为后处理目的渲染目标Pass

所以,只需制作 3 个渲染目标

RT0 = color + depth
RT1 = color
RT2 = color

然后设置Pass对象,使得

Render Objects -> RT0(color+depth)
DistortionPass, taking RT0(color) as input -> RT1(color)
GodrayPass, taking RT1(color) + RT0(depth) as input -> RT2(color)
SSAOPass, taking RT2(color as input -> screen

推荐阅读