【问题标题】:libGDX Grayscale Shader fade effectlibGDX 灰度着色器淡入淡出效果
【发布时间】:2015-05-06 15:09:35
【问题描述】:

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

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

【问题讨论】:

  • 如果我理解你的问题是正确的,你可以引入一个浮点变量,你从你的游戏代码每帧传递给着色器。此变量的范围应为 [0 到 1] 并描述“颜色的褪色程度”。伪代码:float fadeStrength; gl_FragColor = vec4(grey * fadeStrength + (1 - fadeStrength) * c.r, gray * fadeStrength + (1 - fadeStrength) * c.g, .........);您可以找到 SO anwsers 如何相当轻松地将变量传递给着色器。
  • @Patman 这似乎是正确的方法,我必须设置所有内容,但似乎将所有内容渲染为黑色

标签: java libgdx fragment-shader


【解决方案1】:

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

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

【讨论】:

  • 这适用于我的桌面项目,但不适用于我的 android 项目...有什么原因吗?
  • 在着色器的 blendedColor 行上,尝试用 vec3(grey) 替换 gray。移动 GPU 往往对语法更加依赖。如果不是这样,请记录着色器的 getLog(),它会告诉您着色器的哪一行有问题。
猜你喜欢
  • 2019-12-15
  • 2015-02-22
  • 1970-01-01
  • 1970-01-01
  • 2011-03-05
  • 2011-10-16
  • 1970-01-01
  • 1970-01-01
  • 2011-01-01
相关资源
最近更新 更多