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

时间:2015-03-05 09:44:51

标签: java libgdx fragment-shader

我正在使用我在另一个堆栈溢出问题中提供的着色器来渲染我的灰度屏幕:

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是灰色的,但是我可以使用什么来获得从颜色到这一点的值?我希望这是有道理的!

1 个答案:

答案 0 :(得分:5)

您可以在片段着色器中放置一个均匀的浮点数,它将原始颜色和灰色混合在一起,如下所示:

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并按如下方式应用:

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) );