在我的libgdx项目中,我使用自定义着色器为单个灰度字符创建不同的颜色变化。我有一个班级" Shader"它包含顶点和片段着色器的静态String
变量。对于每个人,我基本上通过替换片段着色器字符串中的字符串来创建新的着色器。
出于某种原因,我的角色最终看起来很好,除了在他们的头上添加,看起来像一个头转向侧面:
角色本身没有这个"额外的头部" (我已经检查了所有图片):
甚至更奇怪的是,如果我删除改变肤色的着色器部分,问题就消失了。所有其他颜色都被替换得很好,只有皮肤似乎是问题。
我的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边框,头部就不会以奇怪的方式被绘制。如果灰度部分没有被黑色像素完全包围,那么头发也是如此,这也给我一个奇怪的外观。有人可以解释一下吗?