Ich habe wirklich seltsames Problem Ich kann seit Tagen nicht pin down
. Ich mache eine einfache Per-Vertex-Beleuchtung und es funktioniert gut auf Nvidia
, aber macht nichts schattiert mit Lichtern auf AMD/ATI
. Ich habe herausgefunden, dass das Problem etwas mit Attributen zu tun hat - besonders mit dem Attribut color.
Das ist mein Vertex-Shader:GLSL Shader funktioniert nicht auf AMD/ATI, funktioniert aber auf NVIDIA
#version 140
uniform mat4 modelViewProjectionMatrix;
in vec3 in_Position; // (x,y,z)
in vec4 in_Color; // (r,g,b,a)
in vec2 in_TextureCoord; // (u,v)
out vec2 v_TextureCoord;
out vec4 v_Color;
uniform bool en_ColorEnabled;
uniform bool en_LightingEnabled;
void main()
{
if (en_LightingEnabled == true){
v_Color = vec4(0.0,1.0,0.0,1.0);
}else{
if (en_ColorEnabled == true){
v_Color = in_Color;
}else{
v_Color = vec4(0.0,0.0,1.0,1.0);
}
}
gl_Position = modelViewProjectionMatrix * vec4(in_Position.xyz, 1.0);
v_TextureCoord = in_TextureCoord;
}
Dies ist Pixel-Shader:
#version 140
uniform sampler2D en_TexSampler;
uniform bool en_TexturingEnabled;
uniform bool en_ColorEnabled;
uniform vec4 en_bound_color;
in vec2 v_TextureCoord;
in vec4 v_Color;
out vec4 out_FragColor;
void main()
{
vec4 TexColor;
if (en_TexturingEnabled == true){
TexColor = texture2D(en_TexSampler, v_TextureCoord.st) * v_Color;
}else if (en_ColorEnabled == true){
TexColor = v_Color;
}else{
TexColor = en_bound_color;
}
out_FragColor = TexColor;
}
Also dieser Shader erlaubt 3 Staaten - wenn ich Lichter verwenden, wenn ich nicht Lichter verwenden, aber ein verwenden Per-Vertex-Farbe und wenn ich eine einzige Farbe für alle Ecken verwende. Ich habe den gesamten Lichtberechnungscode entfernt, weil ich das Problem auf ein Attribut aufmerksam gemacht habe. Dies ist die Ausgabe aus dem Shader:
Wie Sie sehen können, ist alles blau (so dass alles, was keine Schattierung oder Farbe hat
(en_LightingEnabled == false and en_ColorEnabled == false)
).
Wenn ich diesen Code in Vertex-Shader ersetzen:
if (en_ColorEnabled == true){
v_Color = in_Color;
}else{
mit diesem:
if (en_ColorEnabled == true){
v_Color = vec4(1.0,0.0,0.0,1.0);
}else{
ich folgendes:
So können Sie sehen, dass es alles ohne Schattierung macht immer noch blau, aber jetzt rendert es auch alles, was Lichter verwendet (en_LightingEnabled == true
) grün. So sollte es sein. Das Problem ist, dass in_Color
Attribut sollte nie Lichter stören, wie es nie einmal ausgeführt würde, wenn Lichter aktiviert sind. Sie können auch sehen, dass nichts in dem Bild rot ist, was bedeutet, dass in dieser Szene en_ColorEnabled
immer false
ist. So in_Color
ist hier völlig nutzlos, aber es verursacht Fehler an Orten, die es logisch nicht sollte. Auf Nvidia
funktioniert es gut und grüne Flächen zeichnen mit oder ohne in_Color
.
Kann ich etwas verwenden AMD
wird nicht unterstützt? Benutze ich etwas außerhalb GLSL
spec? Ich weiß, AMD
ist strenger mit GL
spec als Nvidia
, so ist es möglich, dass ich etwas undefiniert. Ich habe den Code so einfach wie möglich gemacht und habe immer noch das Problem, also sehe ich es nicht.
Auch habe ich festgestellt, dass es nichts (auch blaue Bereiche) auf dem Bildschirm zeichnet, wenn in_Color
Vertex-Attribut deaktiviert ist (nein glEnableVertexAttribArray
), aber warum? Ich benutze nicht einmal die Farbe. Deaktivierte Attribute müssen (0,0,0,1
) von der Spezifikation zurückgegeben werden, oder? Ich habe versucht, mit glVertexAttrib4f
, um diese Farbe zu ändern, aber immer noch schwarz. Compiler und Linker gibt keine Fehler oder Warnungen zurück. Attribut in_Color ist mit glGetAttribLocation
in Ordnung. Aber wie gesagt, nichts davon ist wichtig, da diese Verzweigung nie in meinem Code ausgeführt wird. Irgendwelche Ideen?
Getestet am Nvidia660Ti
und funktioniert gut, getestet am ATI
mobility radeon HD 5000
Laptop und habe diesen Fehler. Meine einzige Idee war, dass ich vielleicht die Fähigkeiten der GPU
(zu viele Attribute und so weiter) überschreiten würde, aber als ich meinen Code auf diesen reduzierte, dann hörte ich auf zu glauben. Ich verwende hier nur 3 Attribute.
Auch einige meiner Freunde getestet auf viel neuere AMD
Karten und bekam das gleiche Problem.
UPDATE 1
Vertex-Attribut gebunden ist, etwa so:
if (useColors){
glUniform1i(uni_colorEnable,1);
glEnableVertexAttribArray(att_color);
glVertexAttribPointer(att_color, 4, GL_UNSIGNED_BYTE, GL_TRUE, STRIDE, OFFSET(offset));
}else{
glUniform1i(uni_colorEnable,0);
}
Auch fand ich, wie die Seltsamkeit zu zeigen, noch einfacher - nimm diesen Vertex-Shader:
void main()
{
v_Color = clamp(vec4(1.,1.,1.,1.) * vec4(0.5,0.5,0.25,1.),0.0,1.0) + in_Color;
gl_Position = modelViewProjectionMatrix * vec4(in_Position.xyz, 1.0);
v_TextureCoord = in_TextureCoord;
}
Also keine Verzweigung. Und ich bekomme diese: Wenn ich diesen Code ändern, indem
in_Color
Entfernung etwa so:
void main()
{
v_Color = clamp(vec4(1.,1.,1.,1.) * vec4(0.5,0.5,0.25,1.),0.0,1.0);
gl_Position = modelViewProjectionMatrix * vec4(in_Position.xyz, 1.0);
v_TextureCoord = in_TextureCoord;
}
ich dieses:
Das letzte ist, was ich erwarten würde, aber die vorherige doesn‘ t zeichne alles, obwohl ich Addition (+
) anstelle von etwas anderem mache. Also wenn attrib
nicht gebunden ist und (0,0,0,0
) oder (0,0,0,1
) angegeben ist, dann sollte es nichts getan haben. Und dennoch versagt es immer noch.
Außerdem sind alle Protokolle leer - Kompilierung, Verknüpfung und Validierung. Keine Fehler oder Warnungen. Obwohl ich festgestellt habe, dass die Shader-Debug-Informationen AMD/ATI
gibt, ist weit unterlegen, was Nvidia
gibt.
UPDATE 2
Die einzige fix ich fand, war attribarray
in allen Fällen zu ermöglichen (so sendet er im Grunde Junk GPU
wenn Farbe nicht aktiviert ist), aber als ich eine Uniform für die Farbe zu überprüfen, dann benutze ich es einfach nicht. Es ist also wie folgt aus:
if (useColors){
glUniform1i(uni_colorEnable,1);
}else{
glUniform1i(uni_colorEnable,0);
}
glEnableVertexAttribArray(att_color);
glVertexAttribPointer(att_color, 4, GL_UNSIGNED_BYTE, GL_TRUE, STRIDE, OFFSET(offset));
Ich habe keine Ahnung, warum das geschieht oder warum muss ich diese verwenden. Ich brauche das nicht auf Nvidia
. Also ich denke, das ist langsamer und ich verschwende Bandbreite? Aber zumindest funktioniert es ... Hilfe, wie man das besser macht, wäre aber nützlich.
Zeigen Sie, wie Sie die Scheitelpunktattribute binden. Versuchen Sie auch, Ihr Programm zu validieren und das Validierungsprotokoll anzuzeigen. – sbabbi
versuchen, ohne die Bedingungen neu zu schreiben ... (Programme stattdessen wechseln) ... Ich lief gerade in ein bonkers Problem mit Intel Treiber und Bedingungen: http://StackOverflow.com/Questions/24222343/GLSL-Boolean-Evaluation-wackiness –
Ich habe das Thema aktualisiert. Also auch ohne Verzweigung bekomme ich immer noch Probleme. – user1214513