我正在研究相对较新的特性GL_ARB_separate_program_object。我所理解的是,我必须创建一个管道对象,它应该包含从阶段映射到那里的着色器glUseProgramStages
这让我想到了使用多个着色器的两种可能性:
1。用不同的顶点/片段着色器对创建多个管道(现在不使用其他着色器类型),从一次映射到每个管道。
2。创建单个管道,并在运行时使用
将映射切换到不同的着色器glUseProgramStages
我最关心的是性能。哪个选项性能更好?
您的问题无法真正回答,因为它会因驱动程序实现等而异。然而,功能的事实和历史应该是有用的。
EXT_separate_shader_objects是这个功能的第一个化身。它们之间最大的区别是:您不能在EXT版本中使用用户定义的变量。您必须使用旧的兼容性输入/输出,如gl_TexCoord
。
EXT_separate_shader_objects规范中的问题#2 试图证明这种难以理解的疏忽是正确的解释了其原因如下:
从性能的角度来看,尝试为任意单独的着色器支持"按名称会合"是不可取的,因为如果没有特殊的链接步骤,单独的着色器将不会自然地编译以匹配相同名称的不同输入和输出。这样一个特殊的链接将引入额外的验证开销来绑定单独的着色器。链接本身将不得不推迟到glBegin时间,因为当从一组一致的着色器过渡到另一组时,单独的着色器将不匹配。当输入和输出变量的名称匹配,但它们的类型不匹配时,这个特殊的链接仍然会产生错误或未定义的行为。
这表明不依赖名称匹配的原因,除了无能之外,还与性能有关(如果您看不出来,我对EXT_SSO评价不高)。"按名会合"的性能来自于每次召唤都必须这样做,而不是一次就能做到。
ARB_separate_shader_objects将程序集合封装在一个对象中。因此,对象可以存储所有的"会合"数据。第一次draw调用可能会比较慢,但是以后使用同一个PPO会很快,只要你不给它附加新的程序。
所以我会把这个作为证据,证明PPOs应该有程序设置,然后不管。一般来说,应该尽可能避免修改附件对象。这就是为什么我们不鼓励你从fbo中添加或删除纹理/渲染缓冲区。