在libgdx中纹理灰度

Ser*_*iel 4 android textures grayscale libgdx

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

P.T*_*.T. 7

您应该能够编写一个GLSL着色器,以灰度渲染纹理.这需要OpenGL 2.x,并不真正"转换"纹理,而只是将其呈现为灰度.

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

(Libgdx并没有真正定义GLSL着色器API,它是从OpenGL传递的,所以你在网上找到的常规OpenGL的大多数教程或代码都应该有效.)

对于更直接的黑客攻击,只需使用Libgdx SpriteBatch着色器并更改片段着色器,以便对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" //
Run Code Online (Sandbox Code Playgroud)


Wil*_*ood 6

Thought I'd share this for anyone wanting to use some copy/paste code.

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);
}
Run Code Online (Sandbox Code Playgroud)

To use it call

spriteBatch.setShader(GrayscaleShader.grayscaleShader)
Run Code Online (Sandbox Code Playgroud)

And when you're done with grayscale don't forget to call

spriteBatch.setShader(null);
Run Code Online (Sandbox Code Playgroud)

  • @iLoveUnicorns 同意。但这对于想要快速解决方案来使用和测试的人来说不是复制/粘贴选项。这并不能阻止他们这样做,这只是朝着正确方向迈出的一步。 (2认同)