有没有人知道是否可以在一个Web-GL“程序”中串行运行多个片段着色器?我正在尝试使用着色器效果复制我在WPF中编写的一些代码。在WPF程序中,我将包装一个带有多个边框的图像,每个边框都会附加一个效果(允许多个效果在同一图像上串行运行)。
答案 0 :(得分:10)
我担心你可能不得不稍微澄清一下你的问题,但无论如何我都会采取措施:
WebGL可以有效地支持您想要的许多不同着色器。 (当然有可用的内存这样的实际限制,但你必须通过创建太多的着色器来努力碰到它们。)事实上,大多数“真实世界”的WebGL / OpenGL应用程序将使用许多不同的组合着色器生成渲染到屏幕的最终场景。 (一个简单的例子:水通常会使用与其周围环境的其他环境不同的着色器或着色器组渲染。)
调度渲染命令时,一次只能有一个着色器程序处于活动状态。通过调用gl.useProgram(shaderProgram);
指定当前活动的程序,之后将使用该程序呈现绘制的任何几何体。如果要渲染需要多个不同着色器的效果,则需要按着色器对它们进行分组并分别绘制每个批处理:
gl.useProgram(shader1);
// Setup shader1 uniforms, bind the appropriate buffers, etc.
gl.drawElements(gl.TRIANGLES, shader1VertexCount, gl.UNSIGNED_SHORT, 0); // Draw geometry that uses shader1
gl.useProgram(shader2);
// Setup shader2 uniforms, bind the appropriate buffers, etc.
gl.drawElements(gl.TRIANGLES, shader2VertexCount, gl.UNSIGNED_SHORT, 0); // Draw geometry that uses shader2
// And so on...
答案 1 :(得分:4)
正如Toji建议的那样,您可能想澄清一下您的问题。如果我理解正确,您想要对图像应用一组后处理效果。
您的问题的简单答案是:不,您不能将多个片段着色器与一个顶点着色器一起使用。
但是,有两种方法可以实现此目的:首先,您可以在一个片段着色器中编写所有内容并最终将它们组合在一起。这取决于你想要的效果! 其次,您可以编写多个着色器程序(每个效果一个)并将结果写入片段缓冲区对象(渲染到纹理)。每个着色器将获得上一个效果的结果并应用下一个效果。这会有点复杂,但它是最灵活的方法。
答案 2 :(得分:4)
其他答案都在正确的轨道上。您需要动态创建着色器,将所有效果应用于一个着色器或帧缓冲区中,并一次应用一个效果。这里有一个例子
http://games.greggman.com/game/webgl-image-processing-continued/
答案 3 :(得分:1)
如果你想在一个渲染过程中运行几个着色器,就像这样(例如从稀薄的空气中拉出来):
...每个阶段附加到单个WebGLProgram
对象,每个阶段都有自己的main()
函数,然后不,GLSL不会这样工作。
GLSL的工作方式更像C / C ++,您可以使用单个全局main()
函数作为程序的入口点,并附加任意数量的库。上面的四个例子都可以是一个单独的"库,"自己编译但链接到一个程序中,并由单个main()
函数调用,但它们可能不会各自定义自己的main()
函数,因为GLSL中的这些定义在整个程序中共享
这很遗憾地要求您为要使用的每个着色器编写单独的main()
函数(至少),这会导致冗余编程的批次,即使您打算重用库本身。这就是为什么我最终写了一个美化的字符串管理器来管理Jax的GLSL库;我不确定代码在我的框架之外是多么有用,但您可以自由地查看它,并使用您觉得有用的任何东西。相关文件是: