【问题标题】:Texture grayscale in libgdxlibgdx 中的纹理灰度
【发布时间】:2013-07-07 20:40:40
【问题描述】:

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

【问题讨论】:

    标签: android textures libgdx grayscale


    【解决方案1】:

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

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

    【讨论】:

    • 你真的应该把着色器放在一个单独的文件中并加载它们(并使用一些简洁的着色器工具),如果你想要一个可维护性和可读性的噩梦,请选择这个选项。
    • @iLoveUnicorns 同意。但这不是想要快速解决方案来玩和测试的人的复制/粘贴选项。这并不妨碍他们这样做,这只是朝着正确方向迈出的一步。
    【解决方案2】:

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

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

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

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

    + "  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" //
    

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-10-07
        • 1970-01-01
        • 2015-12-02
        • 2021-09-05
        • 1970-01-01
        • 1970-01-01
        • 2013-12-09
        • 1970-01-01
        相关资源
        最近更新 更多