OpenGL-Bug ???? Ich bin mir relativ sicher, er sitzt nicht vorm PC..
-
Hallo,
ich hab mich hier in der glslsandbox.com etwas am Raytracing versucht...Ging auch alles gut, bis ich 'ambient occlusion' implementieren wollte.
Also hier mal der Schipsel Pseudo-Code, den ich ändere um den Bug hervorzurufen:
V1:.... = max(0., abs(float)); // BUG!
V2:
.... = abs(float); // kein BUG!
Das noch witzigere ist, dass das max(0., ...) (und das abs()) eigentlich garnicht nötig ist, da der float eh stets >0 ist. Das abs() ist nur da, um sicher zu gehen.
Ich hab das bislang nur auf einer ollen gf8800 und einer gf9800 getestet. Aber ich hatte sonst nie Probleme mit "max()"...
Hat dazu jemand zufällig Infos, oder gibt es irgendwo ne glsl-Bugsammlung? Wäre schon gut zu wissen, welche Hardware wann versagt und warum.Ach ja, für Interessierte, das Symptom besteht darin, dass eine Wand des Raums einfach komplett verschattet wird, aber auch nur wenn ein anderes Objekt in der Szene existiert. Und von der Reihenfolge, wie die Szene aufgebaut wird hängt es auch noch ab.
Jetzt denkt natürlich jeder, dann stimmt wohl was nicht mit dem Objekt, oder wie die Szene aufgebaut wird, aaaber ich habe mir schon jedes erdenkliche Attribut (Normalen, Abstände, ...) zeichnen lassen. Hängt alles nicht von dem Bug ab, sprich sieht alles immer richtig und gleich aus, alles bis auf die AO-Komponente!! Und das würde eh nicht erklären, warum sich da was ändern sollte, wenn ich die oben genannten Änderungen vornehme.Und noch eine Frage: Wie geht glsl eigentlich mit negativen Wurzeln um? Hat leider nichts mit dem Bug zutun, da es keinen Unterschied macht, ob ich sqrt(x) oder sqrt(abs(x)), oder sqrt(max(0., x)) schreibe..
Grüße aus der Programmierhölle!
-
Ok - ist ein Hardware- oder Treiber-BUG. Auf einem neueren Notebook gehts (wenn auch nicht ruckelfrei - alt heißt also nicht zwangsläufig langsam.. :D).
Und ich habe noch einen anderen Weg gefunden den Bug zu umgehen, der auch genau so unsinnig ist.
Aus
if(bool1)
mache
if(bool1 && bool2), wobei bool2 immer ture wenn bool1==true..
- if(bool1 && true) geht allerdings nicht..Was mich jetzt noch interessiert, ist das warum/wann... Das muss doch ein alter Hase wissen!?
Workaround haben ist gut, Raten/Zufall eher nicht.
-
Jo, das sieht schon etwas seltsam aus, aber wundern tut es mich nicht. Dafür habe ich schon zu viele ähnliche Dinge bei Shaderprogrammierung und allem was irgendwie mit Grafiktreiber-Code interagiert erlebt.
Ich würds ohnehin ignorieren und
max()
undabs()
sowieso nur dann verwenden, wenn es von der Berechnung her Sinn macht (oder zum debuggen) - V1 sieht auch ohne das der float > 0 ist etwas aus als wüsste der Programmierer nicht was er wollte oder wie seine Formeln funktionieren sollen: Entweder man will "clampen" oder negative Werte auf die positive Achse projizieren... beides gleichzeitig wirkt etwas widersprüchlichBezüglich Wurzeln aus negativen Zahlen in Shadersprachen: Das Ergebnis ist da üblicherweise einfach undefiniert. Manche Implementationen ignorieren das Vorzeichen, andere geben einfach aus was immer der auf dem Chip für postitive Zahlen verdrahtete Algorithmus eben so hergibt. Da du selbst wissen solltest, was du da eigentlich berechnen willst und mit welchen Wertebereichen du hantierst, sollte das eigentlich ganz natürlich aus deinen Formeln hervorgehen, ob du bei
sqrt()
(so du es denn tatsächlich brauchst) mitabs()
,max()
oder eben nichts dergleichen arbeiten musst (weil z.B. ein x² schon ein "eingebautes"abs()
hat ;))Finnegan
-
OpferGL schrieb:
Was mich jetzt noch interessiert, ist das warum/wann... Das muss doch ein alter Hase wissen!?
Workaround haben ist gut, Raten/Zufall eher nicht.Ich würde mich sogar so weit aus dem Fenster lehnen und behaupten dass grafik-spezifischer Code von Engines die mit verscheidenster Hardware arbeiten müssen fast zum grössten Teil aus Workarounds besteht.
Willkommen in der Wunderbaren Welt der Grafik-Hardware/Treiber und der teilweise sehr eigenwilligen OpenGL-ImpelementierungenFinnegan
-
um den fehler zu analysieren ist nicht genug code da.
ich empfehle dir https://www.shadertoy.com/ , dort kannst du experimentieren und auch die shader abspeichern und mit anderen teilen.wenn du einen shader bug findest auf nur einer platform, geh sicher dass die neusten treiber drauf sind, manchmal vergisst man das, dann sind da treiber von vor 5jahren drauf und die fehler sind laengst behoben (zudem gibt es immer mal wieder optimierungen im shader compiler).
-
Finnegan schrieb:
beides gleichzeitig wirkt etwas widersprüchlich
Ich wäre froh, wenn der BUG das auch so sehen würde. Ist, wie gesagt nur zum deguggen.
Zu negativen Wurzeln: Aber es ist nicht so, dass dann der ganze Shader beeinflusst wird, bzw. andere Variablen, die nichts mit der Wurzel zutun haben?
- Es steht dann evtl nur Müll in der einen Wurzel-Variablen?!Ich habe für diese Grakas die "aktuellen" Treiber drauf, was allerdings nicht im Widerspruch dazu steht, dass sie ~5 Jahre alt sind...
Und noch ein Update zum Bug:
In meinem Browser kann ich "angle" aktivieren (was eine schlechte Idee ist, wenn man den Shader in endlicher Zeit kompiliert haben möchte, und besonders auf shadertoy.com). Dadurch wird der Bug nicht behoben, aber er ist anders: Aus der kompleten Verschattung wird dann garkeine.... Deutet das darauf hin, dass es ein Compiler-Bug ist, oder was kann man daraus schließen?Und ich glaube, rausgefunden zu haben, was die Ursache ist: Ich hatte evtl. zuviele Variablen.. Statt erst alles in einer separaten Var zu speichern und dann zu verwursten, wird jetzt alles direkt verwurstet - und der Bug ist weg....