Libgdx着色器改变纹理

时间:2017-06-04 15:44:25

标签: java libgdx glsl shader

在我的libgdx项目中,我使用自定义着色器为单个灰度字符创建不同的颜色变化。我有一个班级" Shader"它包含顶点和片段着色器的静态String变量。对于每个人,我基本上通过替换片段着色器字符串中的字符串来创建新的着色器。 出于某种原因,我的角色最终看起来很好,除了在他们的头上添加,看起来像一个头转向侧面:

Weird head

角色本身没有这个"额外的头部" (我已经检查了所有图片):

Character still

甚至更奇怪的是,如果我删除改变肤色的着色器部分,问题就消失了。所有其他颜色都被替换得很好,只有皮肤似乎是问题。

我的Shader课程:

public class Shader {

public static final String vertexShader = "attribute vec4 a_position;    \n" +
        "attribute vec4 a_color;\n" +
        "attribute vec2 a_texCoord0;\n" +
        "uniform mat4 u_projTrans;\n" +
        "varying vec4 v_color;" +
        "varying vec2 v_texCoords;" +
        "void main()                  \n" +
        "{                            \n" +
        "   v_texCoords = a_texCoord0; \n" +
        "   gl_Position =  u_projTrans * a_position;  \n"      +
        "}                            \n" ;

private static final String fragmentShader = "#ifdef GL_ES\n" +
        "precision mediump float;\n" +
        "#endif\n" +
        "varying vec4 v_color;\n" +
        "varying vec2 v_texCoords;\n" +
        "uniform sampler2D u_texture;\n" +
        "void main()                                  \n" +
        "{                                            \n" +
        "vec4 color = texture2D(u_texture, v_texCoords).rgba; \n" +
        "vec4 newColor; \n" +
        "if (color.r == {{trousersold}} && color.g == {{trousersold}} && color.b == {{trousersold}}){ //trousers \n" +
        "newColor = vec4({{trousers}}, 1.0); \n" +
        "}else if (color.r == {{shirtold}} && color.g == {{shirtold}} && color.b == {{shirtold}}){ \n" +
        "newColor = vec4({{shirt}}, 1.0); \n" +
        "} \n" +
        "else if (color.r == {{skinold}} && color.g == {{skinold}} && color.b == {{skinold}}){ \n" +
        "newColor = vec4({{skin}}, 1.0); \n" +
        "} \n" +
        "else if (color.r == {{hairold}} && color.g == {{hairold}} && color.b == {{hairold}}){ \n" +
        "newColor = vec4({{hair}}, 1.0); \n" +
        "} \n" +
        "else if (color.r == {{shoeold}} && color.g == {{shoeold}} && color.b == {{shoeold}}){ \n" +
        "newColor = vec4({{shoe}}, 1.0); \n" +
        "} \n" +
        "else if (color.r == {{eyeold}} && color.g == {{eyeold}} && color.b == {{eyeold}}){ \n" +
        "newColor = vec4({{eye}}, 1.0); \n" +
        "} \n" +
        "else{ \n" +
        "newColor = color; \n" +
        "} \n" +
        "  gl_FragColor = vec4(newColor);\n" +
        "}";

public static String getFragmentShader(Color hairColor, Color skinColor, Color shirtColor, Color trousersColor,
                                Color eyeColor, Color shoeColor){
    String trousers = trousersColor.r + "," +trousersColor.g + "," + trousersColor.b;
    String hair = hairColor.r + "," + hairColor.g + "," + hairColor.b;
    String skin = skinColor.r + "," + skinColor.g + "," + skinColor.b;
    String shirt = shirtColor.r + "," + shirtColor.g + "," + shirtColor.b;
    String eye = eyeColor.r + "," + eyeColor.g + "," + eyeColor.b;
    String shoe = shoeColor.r + "," + shoeColor.g + "," + shoeColor.b;

    String fragment = fragmentShader.replace("{{hairold}}", ColorHolder.Hair);
    fragment = fragment.replace("{{trousersold}}", ColorHolder.Trousers);
    fragment = fragment.replace("{{skinold}}", ColorHolder.Skin);
    fragment = fragment.replace("{{shirtold}}", ColorHolder.Shirt);
    fragment = fragment.replace("{{eyeold}}", ColorHolder.Eyes);
    fragment = fragment.replace("{{shoeold}}", ColorHolder.Shoes);

    fragment = fragment.replace("{{hair}}", hair);
    fragment = fragment.replace("{{trousers}}", trousers);
    fragment = fragment.replace("{{skin}}", skin);
    fragment = fragment.replace("{{shirt}}", shirt);
    fragment = fragment.replace("{{eye}}", eye);
    fragment = fragment.replace("{{shoe}}", shoe);

    return fragment;
}    

我的ColorHolder类,我存储颜色值(灰度)和可能的新颜色:

public class ColorHolder {

public static String Trousers = "64.0/255.0";
public static String Shoes = "45.0/255.0";
public static String Shirt = "113.0/255.0";
public static String Skin = "210.0/255.0";
public static String Eyes = "124.0/255.0";
public static String Hair = "150.0/255.0";
public static List<String> TrouserColors = new ArrayList<String>(Arrays.asList("4649c3ff", "4687c3ff", "6e4208ff", "291004ff"));
public static List<String> ShoesColors = new ArrayList<String>(Arrays.asList("440849ff", "3e1c09ff", "d30000ff", "3e3e3eff"));
public static List<String> ShirtColors = new ArrayList<String>(Arrays.asList("839fdfff", "28caa2ff", "9eca28ff", "7428caff"));
public static List<String> SkinColors = new ArrayList<String>(Arrays.asList("e9c38cff", "dfca83ff", "eec39aff", "3b1d04ff"));
public static List<String> EyesColors = new ArrayList<String>(Arrays.asList("2c86ebff", "2ceba1ff", "611500ff", "248711ff"));
public static List<String> HairColors = new ArrayList<String>(Arrays.asList("e9df3eff", "e9a33eff", "543202ff", "ae4512ff"));

}

最后,在我实例化这个人的类中,我得到一个这样的着色器:

private void setUpShader() {
    String vertexShader = Shader.vertexShader;
    String fragmentShader = Shader.getFragmentShader(
            Color.valueOf(ColorHolder.HairColors.get(MathUtils.random(ColorHolder.HairColors.size() - 1))),
            Color.valueOf(ColorHolder.SkinColors.get(MathUtils.random(ColorHolder.SkinColors.size() - 1))),
            Color.valueOf(ColorHolder.ShirtColors.get(MathUtils.random(ColorHolder.ShirtColors.size() - 1))),
            Color.valueOf(ColorHolder.TrouserColors.get(MathUtils.random(ColorHolder.TrouserColors.size() - 1))),
            Color.valueOf(ColorHolder.EyesColors.get(MathUtils.random(ColorHolder.EyesColors.size() - 1))),
            Color.valueOf(ColorHolder.ShoesColors.get(MathUtils.random(ColorHolder.ShoesColors.size() - 1))));
    this.shader = new ShaderProgram(vertexShader, fragmentShader);
}

修改 我发现,如果我改变了人的纹理,使整个头部有一个黑色的1px边框,头部就不会以奇怪的方式被绘制。如果灰度部分没有被黑色像素完全包围,那么头发也是如此,这也给我一个奇怪的外观。有人可以解释一下吗?

0 个答案:

没有答案