【问题标题】:Is this shader conditional bad for performance and can it be optimized?这个着色器有条件对性能不利吗?可以优化吗?
【发布时间】:2019-03-07 08:52:43
【问题描述】:

我有以下用 GLSL 和 HLSL 编写的片段着色器(这里用 HLSL 编写,但实现几乎相同):

sampler2D input : register(s0);
float3 lowerBounds : register(c0);
float3 higherBounds : register(c1);

float4 main(float2 uv : TEXCOORD) : COLOR
{
    float4 color = tex2D(input, uv);

    float y = clamp(0.299 * color.r + 0.587 * color.g + 0.1140 * color.b, 0.0, 1.0);
    float u = clamp(-0.169 * color.r - 0.331 * color.g + 0.5000 * color.b, 0.0, 1.0);
    float v = clamp(0.500 * color.r - 0.419 * color.g - 0.0813 * color.b, 0.0, 1.0);

    if (((y >= lowerBounds.x && y <= higherBounds.x) && (u >= lowerBounds.y && u <= higherBounds.y)) && (v >= lowerBounds.z && v <= higherBounds.z))
    {
        color = 0;
    }

    return color;
}

如您所见,着色器只是检查一个颜色是否在两个 YUV 颜色范围内,如果是,则过滤掉片段。

我知道条件语句可能对性能非常不利,所以我想知道上面是否是“坏”条件的示例和/或可以优化为不使用 if 语句。

编辑:最终优化后的代码如下所示:

sampler2D input : register(s0);
float3 lowerBounds : register(c0);
float3 higherBounds : register(c1);

float4 main(float2 uv : TEXCOORD) : COLOR
{
    float4 color = tex2D(input, uv);

    float y = clamp(0.299 * color.r + 0.587 * color.g + 0.1140 * color.b + 0.0627, 0.0, 1.0);
    float u = clamp(-0.169 * color.r - 0.331 * color.g + 0.5000 * color.b, -0.5, 0.5);
    float v = clamp(0.500 * color.r - 0.419 * color.g - 0.0813 * color.b, -0.5, 0.5);

    float3 yuv = { y, u, v };

    // Calculate and apply mask from background range
    float3 mask = step(lowerBounds, yuv) * step(yuv, higherBounds);
    color *= 1.0 - (mask.x * mask.y * mask.z);

    return color;
}

【问题讨论】:

  • 如果语句不是自动出错...着色器是分批执行的,所以如果只有一个像素符合条件,则每隔一个像素就需要等待。但是,等待一个简单的分配指令(例如“color = 0”)通常比进行复杂的乘法或步进函数调用要好...

标签: opengl optimization glsl directx hlsl


【解决方案1】:

我认为这段代码应该可以解决问题:

vec3 yuv = vec3(y, u, v);
color = step(lowerBounds, yuv ) * step(yuv, upperBounds) * color;

如果 yuv = lowerBounds 相同

如果upperBounds是

【讨论】:

  • 感谢您的回答!这不太正确(阶跃函数需要将所有结果相乘以应用所有通道或不应用),但我自己修复了它并用正确的代码编辑了我的问题:)
  • 是的,情况正好相反,通常当你有很多分支时它很糟糕,你的没有,但现在你有一个矢量化的 impl。进一步查看检查theorangeduck.com/page/avoiding-shader-conditionals
  • 你检查过它是否真的更快?
  • @kaiser 你会如何检查它?某处有没有好的着色器 sn-p 测试工具?或者只是尝试看看它是否会产生明显的 fps 差异?
  • @Kjell Visual Studio 带有一些不错的 GPU 调试和分析工具。但您也可以简单地检查 fps,包括大量三角形。请记住,fps 表示每秒帧数,因此它不是线性的。以毫秒为单位更好地计算帧的执行时间。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-24
相关资源
最近更新 更多