WebGL-依次应用多个程序

WebGL - apply several programs successively

本文关键字:程序 应用 WebGL-      更新时间:2023-09-26

如何让WebGl连续应用几个程序,如

  • 画点什么
  • 将其转换为黑白

在这个例子中,将所有这些放在一个着色器中很容易,但我希望能够将它们分开,以便于更大的着色器的可重用性。

到目前为止,我有一个类似的东西

gl = canvas.getContext("webgl");
gl.viewport(0, 0, canvas.width, canvas.height);
fragmentShader = attachShader(fragmentShaderCode, gl, gl.FRAGMENT_SHADER);
vertexShader = attachShader(vertexShaderCode, gl, gl.VERTEX_SHADER);
program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
gl.useProgram(program);
// attach textures and variables
gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);

我不知道如何有效地添加从第一次传递中获取输入的第二次传递。我的最佳猜测是使用第二个画布,将第一个画布作为纹理输入。但这听起来像是两次渲染,这并不可怕。

@sube除了在WebGL术语中说什么。。。

在初始时间

  1. 创建帧缓冲区(gl.createFramebuffer)
  2. 将纹理附加到它(gl.framebufferTexture2D)
  3. 如果场景需要深度缓冲区,还需要将深度缓冲区附加到帧缓冲区(gl.renderbufferStorage,gl.framebufferRenderbuffer)

在渲染时

  1. 通过帧缓冲区将场景渲染到纹理中。

    // make rendering render to framebuffer's attachments
    gl.bindFramebuffer(gl.FRAMEBUFFER, yourFramebuffer);
    // .. render scene ..
    
  2. 然后使用后处理着色器将帧缓冲区的纹理渲染到画布

    // make rendering render to canvas
    gl.bindFramebuffer(gl.FRAMEBUFFER, null);
    // .. render framebuffer's texture to canvas with post processing shader..
    

正如@ssube所说,要应用多个后期处理效果,可以创建带有附加纹理的帧缓冲区。将场景渲染到第一个帧缓冲区纹理,然后使用第一个后处理效果将该纹理渲染到第二个纹理,现在可以使用下一个后处理效应将第二个贴图渲染回第一个纹理。最后一个后处理效果渲染到画布上。

有关应用多重效果的示例,请参阅此

您确实想再次渲染,但需要获得第一次的输出,并将其用作第二次的输入纹理。

交换纹理和绘制矩形(两个三分之一)是便宜的,尤其是在现代可编程硬件上。

对于简单的效果(使用可见图像作为输入,而不是几何图形或深度),您可以:

  1. 像正常情况一样绘制场景,使其具有可读的纹理
  2. 将该纹理绑定为下一个程序的输入
  3. 用你的程序和以前的输出画一个矩形

您可以重复#2和#3来运行多个效果。这最多需要两个纹理(一个用作输入,一个用作输出,然后交换)。这将适用于模糊、黑白、绽放等简单效果。

更复杂的效果可能需要额外的输入纹理(包括深度),并且可能使用额外的数据。