Gouraudshading


Effiziente Schattierung von Dreiecken

Das Flatshading, wie im letzten Abschnitt gesehen, stellt die schnellste und einfachste Möglichkeit da Dreiecke zu schattieren. Der optische Effekt ist jedoch nur mäßig und nicht wirklich realistisch. Da wir bereits die RGB-Werte an den drei Eckpunkten des Dreiecks berechnet haben kann man durch einfache lineare Interpolation der Farbwerte ein viel realistischeres Farbverhalten erhalten. Das Prinzip dabei ist einfach.

Gegeben seien die Farbwerte der drei Eckpunkte des Dreiecks. Da wir von oben nach unten das Dreieck rastern berechnen wir die Farbwertdelta der jeweiligen Kanten und addieren sie für jede Zeile auf den aktuellen Farbwert der rechten und linken Kante. Wenn wir nun eine Zeile schattieren haben wir bereits die aktuellen Werte für die linke und rechte Kante, so dass wir nur noch das Farbdelta zwischen diesen beiden Werten ermitteln müssen. Dieses Farbdelta ist dann genau das Delta, was den Übergang von einem zum nächsten Pixel in einer Zeile beschreibt.

Beispiel:

Angenommen P0 haben den Blauwert 0, P1 den Blauwert 100 und P2 den Blauwert 200. Welchen Wert hat nun P3 ? Die Antwort ist einfach. Das Delta D02 zwischen P0 und P2 ist 200 - 0 geteilt durch 100 - 0 und somit 2. Analog dazu das Delta D01 welches 1 ist. Der Punkt P3 besitzt die y - Koordinate 50. Addiert man nun 50 mal D02 auf den Blauwert von P0 so ist der aktuelle Wert der linken Kante 100. Analog dazu die rechte Kante mit dem Wert 50. Nun bilden wir wieder das Delta zwischen diesen Werten. 50 - 100 geteilt durch 50 - 0 und somit -1. Um nun den Blauanteil vom Punkt P3 zu erhalten addieren wir nun 25 mal dieses Delta auf den aktuellen Farbwert und erhalten somit 100 + 25 * (-1) = 75.

Wie bereits aber im Gradienten Abschnitt gesehen ist dieser Aufwand überhaupt nicht nötig. Wenn wir also unser Dreieck mit Gouraudshading schattieren wollen, berechnen wir einfach die Gradienten der Farbwerte, also die Rot-, Grün- und Blaustufen. Zur Verdeutlichung nehmen wir noch mal das Beispiel von oben. Mit den Formeln ergibt sich nun:

Somit ergibt sich die Farbe von P3 aus Farbwert von P0 + dcx * 25 + dcy * 50 = 75.

Fliesskommazahlen und Farbwerte

Natürlich ist es logisch, dass die drei Farbdelta für Rot, Grün und Blau in der Regel nicht Ganzzahlig sind. Betrachtet man sich jedoch nun, wie ein Pixel aufgebaut bzw. wie ihn eine Grafikkarte interpretiert, so wird schnell klar, dass die ständige Konvertierung zwischen Fliesskommazahlen und Integer ineffizient ist.

Bits

31 - 24

23 - 16

15 - 8

7 - 0

Pixel

Alpha

Rot

Grün

Blau

Wie man sieht nimm jede Farbe 8 Bit nur in Anspruch. Es bleiben also 24 Bits übrig die keine Verwendung finden. Nun bedienen wir uns des folgenden Tricks. Wir nehmen einfach von den übrigen 24 Bits 8, 16 oder alle um darin den Nachkommastellen anteil unterzubringen. Für das Beispiel beschränken wir uns auf 8 Bits. Angenommen wir möchten zwischen zwei Punkten mit dem Spaltenabstand 4 und den Farbwerten 0 und 2 linear interpolieren. Dazu berechen wir das Farbdelta, welches 2 ist und shiften dieses nun um 8 Bits nach links.

Bit

31

30

29

28

27

26

25

24

23

22

21

20

19

18

17

16

15

14

13

12

11

10

9

8

7

6

5

4

3

2

1

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

1

0

Nach dem shift:

Bit

31

30

29

28

27

26

25

24

23

22

21

20

19

18

17

16

15

14

13

12

11

10

9

8

7

6

5

4

3

2

1

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

1

0

0

0

0

0

0

0

0

0

Nun teilen wir durch den Abstand 4 und erhalten als Delta:

Bit

31

30

29

28

27

26

25

24

23

22

21

20

19

18

17

16

15

14

13

12

11

10

9

8

7

6

5

4

3

2

1

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

1

0

0

0

0

0

0

0

Dieses Delta enspricht der Zahl 128. Teilt man 128 durch 256 wird einem schnell klar, dass dieses genau 2 geteilt durch 4 entspricht. In jedem Schritt addieren wir nun dieses Delta zu dem um 8 Bits nach links geshifteten Anfangswert. Will man die aktuelle Farbe erhalten, so shiftet man diesen Wert um 8 Bits zurück nach rechts. Für das Beispiel erhält man also 0 * 256 + 4 * 128 = 512. Das entspricht genau dem Endwert 2. Dieses muss man natürlich für jeden Farbkanal einzeln berechnen.

Gouraudshading unter perspektivischer Projektion

All die oben beschriebenen Verfahren kann man auch unter perspektivischer Projektion benutzen. Es bleibt nur anzumerken, dass die lineare Interpolation hierbei aber eigentlich Fehler erzeugt, welche jedoch durch das Auge nicht wahrgenommen werden und man deshalb ohne Beschränkung vernachlässigen kann. Mehr dazu beim Texturshader.

Macheffekt

Macheffekt beim Gouraudshading (Wikipedia)
Entstehung des Macheffekts (Wikipedia)

Gouraudschattiertes Dreieck



Index

Flatshading

Pixelshader

Phong Shading