2016-07-30 33 views
-2

Ich bin auf das seltsamste Problem gestoßen, das ich je in meiner Shader-Erfahrung hatte. Ich habe einen Test-Shader-Code erstellt (siehe unten) und habe ihn mit einer einfachen Textur ausgeführt.Shader gibt falsche Fragmentfarbe

Im Grunde habe ich versucht, meinen Shader die Farbe eines Fragments überprüfen zu lassen, und wenn es innerhalb eines bestimmten Bereichs liegt, würde es dieses Fragment nach einer einheitlichen Farbvariablen färben. Das Problem, das ich habe, ist, dass mein Shader die Farbe eines Fragments nicht korrekt erkennt. Ich ging sogar so weit, zu überprüfen, ob der rote Teil der Farbe gleich Eins ist und es immer gibt für jedes Fragment wahr zurück. Wenn ich jedoch den gleichen Shader verwende, um die ursprüngliche Textur zu zeichnen, funktioniert es gut.

Warum passiert das? Der Shader kompiliert ohne irgendwelche Fehler was auch immer. Ich fühle mich, als würde ich etwas offensichtlich übersehen ...

Code (wenn Sie Zugriff auf LibGDX haben, können Sie diesen Code für sich selbst ausführen).

// 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(); 

Die Textur: simple texture

+1

Und welche Farben haben Ihre Ecken? Wenn Sie den obigen Code verwenden können, dann sind sie anscheinend weiß. Es ist also keine Überraschung, dass die Bedingung wahr ist. –

+0

Dies ist natürlich der logische Grund, aber ich sehe nicht, wie meine Scheitelpunkte weiß sein könnten, wenn das einzige, was ich rendere, diese 32x32 Textur ist? – Charanor

+0

Sie übergeben ein Scheitelpunktattribut 'a_color'. Welche Daten liefern Sie für dieses Attribut im Vertex-Puffer? Wenn Sie die Texturfarbe vergleichen möchten, sollten Sie die Textur natürlich zuerst probieren. –

Antwort

2

Sie haben zwei Eingänge Farben für Ihre Fragment-Shader: eine als Vertex-Attribut und eine als Textur gesendet . Sie beabsichtigen, die Texturfarbe zu überprüfen, aber Sie überprüfen stattdessen den Farbwert, der als Vertex-Attribut gesendet wird.

// 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 { 
     ... 
    } 
}