在着色器中没有名称为"u_proj"的制服

Jul*_*nan 4 opengl shader opengl-es glsl libgdx

我写了一对着色器,将纹理显示为灰度而不是全彩.我将这些着色器与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);
Run Code Online (Sandbox Code Playgroud)

这是我的顶点着色器:

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

这是片段着色器:

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

我得到的错误是:

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

我想你们中的任何人都知道为什么这不起作用?有一个名为u_proj的制服.谢谢你们!

Jul*_*nan 8

Reto Koradi所说的是真的,我忘了在u_projTrans之前放一个mat4标签,这对我很有帮助.

那么Tenfour04所说的也是一个巨大的帮助!我不知道:

if (!shader.isCompiled()) throw new GdxRuntimeException("Couldn't compile shader: " + shader.getLog());
Run Code Online (Sandbox Code Playgroud)

从长远来看,最有帮助的是发现glsl在编译时会取消未使用的导入,如果你不能欺骗编译器认为使用了未使用的导入,那么着色器会编译然后崩溃在运行时.

在libgdx中,您可以设置一个静态的"迂腐"变量.如果设置为false,如果将变量发送到着色器未使用的着色器,应用程序将不会崩溃,它们将被忽略.我的libgdx程序中的代码看起来像这样:

ShaderProgram.pedantic = false;
Run Code Online (Sandbox Code Playgroud)

谢谢你的帮助!我希望这可以帮助将来的某个人


Ret*_*adi 7

确保检查着色器编译/链接是否成功.您的片段着色器将无法编译:

uniform u_projTrans;
Run Code Online (Sandbox Code Playgroud)

此变量声明需要一个类型.它应该是:

uniform mat4 u_projTrans;
Run Code Online (Sandbox Code Playgroud)

在设置着色器程序时,您可以使用以下调用来测试错误:

glGetShaderiv(shaderId, GL_COMPILE_STATUS, ...);
glGetShaderInfoLog(shaderId, ...);
glGetProgramiv(programId, GL_LINK_STATUS, ...);
glGetProgramInfoLog(programId, ...);
Run Code Online (Sandbox Code Playgroud)

  • 在OP正在使用的libgdx中,通过在创建ShaderProgram之后调用它来更简单地看到错误:`if(!shader.isCompiled())抛出新的GdxRuntimeException("无法编译着色器:"+ shader.getLog ());` (9认同)