3

在我的片段着色器中有两行如下:</p>

float depthExp=max(0.5,pow(depth,100.0));
gl_FragColor=vec4(depthExp*vec3(color),1);

我把它“优化”成:</p>

if(depth<0.99309249543703590153321021688807){//0.5^(1/100.0)
    gl_FragColor=vec4(0.5*vec3(color),1);
}else{
    float depthExp=pow(depth,100.0);
    gl_FragColor=vec4(depthExp*vec3(color),1);
}

我可以通过这个来提高性能吗?还是我只是违背自己的意愿做事?


我在这里给出完整的片段着色器,看看是否有机会优化它:

varying vec2 TexCoord;
uniform sampler2D Texture_color;
uniform sampler2D Texture_depth;
uniform sampler2D Texture_stencil;
void main() 
{ 
     float depth=texture2D(Texture_depth,TexCoord).r;
     float stencil=texture2D(Texture_stencil,TexCoord).r;
     vec4 color=texture2D(Texture_color,TexCoord); 
     if(stencil==0.0){
           gl_FragColor=color;
     }else{
           float depthExp=max(0.5,pow(depth,100.0));
           gl_FragColor=vec4(depthExp*vec3(color),1);       
     }
} 
4

2 回答 2

2

首先,着色器中的过度分支通常不是一个好主意。在现代硬件上,只要附近的片段都采用相同的分支,它就不会太糟糕。但是,一旦本地片段包的两个片段(其大小取决于实现,可能是一个小方块,例如 4x4-8x8)采用不同的分支,GPU 实际上将不得不为数据包的每个片段执行两个分支。

因此,如果附近的片段可能采用相同的分支,它可能会带来一些改进。由于条件是基于深度的(尽管我猜是来自之前的渲染),并且深度缓冲区通常由具有单调深度分布的较大区域组成,因此附近的片段确实很可能进入同一个分支。并且由于对大多数片段执行优化分支(因为大多数片段将小于 0.993,由于深度缓冲区的非线性特性和较小值的更高精度,更是如此)它可能是有利可图的。但就像Apeforce建议的那样,最好的办法是衡量它。

但这给我带来了另一个问题。鉴于通常场景中的几乎所有片段的深度都小于 0.993,除了背景,大多数值在用 100 (0.95^100 = 0.005人和0.9^100 = 0,00002无论如何,对感知的认识并不是那么高)这个数量很可能只是将其归零。因此,如果您确实有一个标准深度缓冲区,其值来自 [0,1] (甚至可能像往常一样非线性),那么我怀疑它的实际目的是什么pow,如果您的问题可能有不同的解决方案.

于 2012-10-01T09:53:22.450 回答
1

通常,您会不惜一切代价避免在着色器内部分支,您最好从一开始就保留它。我听说现代 GPU 在这方面做得更好(分支语句),你在写什么,OpenGL ES 2.0 或 OpenGL 3.2+?您使用的变化表明您正在为 OpenGL ES 编写代码?

我建议您将 fps 写到控制台(这会影响性能,但因为这两种情况都没有问题)或屏幕,首先使用原始着色器,然后是“优化”着色器,然后看看哪个帧数更高。

不过一般来说,你不能使用分支条件来优化着色器程序,这感觉真的是倒退,但这是因为硬件的行为方式。

于 2012-10-01T08:46:03.243 回答