Shader提供错误的片段颜色

时间:2016-07-30 01:35:06

标签: java opengl libgdx glsl shader

我遇到了我在着色器体验中遇到过的最奇怪的问题。我创建了一些测试着色器代码(见下文)并在一个简单的纹理上运行它。

基本上我要做的是让我的着色器检查片段的颜色,如果它在一定范围内,它会根据统一的颜色变量为该片段着色。我遇到的问题是我的着色器无法正确识别片段的颜色。我甚至去检查颜色的红色部分是否等于1,并且总是为每个片段返回true。然而,如果我使用相同的着色器绘制原始纹理,它就可以正常工作。

为什么会这样?着色器编译时没有任何错误。我觉得我错过了一些明显的东西......

代码(如果您有权访问LibGDX,则可以自己运行此代码)。

// Vertex
#version 330

in vec4 a_position;
in vec4 a_color;
in vec2 a_texCoord0;

out vec4 v_color;
out vec2 v_texCoord0;

uniform mat4 u_projTrans;

void main() {
    v_color = a_color;
    v_texCoord0 = a_texCoord0;
    gl_Position = u_projTrans * a_position;
}

// Fragment
#version 330

in vec4 v_color;
in vec2 v_texCoord0;

out vec4 outColor;

uniform vec4 color;
uniform sampler2D u_texture;

void main() {
    // This is always true for some reason...
    if(v_color.r == 1.0) {
        outColor = color;
    } else {
        // But if I run this code it draws the original texture just fine with the correct colors.
        outColor = v_color * texture2D(u_texture, v_texCoord0);
    }
}

// Java code.
// Creating sprite, shader and sprite batch.
SpriteBatch batch = new SpriteBatch();
Sprite sprite = new Sprite(new Texture("testTexture.png"));
ShaderProgram shader = new ShaderProgram(Gdx.files.internal("vertex.vert"),
                Gdx.files.internal("fragment.frag"));
// Check to see if the shader has logged any errors. Prints nothing.
System.out.println(shader.getLog());
// We start the rendering.
batch.begin();
// We begin the shader so we can load uniforms into it.
shader.begin();
// Set the uniform (works fine).
shader.setUniformf("color", Color.RED);
// We end the shader to tell it we've finished loading uniforms.
shader.end();
// We then tell our renderer to use this shader.
batch.setShader(shader);
// Then we draw our sprite.     
sprite.draw(batch);
// And finally we tell our renderer that we're finished drawing.
batch.end();

// Dispose to release resources.
shader.dispose();
batch.dispose();
sprite.getTexture().dispose();

纹理:simple texture

1 个答案:

答案 0 :(得分:2)

片段着色器有2种输入颜色:一种作为顶点属性发送,另一种作为纹理发送。您打算检查纹理颜色,而是检查作为顶点属性发送的颜色值。

// Vertex
#version 330

in vec4 a_position;
in vec4 a_color;    // <--- A color value is passed as a vertex attribute
in vec2 a_texCoord0;

out vec4 v_color;
out vec2 v_texCoord0;

uniform mat4 u_projTrans;

void main() {
    v_color = a_color;    // <--- you are sending it to fragment shader
    v_texCoord0 = a_texCoord0;
    gl_Position = u_projTrans * a_position;
}
// Fragment
#version 330

in vec4 v_color;    // <--- coming from vertex buffer
in vec2 v_texCoord0;

out vec4 outColor;

uniform vec4 color;
uniform sampler2D u_texture;

void main() {
    // This is always true for some reason...
    if(v_color.r == 1.0) {   // <--- and then checking this vertex attribute color 
        outColor = color;    //      instead of what you send from texture
    } else {
        ...
    }
}