Warum eine Kugel auf dem Bildschirm rund aussieht
Diffuse Schattierung macht eine Fläche heller, je mehr sie dem Licht zugewandt ist. Ohne sie wäre eine Kugel auf dem Bildschirm nur eine flache, gleichfarbige Scheibe.
Die Helligkeit eines Pixels folgt aus einer einzigen Rechnung mit zwei Richtungen, der Richtung der Fläche und der Richtung zum Licht. Die rechnen Sie hier selbst.
Am Ende dieser Lektion
Notiz
Ich kann die diffuse Helligkeit einer Fläche aus ihrer Normalen und der Lichtrichtung berechnen.
Schlüsselwörter
| Begriff | Was er bedeutet |
|---|---|
| Normale | ein Pfeil senkrecht zur Fläche |
| Einheitsvektor | ein Vektor mit der Länge 1 |
| Normieren | einen Vektor auf die Länge 1 bringen |
| Diffuse Helligkeit | Helligkeit, die vom Winkel zum Licht abhängt |
| Lichtrichtung | der Pfeil vom Punkt zur Lichtquelle |
Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.
Die Normale zeigt senkrecht von der Fläche weg
Die Normale ist ein Pfeil, der senkrecht auf der Fläche steht. Bei einer Kugel zeigt sie von der Mitte C zum Punkt P: Sie ist P minus C, geteilt durch den Radius.
Für die Helligkeit zählt nur die Richtung. Darum normiert man jeden Pfeil: Man teilt jede Zahl durch die Länge des Pfeils, die Wurzel aus der Summe der Quadrate. Dann hat er die Länge 1.
Beispiel: den Vektor (0, 3, 4) normieren
| Schritt | Rechnung | Ergebnis |
|---|---|---|
| Quadrate | 0 mal 0, 3 mal 3, 4 mal 4 | 0, 9, 16 |
| Länge | Wurzel aus 0 plus 9 plus 16 | 5 |
| Jede Zahl teilen | 0 durch 5, 3 durch 5, 4 durch 5 | (0, 0,6, 0,8) |
| Probe | Länge von (0, 0,6, 0,8) | 1 |
Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.
Je kleiner der Winkel zum Licht, desto heller
Die diffuse Helligkeit ist das Skalarprodukt aus der Normalen und der Lichtrichtung, beide normiert. Zeigen beide in dieselbe Richtung, ist es 1, die Fläche ist am hellsten. Stehen sie senkrecht, ist es 0.
Ein negativer Wert hieße, das Licht kommt von hinten. Dann gilt max(0, ...): Die Fläche ist schwarz, nie dunkler. Mal 255 und gerundet ergibt das den Grauwert.
Beispiel: Normale (0, 0, 1) und vier Lichtrichtungen
| Lichtrichtung | Normiert | Skalarprodukt | Helligkeit | Grauwert |
|---|---|---|---|---|
| (0, 0, 1) | (0, 0, 1) | 1 | 1 | 255 |
| (0, 3, 4) | (0, 0,6, 0,8) | 0,8 | 0,8 | 204 |
| (0, 1, 0) | (0, 1, 0) | 0 | 0 | 0 |
| (0, 0, -1) | (0, 0, -1) | -1 | 0 | 0 |
Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.
Die diffuse Helligkeit ausrechnen
# Diffuse Helligkeit: Normale (0, 0, 1), Licht aus Richtung (0, 3, 4).
n = [0, 0, 1]
l = [0, 3, 4]
laenge = (l[0] ** 2 + l[1] ** 2 + l[2] ** 2) ** 0.5
einheit = [l[0] / laenge, l[1] / laenge, l[2] / laenge]
h = n[0] * einheit[0] + n[1] * einheit[1] + n[2] * einheit[2]
print("Helligkeit:", h)
print("Grauwert:", int(255 * max(0, h) + 0.5))
# Ändern Sie l auf [0, 0, -4] und starten Sie erneut: Das Licht kommt von hinten.
Das Lab rechnet die Helligkeit mit NumPy nach
Der erste Befehl nimmt die Normale (0, 0, 1) und die Richtung (0, 3, 4), geteilt durch ihre Länge 5, und multipliziert sie mit @. Er gibt 0.8 aus.
Das ist dieselbe Zahl wie in der Tabelle. Die Lichtquelle steht für diese Fläche schräg von oben, die Fläche bleibt ziemlich hell.
Die diffuse Helligkeit nachrechnen
docker exec jupyter python3 -c "import numpy as np; n = np.array([0, 0, 1]); l = np.array([0, 3, 4]) / 5; print(n @ l)"Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Für jedes Pixel der Kugel gilt dieselbe Rechnung
Für jedes Pixel der Kugel berechnet der Befehl die Normale, die Helligkeit zum Licht von links oben vorn und daraus den Grauwert. Außerhalb der Kugel bleibt es schwarz.
Er speichert kugel_licht.png und gibt vier Zahlen aus: 255 147 4 0. Das ist der hellste Wert, der Wert in der Mitte, ein Wert unten rechts am Rand und ein Wert außerhalb.
Eine schattierte Kugel zeichnen
docker exec jupyter python3 -c "import numpy as np; from PIL import Image; y, x = np.mgrid[-20:20, -20:20]; z2 = 400 - x * x - y * y; ok = z2 >= 0; z = np.sqrt(np.where(ok, z2, 0)); n = np.stack([x, y, z]) / 20; l = np.array([-1.0, -1.0, 1.0]) / np.sqrt(3); h = np.clip((n * l.reshape(3, 1, 1)).sum(0), 0, 1) * ok; Image.fromarray((h * 255 + 0.5).astype('uint8')).save('kugel_licht.png'); b = np.array(Image.open('kugel_licht.png')); print(b.max(), b[20, 20], b[28, 28], b[0, 0])"Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
So sieht die schattierte Kugel aus
Die Datei zeigt eine runde Scheibe auf schwarzem Grund. Oben links ist sie fast weiß, zur Mitte hin wird sie grau, unten rechts geht sie in Schwarz über.
Dort zeigt die Normale vom Licht weg, das Skalarprodukt ist null oder negativ. Erst durch diesen Verlauf wirkt die Scheibe wie eine Kugel.
Ein häufiger Fehler
Warnung
Viele denken, die Länge der beiden Pfeile spiele für die Helligkeit keine Rolle. Das Skalarprodukt wächst aber mit jeder Länge. Ein Licht (0, 0, 4) ohne Normieren ergäbe 4 statt 1. Normieren Sie darum immer beide Vektoren, bevor Sie multiplizieren.