LibGDX 着色器停用重要的 SpriteBatch 方法

LibGDX Shader inactivates important SpriteBatch methods

我正在开发一款游戏并添加了一个着色器,它将所有内容淡化为灰度,然后变为黑色。着色器本身工作正常,但是当我启动它时,Spritebatch 和 Sprites 的一些功能停止工作。忽略颜色变化,任何事物的 Alpha 始终为 1。这些方法通常负责图形变化,在使用默认着色器时效果非常好:

sprite.setColor(Color.RED);
sprite.setAlpha((float)lifeTime/100f);
sprite.draw(pBatch);

此代码将弹出窗口着色为红色,更改 alpha,然后绘制它。当着色器打开时,它只是绘制它,就像前两行不存在一样。

这是着色器的代码:

顶点:

attribute vec4 a_position;
attribute vec4 a_color;
attribute vec2 a_texCoord0;

uniform mat4 u_projTrans;

varying vec4 v_color;
varying vec2 v_texCoords;

void main() {
    v_color = a_color;
    v_texCoords = a_texCoord0;
    gl_Position = u_projTrans * a_position;
}

片段:

#ifdef GL_ES
    precision mediump float;
#endif

varying vec2 v_texCoords;
uniform sampler2D u_texture;
uniform mat4 u_projTrans;

uniform float u_fade;

void main() {
        float gray_fade = u_fade;
        float dark_fade = 1;
        if(u_fade >= 1){
            gray_fade = 1;
            dark_fade = 2-u_fade;
        }

        vec4 color = texture2D(u_texture, v_texCoords).rgba;
        float gRed   = color.r - (color.r - (0.299*color.r +  0.587*color.g + 0.114*color.b))* gray_fade;
        float gGreen = color.g - (color.g - (0.299*color.r +  0.587*color.g + 0.114*color.b))* gray_fade;
        float gBlue  = color.b - (color.b - (0.299*color.r +  0.587*color.g + 0.114*color.b))* gray_fade;
        vec3 grayscale = vec3(gRed * dark_fade, gGreen * dark_fade, gBlue * dark_fade);


        gl_FragColor = vec4(grayscale, color.a);

}

您的着色器忽略了精灵的顶点颜色。

将声明 varying vec4 v_color; 放入片段着色器并将最后一行更改为:

gl_FragColor = vec4(grayscale*v_color.rgb, color.a*v_color.a);

编辑:

我想到上面的设置会破坏灰度设置,如果场景中的某些精灵是彩色的,处理起来会很痛苦。因此,请保留 gl_FragColor 行,并将乘法移动到您对纹理颜色进行采样的位置:

vec4 color = texture2D(u_texture, v_texCoords) * v_color;

你的shader也有很大的效率低下,同一个点积计算了3次!另外,我认为在某些情况下,一次对整个向量进行计算可能比单独手动计算更快。

所以我要把中间那五行改成:

vec4 color = texture2D(u_texture, v_texCoords);
float grayValue = dot(color.rgb, vec3(0.299, 0.587, 0.1144));
vec3 grayscale = (color.rgb - (color.rgb - grayValue) * gray_fade) * dark_fade;

关于着色器中的 if 语句:一般而言,分支语句在片段着色器中具有非常重要的影响,应避免使用。但在这种情况下,分支是制服上的 if 语句,所以我不确定它是否会产生任何重大影响,因为它会在整个绘制调用中评估相同的内容。也许其他人可以插话。如果这确实导致了很大的性能问题,您可以通过将 u_fade 替换为 u_gray_fadeu_dark_fade 并将此计算移出着色器来解决它。