5

有没有办法将 libgdx 的纹理转换为灰度图像?到目前为止,我已经复制了想要灰度化的图像并手动完成,但我认为这不是最好的解决方案,因为我的游戏使用越来越多的图像并且它使用了大量的磁盘空间。

4

3 回答 3

9

以为我会为任何想要使用复制/粘贴代码的人分享这个。

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

使用它调用

spriteBatch.setShader(GrayscaleShader.grayscaleShader)

当你完成灰度时,别忘了打电话

spriteBatch.setShader(null);
于 2014-04-07T11:45:02.037 回答
7

您应该能够编写一个以灰度渲染纹理的 GLSL 着色器。这需要 OpenGL 2.x,并且不会真正“转换”纹理,而只是将其渲染为灰度显示。

有关包含灰度着色器的着色器的详细教程,请查看: https ://github.com/mattdesl/lwjgl-basics/wiki/ShaderLesson3

(Libgdx 并没有真正定义 GLSL 着色器 API,它是从 OpenGL 传递的,因此您在网上找到的大多数常规 OpenGL 教程或代码都应该可以工作。)

对于更直接的 hack,只需使用LibgdxSpriteBatch着色器并更改片段着色器,使其平均rgb组件。(您可以定义自己的ShaderProgram并将其提供给 aSpriteBatch使用。)将片段着色器的主体更改为类似这样的内容(未经测试,因此可能无法编译):

+ "  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" //
于 2013-07-07T23:50:49.630 回答
2

您可以仅将纹理加载为亮度,或在 GLES 中加载亮度和 alpha(请参阅glTexImage2D)。在 libgdx 中,您可以在实例化Texture时指定PixFormat.Intensity(亮度)或LuminanceAlpha(亮度和 alpha)。这将生成灰度纹理。

您仍然需要加载两种纹理(一种颜色,一种灰度),但它们可以使用相同的源,并且亮度在内存中每个像素仅使用 1 个字节。更有效的解决方案是按照 PT 的建议实现着色器,但仅在 GLES 2 中可用。

于 2013-07-08T02:32:14.087 回答