【问题标题】:Optimizing pixel-swapping shader优化像素交换着色器
【发布时间】:2022-01-27 12:23:51
【问题描述】:

我正在使用在纹理上交换颜色/调色板的着色器。着色器检查像素的透明度,如果不透明则设置像素。除了潜在分支之外,是否有一种有效的方法来忽略 0 alpha 像素?在这种情况下,我设置pixel = newPixel:

uniform bool alternate;
uniform sampler2D texture;

void main()
{
    vec4 pixel = texture2D(bitmap, openfl_TextureCoordv);

    if(alternate)
    {
        vec4 newPixel = texture2D(texture, vec2(pixel.r, pixel.b));

        if(newPixel.a != 0.0)
            pixel = newPixel;
    }

    gl_FragColor = pixel;

}

【问题讨论】:

    标签: opengl glsl fragment-shader


    【解决方案1】:

    您可以使用mixstep

    void main()
    {
        vec4 pixel = texture2D(bitmap, openfl_TextureCoordv);
        vec4 newPixel = texture2D(texture, vec2(pixel.r, pixel.b));
        gl_FragColor = mix(pixel, newPixel, 
                           float(alternate) * (1.0 - step(newPixel.a, 0.0)));
    }
    

    您可能希望根据 Alpha 通道进行平滑过渡。这种情况下你只需要mix:

    gl_FragColor = mix(pixel, newPixel, float(alternate) * newPixel.a);
    

    【讨论】:

    • 我正在使用着色器为只有纯色或完全透明的像素艺术 PNG 源图形重新着色。第一个 gl_FragColor 也不会绘制旧颜色(仅绘制更改的像素),但您列出的第二个示例到目前为止似乎正在工作!
    • @dinorider 试试step(0.01, newPixel.a)(1.0 - step(newPixel.a, 0.0))。 (step 仅在 x 时返回 0.0)
    • @dinorider 这里没有什么可以优化的。你必须衡量性能。结果可能因硬件和驱动程序而异。在这种情况下,我将只取最短的代码并将优化留给编译器和驱动程序。
    • 我会研究测试,但感谢您的代码和帮助!
    • 作为后续,当使用大量图形进行压力测试时,原始“分支”代码和新的缩短代码对各种目标的执行几乎相同。幕后一定有一些优化。
    【解决方案2】:

    我会研究step 函数。您可以将 if 语句表示为两个条件的乘积。

    例如:

    if (a >= 0) {
      b = c;
    }
    

    相当于

    b = (step(a, 0)*c) + (1.0 - step(a, 0)*b);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-06
      • 2017-07-03
      • 2017-05-20
      • 2019-03-04
      • 2019-02-17
      • 2013-09-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多