2012-07-08 57 views
4

有谁知道是否有可能在单个Web-GL“程序”中连续运行多片段着色器?我正在尝试使用着色器效果来复制我在WPF中编写的代码。在WPF程序中,我会用多个边框包装图像,每个边框都会附加一个效果(允许多个效果在同一图像上连续运行)。Web-GL:每个程序的多片段着色器

回答

9

我怕你可能将不得不澄清你的问题了一点,但我会在回答反正花刺:

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... 
+0

阶段之间如何进行同步?对于上面的代码片段,它看起来好像有一个假设,即阶段X完成的方式比要创建的阶段X + 1的Javascript代码更快。 – jldupont 2016-11-27 20:20:09

3

由于东治建议,你可能想澄清你的问题。如果我正确地理解了你,你想要对图像应用一系列后期处理效果。

您的问题的简单答案是:不,您不能在一个顶点着色器中使用多个片段着色器。

但是,有两种方法可以实现这一点:首先,您可以将所有内容写入一个片段着色器,并最终将它们组合在一起。这取决于你想要的效果!其次,您可以编写多个着色器程序(每个效果一个),并将结果写入片段缓冲区对象(渲染为纹理)。每个着色器都会得到上一个效果的结果并应用下一个效果。这会更复杂一些,但它是最灵活的方法。

3

其他答案在正确的轨道上。您可能需要在一个着色器或帧缓冲区中动态创建着色器,并一次应用一个效果。这里有后来的一个例子

http://games.greggman.com/game/webgl-image-processing-continued/

+0

我一直在关注过去一周的教程。他们非常有帮助,并感谢你这样做。 – hyde 2014-06-06 18:48:50

1

如果你的意思是在一个运行多个着色渲染通道,像这样(例如,从稀薄的空气拉):

  1. 顶点颜色
  2. 纹理
  3. 照明
  4. 阴影

...每个舞台都附有一个WebGLProgram对象,每个舞台都有自己的main()函数,那么不行,GLSL不会这样工作。

GLSL更像C/C++,其中有一个全局的main()函数可用作程序的入口点,并且可以附加任意数量的库。上面的四个例子可以是一个独立的“库”,它自己编译,但是链接在一起成为一个程序,并且由一个函数调用,但是它们可能没有定义它们自己的main()函数,因为GLSL中的这些定义是在整个计划中共享。

这不幸的是需要你写(至少)单独main()功能每次你打算使用着色器,这会导致冗余编程的很多,即使你打算重用库本身。这就是为什么我最终写了一个荣耀的字符串管理器来管理我的GLSL库Jax;我不确定代码在框架之外会有多大用处,但是您肯定可以自由地查看它,并利用您认为有用的任何内容。相关文件是:

祝你好运!