three.js - Three.js 后处理:如何保持多遍的深度纹理?
问题描述
我正在使用需要多个后处理通道的 three.js 渲染场景。这些步骤中的大多数都需要深度缓冲区。我的计划是首先渲染所有可见对象以获得颜色和深度,然后使用 2 个交替读取和写入帧缓冲区的帧缓冲区渲染所有后处理通道。通行证只是示例:
- 渲染对象 -> FB0
- DistortionPass,以 FB0 作为输入 -> FB1
- GodrayPass,以 FB1 作为输入 -> FB0
- SSAOPass,以 FB0 作为输入 -> 屏幕
GodrayPass 需要读取第一个渲染通道的深度,因此我需要绑定深度纹理,它不应该是绑定到 FB0 的纹理,否则会导致反馈循环,因为该着色器正在写入 FB0。
我认为在渲染对象后将深度复制到单独的纹理中是有意义的,因此我可以在需要时绑定此纹理,而无需担心反馈循环。
然而,
- copyTexImage2D 似乎不支持从深度缓冲区复制。
- 在第一次传递到 RGBA8 纹理之后使用着色器将深度缓冲区打包将需要每次传递都再次“解包”浮动
- 使用将深度输出到颜色缓冲区的着色器再次渲染所有对象?将需要再次包装或精度损失。
这里的最佳做法是什么?我在正确的道路上吗?
我可以使用 WebGL 2.0 (OpenGL ES 3.0),但想避免使用不受欢迎的扩展。
解决方案
Three.js 不称他们为 FB,而是称他们为RenderTarget
s。对于 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;
这篇文章展示了渲染目标。这篇文章展示了使用和EffectComposer
three.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
推荐阅读
- javascript - noscript 和禁用 javascript
- java - Spring Boot 应用程序不创建 .jar 文件
- flutter - 如何在网格视图中动态更改 childAspectRatio
- node.js - 如何解决问题 jquery 和 angular 等未找到?
- javascript - 数组按日期分组并重新映射对象
- c# - 如何生成 rand 继承类
- arrays - Python,如何将字母打印到语音
- entity-framework - EF Core 2.2 LINQ 查询在 EF Core 3.0 中不起作用
- spring-boot - Key.of(2, 2) 在谷歌扳手中做什么?
- search - 从另一个文件中的一个文件搜索模式并将匹配后的行写入第三个文件