OpenGL Farbverläufe zwischen Triangles

Für Fragen zu Grafik APIs wie DirectX und OpenGL sowie Shaderprogrammierung.
Antworten
snoob741
Beiträge: 76
Registriert: 03.04.2012, 22:36

OpenGL Farbverläufe zwischen Triangles

Beitrag von snoob741 »

Hallo zusammen,

ich beschäftige mich grad mit der Einführung in OpenGL und habe bisher nur etwas DirectX Erfahrung.
Nun bastel ich mir grad ein Quadrat zusammen, das ich als GL_TRIANGLES render und mit unterschiedlichen
Farbwerten für die einzelnen Eckpunkte versehe:

Code: Alles auswählen

		glVertex3f(-1.0f,  1.0f,  1.0f);
                glColor3f(1.0f, 1.0f, 0.0f);
   
		glVertex3f(-1.0f, -1.0f,  1.0f);
                glColor3f(1.0f, 0.0f, 0.0f);
   
		glVertex3f( 1.0f, -1.0f,  1.0f);
                glColor3f(0.0f, 1.0f, 0.0f);
   
		glVertex( 1.0f, -1.0f,  1.0f);
                glColor3f(0.0f, 1.0f, 0.0f);
   
		glVertex3f( 1.0f,  1.0f,  1.0f);
                glColor3f(0.0f, 0.0f, 1.0f);
   
		glVertex3f(-1.0f,  1.0f,  1.0f);
                glColor3f(1.0f, 1.0f, 0.0f);
Wieso erhalte ich nicht den gleichen Farbverlauf, als wenn ich mit GL_QUADS render? Irgendwie scheinen
die Farbverläufe zwischen den Dreiecken strikt getrennt zu sein. Aus DirectX kenne ich das, dass eine
Liste aus Dreiecken den gleichen Farbverlauf wie GL_QUADS erzeugt...

Mache ich etwas falsch? Denn korrigiert mich wenn ich falsch liege, aber später werde ich ja hauptsächlich
mit GL_TRIANGLES oder GL_TRIANGLE_STRIP arbeiten oder?
Benutzeravatar
eXile
Establishment
Beiträge: 1136
Registriert: 28.02.2009, 13:27

Re: OpenGL Farbverläufe zwischen Triangles

Beitrag von eXile »

Mach' bitte mal einen Screenshot.

Wenn ich mir das gerade im Kopf richtig vorstelle, ist das so by Design, und liegt an der Interpolation der Farbwerte via baryzentrischer Koordinaten. In der Mitte des Quads müsste ein Pixel in Dreieck 1 bereits die Farbe des nicht-mit-Dreieck-1-geteilten Vertex von Dreieck 2 kennen.

Der Grund, warum das für die Praxis nicht relevant ist, ist dass fast immer Texturen benutzt werden, und die Farbwerte komplett anders (als via baryzentrischer Koordinaten) im Pixel Shader berechnet werden (eben weil man die Texturen samplet, oder mit irgendwelchen Formeln Farbwerte generiert).

(Nachtrag: Baryzentrische Koordinaten sind nur für Simplizes definiert; daher wird bei einem Quad eine simple Linearkombination gebildet.)
Zuletzt geändert von eXile am 03.04.2012, 23:18, insgesamt 1-mal geändert.
snoob741
Beiträge: 76
Registriert: 03.04.2012, 22:36

Re: OpenGL Farbverläufe zwischen Triangles

Beitrag von snoob741 »

Bitte sehr, hier 2 Screenshots:

http://s7.directupload.net/file/d/2849/hpeqqkhb_jpg.htm GL_QUADS Farbverlauf
http://s14.directupload.net/file/d/2849 ... nr_jpg.htm GL_TRIANGLES / GL_TRIANGLE_STRIP Farbverlauf
Benutzeravatar
eXile
Establishment
Beiträge: 1136
Registriert: 28.02.2009, 13:27

Re: OpenGL Farbverläufe zwischen Triangles

Beitrag von eXile »

Meine Hypothese war richtig, es liegt an der Farbinterpolation via baryzentrischer Koordinaten: Das links-untere Dreieck „kennt“ die blaue Färbung des Vertex rechts-oben nicht. Daher kriegt kein Pixel im links-unteren Dreieck irgendwelche blaue Farbe ab. Das ist so by Design.

Wenn du uns sagst, was du im Endeffekt erreichen willst, können wir Dir vielleicht weiterhelfen, auf welchem Wege du dieses Problem umgehen kannst.
snoob741
Beiträge: 76
Registriert: 03.04.2012, 22:36

Re: OpenGL Farbverläufe zwischen Triangles

Beitrag von snoob741 »

Danke für Deine Ausführliche Antwort. Erreichen will ich damit nichts, hatte mit den Formen "nur" rumgespielt
und mich dabei gewundert, dass das Verhalten anders ist als ich es von DirectX 9 herr kenne. Dort hat ein Quad,
dass man selbst aus 2 Tris erstellt den Farbverlauf von GL_QUADS.

Ich hatte nur angst, das ich was falsch gemacht habe. Später wird man wie ich gelesen habe, überwiegend mit
Vertexbuffern rendern und hier Strips bzw. Listen nehmen wie ich es von DX her schon kenne. Würde ich jetzt
ein einfachen Stride aus unterschiedlichen Farben rendern hätte ich zwischen OpenGL und DirectX unterschiedliche
Farbverläufe, was ich erstmal nicht erwartet hab.
waigie
Beiträge: 82
Registriert: 20.05.2009, 19:37

Re: OpenGL Farbverläufe zwischen Triangles

Beitrag von waigie »

Exile hat ganz recht das Problem liegt daran wie die Farben interpoliert werden. Dazu hier mal ein Beispiel von mir

Code: Alles auswählen

// Quad Ergebnis
	    gl.glBegin(GL2.GL_TRIANGLE_STRIP);
	    
	    gl.glColor3f(1.0f, 1.0f, 0.0f);
	    gl.glVertex3f(-1.0f, 1.0f, 1.0f);
	    
	    gl.glColor3f(1.0f, 0.0f, 0.0f);
	    gl.glVertex3f(-1.0f, -1.0f, 1.0f);
	       
	    gl.glColor3f(0.0f, 0.0f, 1.0f);
	    gl.glVertex3f( 1.0f, 1.0f, 1.0f);
	    
	    gl.glColor3f(0.0f, 1.0f, 0.0f);
	    gl.glVertex3f( 1.0f, -1.0f, 1.0f);
	    
	    gl.glEnd();
	    
	    // Triangle Strip Ergebnis
	    gl.glBegin(GL2.GL_TRIANGLE_STRIP);
	    
	    gl.glColor3f(1.0f, 0.0f, 0.0f);
	    gl.glVertex3f(-1.0f, -1.0f, 1.0f);

	    gl.glColor3f(0.0f, 1.0f, 0.0f);
	    gl.glVertex3f( 1.0f, -1.0f, 1.0f);
	    
	    gl.glColor3f(1.0f, 1.0f, 0.0f);
	    gl.glVertex3f(-1.0f, 1.0f, 1.0f);
	           
	    gl.glColor3f(0.0f, 0.0f, 1.0f);
	    gl.glVertex3f( 1.0f, 1.0f, 1.0f);
	    	    
	    gl.glEnd();
Renderergebnisse:
Bild
Ich zeichne 2 mal 2 Dreiecke die Diagonale liegt jedoch anders. Damit sind auch die 2 unterschiedlichen Farbverläufe zu erklären.

Was mir bei dir noch auffällt. Du verwendest glColor immer nachdem du die Vertexdaten gesetzt hast. Das ist die falsche Reihenfolge, du musst die Farbe vor dem Vertex setzen.
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: OpenGL Farbverläufe zwischen Triangles

Beitrag von dot »

Exakt. Es liegt daran wie der Treiber/die GPU deine Quads triangularisieren. Verwend einfach nur Dreiecke, dann gibts da keine Unklarheiten (Quads sind eh deprecated) ;)
snoob741
Beiträge: 76
Registriert: 03.04.2012, 22:36

Re: OpenGL Farbverläufe zwischen Triangles

Beitrag von snoob741 »

Jetzt ist alles klar. Danke für Eure hilfe! Habe es sogar mit Eurer hilfe mit VBO's
zum Laufen bekommen.

Ich habe jedoch noch ein kleines Problem mit dem Datentypen Short. Wenn ich
ein Quad wie folgt definiere:

Code: Alles auswählen

Vertex vertices[] = {
		Vertex(-1.0f,  1.0f,  1.0f, 255,  255,   0, 255),   
		Vertex(-1.0f, -1.0f,  1.0f, 255,    0,   0, 255),  
		Vertex( 1.0f,  1.0f,  1.0f,   0,    0, 255, 255),  
		Vertex(-1.0f, -1.0f,  1.0f, 255,    0,   0, 255),    
		Vertex( 1.0f, -1.0f,  1.0f,   0,  255,   0, 255),
		Vertex( 1.0f,  1.0f,  1.0f,   0,    0, 255, 255)
    };
Kann ich wenn ich in der Klasse Vertex für die Farbwerte GLbyte verwende
die alles nach wie vor korrekt rendern. Nutze ich jedoch GLshort, was laut
Spec auch gehen sollte (GL_SHORT bzw. GL_UNSIGNED_SHORT), dann sehe
ich nichts ... Mache ich hier was falsch?

Code: Alles auswählen

glVertexPointer(3, GL_FLOAT, sizeof(Vertex), sizeof(float)*0);
glEnableClientState(GL_VERTEX_ARRAY);

glColorPointer(4, GL_SHORT, sizeof(Vertex), sizeof(float)*3); 
glEnableClientState(GL_COLOR_ARRAY);
anonym
Beiträge: 79
Registriert: 15.07.2009, 07:35
Kontaktdaten:

Re: OpenGL Farbverläufe zwischen Triangles

Beitrag von anonym »

Passt Du auch die Farbwerte an? Ich vermute, dass die Integerwerte wie unter Direct3D auf den Wertebereich [0.0f; 1.0f] (unsigned, unorm) bzw. [-1.0f; 1.0f] (signed, snorm) abgebildet werden. Die Werte der Farkomponenten würden dann im Falle des (ushort)255 jeweils 255/65535 < 1/255 annehmen und alle Komponenten gemeinsam somit schwarz repräsentieren (oder zumindest fast schwarz, abhängig von der Konvertierung ins Format des Rendertargets). Dies impliziert einen schwarzen Hintergrund. Ist das richtig?

EDIT:
OpenGL Spec - 4.1.9 Dithering hat geschrieben:"Representable color value" sind diejenigen Werte, welche vom Format des Ziels angenommen werden können.
Wenn Dithering deaktiviert, dann wird auf den nächsten "representable color value" abgerundet.
Wenn Dithering aktiviert, dann ist auf Basis von der Lage des Fragments sowie des Farbwerts ein nicht spezifizierter Ditheringalgorithmus zu konsultieren, der einen der beiden angrenzenden "representable color value" auswählt. Innerhalb dieser Einschränkung gibt es anscheinbar mehrere Optionen.
Standardmäßig ist Dithering aktiviert, somit sollte der Fall "fast schwarz" eingetreten sein.
snoob741
Beiträge: 76
Registriert: 03.04.2012, 22:36

Re: OpenGL Farbverläufe zwischen Triangles

Beitrag von snoob741 »

Ja ich habe auch die Farbwerte angepasst und auf den Wertebereich [1...0] gesetzt, das ändert aber nichts (Unter DirectX läuft es mit dem Wertebereich [0...255] als D3DDECLTYPE_SHORT4.
Das mit dem schwarzen Hintergrund ist richtig. Danke für die Info mit dem Dithering.
anonym
Beiträge: 79
Registriert: 15.07.2009, 07:35
Kontaktdaten:

Re: OpenGL Farbverläufe zwischen Triangles

Beitrag von anonym »

Ich dachte wegen der 255 in den Vertices an DXGI_FORMAT_*_UNORM und mal wieder nicht weiter. :roll: Jedenfalls verhält es sich unter OpenGL bei Farben folgendermaßen:
OpenGL Spec - glColor* hat geschrieben:Current color values are stored in floating-point format, with unspecified mantissa and exponent sizes. Unsigned integer color components, when specified, are linearly mapped to floating-point values such that the largest representable value maps to 1.0 (full intensity), and 0 maps to 0.0 (zero intensity). Signed integer color components, when specified, are linearly mapped to floating-point values such that the most positive representable value maps to 1.0, and the most negative representable value maps to -1.0. (Note that this mapping does not convert 0 precisely to 0.0.) Floating-point values are mapped directly.
Ich habe bei mir obiges Beispiel getestet, dass anstatt glColor3f glColor3us sowie glColor3s verwendet und wie erwartet funktioniert (65535/65535 bzw. 32767/32767 sichtbar).
Antworten