我是OpenGL的初学者,并且一直在对着色器和属性进行一些研究。我去过的大多数地方都说过,显式属性绑定(无论是使用layout(location=x)还是使用glBindAttribLocation着色器本身)都比让OpenGL生成一些属性号更好。但是,我不完全了解为什么显式属性绑定更好。

所以我想我的问题是,显式/自动属性绑定的利弊是什么,哪个更有利于总体上更好的程序设计?

评论

从原则上讲,我认为自动具有一个优点:当将同一个顶点着色器与各种片段着色器一起使用时,某些属性可能不会促进给定像素着色器的输出,并且编译器可以检测到这一点并通知应用程序,从而可以优化顶点布局。实际上,出于某些原因,我没有利用这一点。我也很想知道自动化的弊端是什么...

这篇文章中公认的答案表明了明显的一面,也许您可​​以看看他为什么这么认为。 stackoverflow.com/questions/4635913/…

将VAO与使用相同顶点布局的多个着色器重复使用。如果让编译器决定,则即使每个VB使用完全相同的属性,您也可能需要为每个VB提供VAO。听起来不错!现在规格已经出炉了,我应该看看Vulkan的工作。

#1 楼

它基本上使您可以控制各个属性索引的语义。这在较大的项目中大有裨益,在大型项目中,您拥有许多不同的着色器,但是它们通常使用相当通用的属性,例如位置或纹理坐标。使用显式的属性位置,您可以为这些属性建立语义,并在所有着色器上实施该语义,例如位置始终在属性0中,纹理坐标始终在属性1中,...

首先,它的优点是不必查询每个着色器的属性索引。当然,您可以查询一次,然后将其排序,例如从属性名称/语义到索引的映射,但是事先建立更好的关系。而且,这给我们带来了更大的优势,如果没有显式的属性绑定,您将不仅必须将模型的顶点数组绑定到每个模型的每个属性通道,还要将每个着色器绑定到各个属性通道,因为位置数组可能会变为属性0在一个着色器中使用属性1在另一个着色器中使用。

这不仅是一个巨大的麻烦,而且基本上破坏了Vertey Array Objects(VAO)的优势,后者明确地在那里捕获了所有顶点属性状态,包括已启用的属性索引及其缓冲区源,以便您可以通过绑定VAO并调用绘制函数来绘制对象。如果没有显式的属性绑定,则至少仍然必须为您使用的每个不同的着色器重新启用/绑定各个数组。使用显式属性绑定,您知道模型的位置始终进入属性索引0。