PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Interpoliert G80 "falsch" ?


Asmodeus
2006-12-07, 19:19:49
Ich habe leider noch eine weitere Merkwürdigkeit beim Testen meiner 8800GTX festgestellt. Ich übergebe an einen GLSL Vertex Shader mittels uniform einen einzelnen float Wert. Dieser float Wert beträgt immer 1.0f. Innerhalb des Vertex Shaders wird dieser Wert einfach an eine varying float Variable übergeben, um darauf im Fragment Shader zugreifen zu können. Die varyings werden dann ja interpoliert. Meinem Veständnis nach (und bei einer 7900GTX ist es z.b. auch so) ergibt jegliche Interpolation zwischen 1.0f und 1.0f immer auch wieder genau 1.0f. Um das zu überprüfen färbe ich im Fragment Shader alle Fragmente rot, wo der Wert der varying float Variablen == 1.0 ist. Für Werte != 1.0 wird das Fragment grün eingefärbt. Auf einer 7900GTX kommt dabei dann folgendes Ergebnis heraus:

http://www.inf.uni-konstanz.de/~colditz/Interpol01.jpg

Das entspricht auch meiner Erwartung. Der selbe unveränderte Shader Code führt nun aber auf einer 8800GTX zu folgendem Ergebnis:

http://www.inf.uni-konstanz.de/~colditz/Interpol02.jpg

Und das ist zumindest meiner Meinung nach falsch, denn zwischen 1.0 und 1.0 zu interpolieren liefert trotzdem immer wieder genau 1.0. Oder übersehe ich bei der Sache etwas?

EDIT: Ja, ich weiß, dass man Fließkommazahlen nie auf Gleichheit testen sollte. Die ganze Sache ist ja auch nur ein vereinfachtes Testszenario, um so einige Dinge herauszufinden. ;)

Gruss, Carsten.

Juerg
2006-12-07, 21:31:29
Gemeinsames Target SM3.0 verwendet oder für G70 SM3.0 und G80 SM4.0?

Demirug
2006-12-07, 21:44:22
Ich würde jetzt mal die gewagte These aufstellen das der Shaderoptimizer bei G70 die Interpolation durch eine Konstante ersetzt hat.

ScottManDeath
2006-12-07, 22:58:09
Für varying gibts in GLSL 1.20 noch den invariant specifier. Vieleicht hilft das.

Asmodeus
2006-12-08, 08:39:42
Für varying gibts in GLSL 1.20 noch den invariant specifier. Vieleicht hilft das.

Ja, habe ich auch schon dran gedacht und ausprobiert, dass Ergebnis bleibt jedoch das gleiche.

Gruss, Carsten.

Chris Lux
2006-12-08, 21:27:30
ineressant wäre hier wie groß die fehler sind die passiren. vielleicht mit einem epsilon vergleich nochmal machen und nachsehen wie groß das wird...

Asmodeus
2006-12-08, 22:33:22
ineressant wäre hier wie groß die fehler sind die passiren. vielleicht mit einem epsilon vergleich nochmal machen und nachsehen wie groß das wird...

Gute Idee, werde ich nochmal testen. Bisher habe ich noch herausgefunden, dass beim Auftreten des "Fehlers" der Wert auf jeden Fall immer kleiner als 1.0 ist. Außerdem tritt der Effekt auch dann auf, wenn ich im Vertex Shader der varying Variablen immer gleich den Wert 1.0 fest zuweise, den Wert als nicht über eine uniform Variable von außen übergebe.

Gruss, Carsten.

Asmodeus
2006-12-09, 11:55:08
Also die Abweichung von 1.0 geht bis maximal etwa -0.00000015. Also liegen die interpolierten Werte alle etwa zwischen 0.99999985 und 1.0.

Gruss, Carsten.

Trap
2006-12-09, 12:22:11
Wundert mich schon etwas, wie muss eine Schaltung aussehen, damit man solche Fehler bekommt? Wert = a*X1+(1-a)*X2 könnte solche Fehler erzeugen.

Aber warum nimmt man das anstatt Wert = X1+a*(X2-X1)? Ist das durch die Symmetrie leichter/billiger zu implementieren? Ich vermute eher, dass es schneller ist.

Asmodeus
2006-12-13, 17:19:08
Es gibt eine Lösung für das Problem. Mit der neuen Extension GL_EXT_gpu_shader4 wird auch der Modifier flat für varying Variablen eingeführt. Also mit:
flat varying float XYZ;
wird XYZ nicht über die Dreiecksfläche interpoliert sondern der Wert von XYZ bleibt an allen Stellen konstant.

EDIT: Ja, ich hätte wohl einfach nochmal genauer die Specs der neuen Extensions lesen sollen.

Gruss, Carsten.