代码之家  ›  专栏  ›  技术社区  ›  Guig

WebGL-连续应用多个程序

  •  2
  • Guig  · 技术社区  · 10 年前

    如何让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);
    

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

    2 回复  |  直到 10 年前
        1
  •  4
  •   gman    10 年前

    @ssube所说的内容(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所说,要应用多个后期处理效果,可以使用附加纹理创建帧缓冲区。将场景渲染到第一个帧缓冲区纹理,然后使用第一个后期处理效果将该纹理渲染到第二个纹理,现在可以使用下一个后期处理效应将第二个贴图渲染回第一个纹理。最后一个后期处理效果渲染到画布。

    For an example of applying multiple effects see this

        2
  •  2
  •   ssube    10 年前

    您确实希望再次渲染,但需要获取第一个过程的输出,并将其用作第二个过程的输入纹理。

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

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

    1. 像正常一样将场景绘制到 可读的,可读的 纹理
    2. 将该纹理作为输入绑定到下一个程序。
    3. 用程序和以前的输出绘制一个矩形。

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

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