我写了一对着色器,将纹理显示为灰度而不是全彩色。我将这些着色器与libGDX内置的SpriteBatch类一起使用,并且它有效。然后,当我尝试将它与内置的SpriteCache类一起使用时,它不起作用。我查看了SpriteCache代码,看到它设置了一些我试图考虑的不同制服,但我似乎已经出错了。
libGDX中的SpriteCache类设置以下制服:
customShader.setUniformMatrix("u_proj", projectionMatrix);
customShader.setUniformMatrix("u_trans", transformMatrix);
customShader.setUniformMatrix("u_projTrans", combinedMatrix);
customShader.setUniformi("u_texture", 0);
这是我的顶点着色器:
attribute vec4 a_position;
attribute vec4 a_color;
attribute vec2 a_texCoord0;
uniform mat4 u_proj;
uniform mat4 u_projTrans;
uniform mat4 u_trans;
varying vec4 v_color;
varying vec2 v_texCoords;
void main() {
v_color = a_color;
v_texCoords = a_texCoord0;
gl_Position = a_position* u_proj * u_trans;
}
这是片段着色器:
varying vec4 v_color;
varying vec2 v_texCoords;
uniform sampler2D u_texture;
uniform u_projTrans;
void main() {
vec4 color = texture2D(u_texture, v_texCoords).rgba;
float gray = (color.r + color.g + color.b) / 3.0;
vec3 grayscale = vec3(gray + 0* u_projTrans[0][0]);
gl_FragColor = vec4(grayscale, color.a);
}
我得到的错误是:
Exception in thread "LWJGL Application" java.lang.IllegalArgumentException: no uniform with name 'u_proj' in shader
...
com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:206)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:114)ackends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:206)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:114)
我想你们中的任何人都知道为什么这不起作用?有一个名为u_proj的制服。 谢谢大家!
答案 0 :(得分:7)
确保检查着色器编译/链接是否成功。您的片段着色器将无法编译:
uniform u_projTrans;
此变量声明需要一个类型。它应该是:
uniform mat4 u_projTrans;
您可以在设置着色器程序时使用以下调用来测试错误:
glGetShaderiv(shaderId, GL_COMPILE_STATUS, ...);
glGetShaderInfoLog(shaderId, ...);
glGetProgramiv(programId, GL_LINK_STATUS, ...);
glGetProgramInfoLog(programId, ...);
答案 1 :(得分:7)
Reto Koradi所说的是真的我忘了在u_projTrans之前放一个mat4标签,这对我很有帮助。
那么Tenfour04所说的也是一个巨大的帮助!我不知道:
if (!shader.isCompiled()) throw new GdxRuntimeException("Couldn't compile shader: " + shader.getLog());
从长远来看,最有帮助的是发现glsl在编译时会取消未使用的导入,如果你不能欺骗编译器认为未使用的导入被用于使用着色器将编译然后在运行时崩溃。
在libgdx中有一个静态的"迂腐"您可以设置的变量。如果设置为false,如果变量被发送到着色器未使用的着色器,则应用程序不会崩溃,它们将被忽略。我的libgdx程序中的代码看起来像这样:
ShaderProgram.pedantic = false;
感谢您的帮助!我希望这可以帮助将来的某个人