我正在尝试消化这两个链接:
https://www.khronos.org/opengl/wiki/Rendering_Pipeline_Overview https://www.khronos.org/opengl/wiki/Vertex_Shader
管道概述说顶点着色器在基元组件之前运行。
第二个提到这个:
顶点着色器(通常)与其输入不变。也就是说,在单个Drawing命令中,两个获得完全相同输入属性的顶点着色器调用将返回二进制相同结果。因此,如果OpenGL可以检测到顶点着色器调用被赋予与先前调用相同的输入,则允许重用前一次调用的结果,而不是浪费宝贵的时间来执行它已经知道答案的内容。
OpenGL实现通常不会通过实际比较输入值(这需要太长时间)来做到这一点。相反,此优化通常仅在使用索引渲染功能时发生。 如果多次指定特定索引(在同一个Instanced Rendering中),则保证此顶点产生完全相同的输入数据。
因此,实现在顶点着色器的结果上使用缓存。 如果索引/实例对再次出现,结果仍然在缓存中,则不会再次执行顶点着色器。 因此,顶点着色器调用的次数可能少于指定的顶点。
所以,如果我有两个四边形,每个都有两个三角形:
索引:
verts: { 0 1 2 3 }
tris: { 0 1 2 }
{ 1 2 3 }
汤:
verts: { 0 1 2 3 4 5 }
tris: { 0 1 2 }
{ 3 4 5 }
也许是一个看起来像这样的顶点着色器:
uniform mat4 mvm;
uniform mat4 pm;
attribute vec3 position;
void main (){
vec4 res;
for ( int i = 0; i < 256; i++ ){
res = pm * mvm * vec4(position,1.);
}
gl_Position = res;
我是否应该关心一个有4个顶点而另一个有6个?从gpu到gpu是否真的如此,是否会调用顶点着色器4次对6?这是如何受缓存影响的:
如果索引/实例对再次出现,且结果仍在缓存中 ...
这里的原始数字与表现有什么关系?在这两种情况下,我都有相同数量的原语。
对于一个非常简单的片段着色器,但是一个昂贵的顶点着色器:
void main(){
gl_FragColor = vec4(1.);
}
一个曲面细分的四(100x100段)可以说索引版 运行得更快,或可以运行得更快,或者说没有?
答案 0 :(得分:1)
根据规范,像GPU中的所有内容一样,你什么都不说。它取决于驱动程序和GPU。实际上,虽然在你的例子中,4个顶点的运行速度会比6个地方快得多吗?
搜索顶点顺序优化并出现大量文章
Linear-Speed Vertex Cache Optimisation
AMD Triangle Order Optimization Tool
Triangle Order Optimization for Graphics Hardware Computation Culling
无关,但规范与现实的另一个例子是根据规范深度测试在片段着色器运行之后发生(否则你不能在片段着色器中设置gl_FragDepth
。实际上虽然由于结果相同,驱动程序/ GPU可以做任何事情,因此片段着色器不会设置gl_FragDepth
或discard
某些片段首先进行深度测试,并且只有在测试通过时才会运行。