使用相同的着色器更改渲染目标的数量

时间:2018-12-07 15:50:43

标签: webgl2

我正在尝试使用多个渲染目标来保存渲染中的一些其他数据(法线等)。我已经设置了帧缓冲区,就像对这个问题WebGL 2.0: Multiple output textures from the same program的回答一样。当我使用向每个目标写入恒定颜色的虚拟着色器,并使用另一个着色器渲染结果时,一切似乎都可以正常工作。但是,随着着色器复杂性的增加,我遇到了一个问题。我有一个这样的着色器

#version 300 es
precision highp float;

layout(location = 0) out vec4 result_image;
layout(location = 1) out vec4 result_albedo;
layout(location = 2) out vec4 result_normals;

void main(){
    result_image = do_some_work(...); // I omitted related functions, textures, uniforms, ...
    result_albedo = vec4(0.0, 1.0, 0.0, 1.0);
    result_normals = vec4(0.0, 0.0, 1.0, 1.0);
}

此着色器需要花费一些时间进行编译(gl.getError将其阻塞一段时间后调用gl.linkProgram)。当我只写第一个纹理时使用它-在gl.bindFramebuffer之后,我打电话

gl.drawBuffers([
    gl.COLOR_ATTACHMENT0,
]);

一切正常。但是当我尝试渲染到多个纹理

gl.drawBuffers([
    gl.COLOR_ATTACHMENT0,
    gl.COLOR_ATTACHMENT1,
    gl.COLOR_ATTACHMENT2,
]);
使用该着色器的

第一次绘制使WebGL停顿了几秒钟,随后的所有绘制均正常运行。随着着色器复杂度(在这种情况下为do_some_work(...))的增加,此停顿变得更长,并且有时会使WebGL崩溃(由于命令花费的时间太长)。

(注意:当第一次使用1个绘制缓冲区进行渲染,并且切换到3后,在调用drawArrays浏览器后冻结几秒钟,然后继续正常运行时,也会发生这种情况。

使用MRT而不是没有MRT的第一帧会发生这种失速吗?帧缓冲已经绑定了所有纹理,并且所有纹理都已经通过虚拟着色器写入,因此不是初始化纹理的情况。

是否可以先与多个绘制缓冲区一起使用,使着色器重新编译?请注意,我只会向其他渲染目标输出恒定的颜色,因此这可能不会增加太多的编译时间(如果是这种情况,则linkProgram之后的编译会花费更长的时间。而且如果重新编译,Chrome的着色器缓存将无法工作不使用MRT还是这种情况?)。

0 个答案:

没有答案