libGDX灰度着色器淡入淡出效果

libGDX Grayscale Shader fade effect

我正在使用我在另一个堆栈溢出问题中找到的着色器以灰度方式渲染我的屏幕:

import com.badlogic.gdx.graphics.glutils.ShaderProgram;

public class GrayscaleShader {
static String vertexShader = "attribute vec4 a_position;\n" +
        "attribute vec4 a_color;\n" +
        "attribute vec2 a_texCoord0;\n" +
        "\n" +
        "uniform mat4 u_projTrans;\n" +
        "\n" +
        "varying vec4 v_color;\n" +
        "varying vec2 v_texCoords;\n" +
        "\n" +
        "void main() {\n" +
        "    v_color = a_color;\n" +
        "    v_texCoords = a_texCoord0;\n" +
        "    gl_Position = u_projTrans * a_position;\n" +
        "}";

static String fragmentShader = "#ifdef GL_ES\n" +
        "    precision mediump float;\n" +
        "#endif\n" +
        "\n" +
        "varying vec4 v_color;\n" +
        "varying vec2 v_texCoords;\n" +
        "uniform sampler2D u_texture;\n" +
        "\n" +
        "void main() {\n" +
        "  vec4 c = v_color * texture2D(u_texture, v_texCoords);\n" +
        "  float grey = (c.r + c.g + c.b) / 3.0;\n" +
        "  gl_FragColor = vec4(grey, grey, grey, c.a);\n" +
        "}";

public static ShaderProgram grayscaleShader = new ShaderProgram(vertexShader,
        fragmentShader);
}

我希望能够从全色淡入灰度。我想我应该能够通过补间 r、g 和 b 颜色来做到这一点,然后将它们设置为 gl_FragColor(我想我需要在使用的每个 setter 方法中创建一个新的 ShaderProgram在补间过程中,每次都使用新的颜色值)。我明白为什么 (c.r + c.g + c.b)/3.0 是灰色的,但是我可以用什么来获取从颜色到这一点的值?我希望这是有道理的!

您可以在片段着色器中放置一个统一的浮点数,像这样在原始颜色和灰色之间混合:

static final String FRAG = "#ifdef GL_ES\n" +
        "    precision mediump float;\n" +
        "#endif\n" +
        "\n" +
        "varying vec4 v_color;\n" +
        "varying vec2 v_texCoords;\n" +
        "uniform sampler2D u_texture;\n" +
        "uniform float u_grayness;\n" +
        "\n" +
        "void main() {\n" +
        "  vec4 c = v_color * texture2D(u_texture, v_texCoords);\n" +
        "  float grey = (c.r + c.g + c.b) / 3.0;\n" +
        "  vec3 blendedColor = mix(c.rgb, vec3(grey), u_grayness);\n" +
        "  gl_FragColor = vec4(blendedColor.rgb, c.a);\n" +
        "}";

您可以保留一个从 0 到 1 跟踪 "grayness" 的浮点数,并像这样应用它:

batch.setShader(grayscaleShader);
batch.begin();
grayscaleShader.setUniformf("u_grayness", grayness);
//draw stuff
batch.end();
batch.setShader(null);

顺便说一句,使用适当的亮度标度来计算灰度可能会得到更好的结果,而不是简单地求和并除以 3。这是因为红色、绿色和蓝色具有不同的相对亮度,如眼睛。示例:

float grey = dot( c.rgb, vec3(0.22, 0.707, 0.071) );