【发布时间】:2014-10-19 16:14:42
【问题描述】:
我有一个非常复杂的 HLSL 着色器,它使用 Direct3D9 中的着色器模型 3 进行大量纹理读取。复杂代码仅用于某些像素,因此我在该代码块周围放置了一个 if 语句。令我惊讶的是,这根本没有带来任何性能提升。如果我改用 clip(-1),我确实看到了巨大的性能提升,所以这个着色器确实是我程序的瓶颈。为什么在没有 clip(-1) 行的情况下分支不能提高我的性能?
我找到了这个话题:How much performance do conditionals and unused samplers/textures add to SM2/3 pixel shaders? 这个话题表明在着色器模型 3 中可以使用分支进行优化,但性能是每批像素中最差的。在某些情况下,慢速分支主要位于屏幕边缘,而快速分支主要位于屏幕中心。我认为这意味着批量像素通常会采用相同的分支,因此我希望通过这种方式获得性能提升。
在伪代码中,像素着色器如下所示:
float4 colour = tex2D(texture, uv);
if (colour.a < 0.5f)
{
//I only get a performance boost if I replace this line with clip(-1);
oColour = colour;
}
else
{
complexSlowCodeWithTonsOfTextureReadsGoesHere;
oColour = result;
}
oColour *= 2;
这给了我与删除分支并始终使用慢速 else 分支中的代码时完全相同的性能。如果我用 clip(-1) 替换第五行,我会看到巨大的性能提升(以及大部分黑屏),因此 if 语句实际上正在运行。
我在这里做错了什么还是不可能在着色器模型 3 中优化这样的着色器?
【问题讨论】:
-
您的着色器是否只是在全屏过程中运行一次?或者它是用来绘制几个对象的。在第一种情况下,使用 stencil 可以为您带来相当不错的性能提升。
-
是全屏后期效果。为此使用模板缓冲区将非常复杂,但可能。 Gnietschow 在下面的回复已经很好地回答了我的问题。 :) (我只是发现我可以点击 V 符号表示我的问题已得到回答......)