我正在探索相对较新的功能GL_ARB_separate_program_object。我理解的是我必须创建一个管道对象,该对象应包含来自阶段的着色器,这些阶段通过 glUseProgramStages
这让我想到了使用多个着色器的两种可能性:
1.使用变体Vertex / Fragment着色器创建多个管道(从现在开始不使用其他着色器类型),从一次映射到每个管道。
2.创建单个管道并在运行时使用
将映射切换到不同的着色器glUseProgramStages
我最关心的是表现。哪种选择更具表现力?
答案 0 :(得分:2)
您的问题无法真正得到解答,因为它会因驱动程序实施而异。但是,功能的事实和历史应该是提供信息的。
EXT_separate_shader_objects是此功能的第一个版本。它们之间最大的区别在于:您无法在EXT版本中使用用户定义的更改。您必须使用旧的兼容性输入/输出,如gl_TexCoord
。
Issue #2 in the EXT_separate_shader_objects specification 试图证明这种不可理解的疏忽解释了其原因如下:
从性能角度来看,尝试为任意单独的着色器支持“按名称进行会合”是不可取的,因为单独的着色器不会自然编译以匹配其相同名称的不同输入和输出,而无需特殊的链接步骤。这种特殊链接会为绑定单独的着色器引入额外的验证开销。链接本身必须延迟到glBegin时间,因为当从一组一致着色器转换到另一组着色器时,单独的着色器将不匹配。当输入和输出变化的名称匹配但其类型不匹配时,此特殊链接仍会产生错误或未定义的行为。
这表明不依赖名称匹配的原因,除了无能,与性能有关(如果你不能说,我不认为EXT_SSO非常高)。 “按名称会合”的表现来自于必须在每次抽奖时都这样做,而不是能够做一次。
ARB_separate_shader_objects封装了对象中的程序集合。因此,对象可以存储所有“会合”数据。第一次绘制调用可能会较慢,但只要您不向其附加新程序,相同PPO的后续使用将会很快。
因此,我会将此视为PPO应该在其上设置程序然后单独留下的证据。通常,应尽可能避免修改附件对象。这就是为什么鼓励你不要在FBO中添加或删除纹理/渲染缓冲区。