Lazarus - OpenGL 3.3 Tutorial - Beleuchtung - Directional Light: Unterschied zwischen den Versionen
(→Vertex-Shader:) |
K (→Fragment-Shader) |
||
(12 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt) | |||
Zeile 1: | Zeile 1: | ||
− | [[Image:Lazarus - OpenGL 3.3 Tutorial - Beleuchtung - | + | [[Image:Lazarus - OpenGL 3.3 Tutorial - Beleuchtung - Directional Light.png|200px]]<br><br> |
− | =Beleuchtung - | + | =Beleuchtung - Directional Light = |
== Einleitung == | == Einleitung == | ||
− | + | Das Directional-Light entspricht in etwa dem Sonnen-Licht, die Lichtstrahlen kommen alle von der gleichen Richtung.<br> | |
− | + | Im Grunde ist die Sonne auch ein Punktlicht, aber auf der Erde nimmt man es als Directional-Light war.<br> | |
− | + | Im Beispiel von Rechts.<br> | |
<br> | <br> | ||
− | + | Im ersten Beispiel wurde die Beleuchung mit Acos und Pi berechnet.<br> | |
− | + | Dieser Umweg kann man sich sparen, es gibt zwar so ein kleiner Rechnungsfehler, aber diesen kann man getrost ingnorieren.<br> | |
+ | Dies hat sogar den Vorteil, wen der Einstrahlwinkel des Lichtes flacher als 90° ist, ist die Beleuchtungsstärke gleich null.<br> | ||
+ | Als was flacher als 90° ist, ist negativ.<br> | ||
+ | Für dies gibt es in GLSL eine fertige Funktion '''clamp''', mit der kann man einen Bereich festlegen.<br> | ||
+ | So das es in diesem Beispiel keinen Wert < '''0.0''' oder > '''1.0''' gibt.<br> | ||
<br> | <br> | ||
− | + | Der einzige Unterschied zu vorherigem Beispiel ist im Shader-Code. Auch der Hintergrund wurde etwas dunkler gemacht, das man den Licht-Effekt besser sieht.<br> | |
+ | <br> | ||
+ | Bei dem Lichtpositions-Vector ist es egal, wie weit die Lichtquelle weg ist, da der Vektor nur die Lichtrichtung angeben muss.<br> | ||
+ | Meistens nimmt man aber einen '''Einheitsvektor''', das ist ein Vektor mit der Länge '''1.0'''.<br> | ||
+ | Die Lichtposition wird im Vertex-Shader als Konstante definiert.<br> | ||
<br><br> | <br><br> | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
<br><br> | <br><br> | ||
− | + | Hier sieht man, das anstelle von arcos und Pi, '''clamp''' verwendet wurde.<br> | |
− | |||
− | |||
==Vertex-Shader:== | ==Vertex-Shader:== | ||
− | |||
− | |||
<syntaxhighlight lang="glsl">#version 330 | <syntaxhighlight lang="glsl">#version 330 | ||
− | #define | + | // Das Licht kommt von Rechts. |
+ | #define LightPos vec3(1.0, 0.0, 0.0) | ||
layout (location = 0) in vec3 inPos; // Vertex-Koordinaten | layout (location = 0) in vec3 inPos; // Vertex-Koordinaten | ||
Zeile 73: | Zeile 32: | ||
out vec4 Color; // Farbe, an Fragment-Shader übergeben. | out vec4 Color; // Farbe, an Fragment-Shader übergeben. | ||
+ | uniform mat4 ModelMatrix; // Matrix des Modell, ohne Frustumeinfluss. | ||
uniform mat4 Matrix; // Matrix für die Drehbewegung und Frustum. | uniform mat4 Matrix; // Matrix für die Drehbewegung und Frustum. | ||
− | + | float light(vec3 p, vec3 n) { | |
− | + | vec3 v1 = normalize(p); // Vektoren normalisieren, | |
− | float | + | vec3 v2 = normalize(n); // so das die Länge des Vektors immer 1.0 ist. |
− | vec3 | + | float d = dot(v1, v2); // Skalarprodukt aus beiden Vektoren berechnen. |
− | + | float c = clamp(d, 0.0, 1.0); // Alles > 1.0 und < 0.0, wird zwischen 0.0 und 1.0 gesetzt. | |
− | float d = dot( | + | return c; // Lichtstärke als Rückgabewert. |
− | |||
} | } | ||
− | void main(void) | + | void main(void) { |
− | { | + | gl_Position = Matrix * vec4(inPos, 1.0); |
− | |||
− | float col = | + | vec3 Normal = mat3(ModelMatrix) * inNormal; |
+ | float col = light(LightPos, Normal); | ||
− | + | Color = vec4(col, col, col, 1.0); | |
− | Color = vec4(col, col, col, | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<br><br> | <br><br> | ||
− | |||
==Fragment-Shader== | ==Fragment-Shader== | ||
<syntaxhighlight lang="glsl">#version 330 | <syntaxhighlight lang="glsl">#version 330 | ||
− | in vec4 Color; | + | in vec4 Color; // interpolierte Farbe vom Vertexshader |
out vec4 outColor; // ausgegebene Farbe | out vec4 outColor; // ausgegebene Farbe | ||
− | void main(void) | + | void main(void) { |
− | { | ||
outColor = Color; // Die Ausgabe der Farbe | outColor = Color; // Die Ausgabe der Farbe | ||
} | } | ||
Zeile 109: | Zeile 65: | ||
<br>Autor: [[Mathias]] | <br>Autor: [[Mathias]] | ||
+ | |||
== Siehe auch == | == Siehe auch == | ||
* Übersichtseite [[Lazarus - OpenGL 3.3 Tutorial]] | * Übersichtseite [[Lazarus - OpenGL 3.3 Tutorial]] |
Aktuelle Version vom 22. Juli 2018, 21:06 Uhr
Inhaltsverzeichnis
Beleuchtung - Directional Light
Einleitung
Das Directional-Light entspricht in etwa dem Sonnen-Licht, die Lichtstrahlen kommen alle von der gleichen Richtung.
Im Grunde ist die Sonne auch ein Punktlicht, aber auf der Erde nimmt man es als Directional-Light war.
Im Beispiel von Rechts.
Im ersten Beispiel wurde die Beleuchung mit Acos und Pi berechnet.
Dieser Umweg kann man sich sparen, es gibt zwar so ein kleiner Rechnungsfehler, aber diesen kann man getrost ingnorieren.
Dies hat sogar den Vorteil, wen der Einstrahlwinkel des Lichtes flacher als 90° ist, ist die Beleuchtungsstärke gleich null.
Als was flacher als 90° ist, ist negativ.
Für dies gibt es in GLSL eine fertige Funktion clamp, mit der kann man einen Bereich festlegen.
So das es in diesem Beispiel keinen Wert < 0.0 oder > 1.0 gibt.
Der einzige Unterschied zu vorherigem Beispiel ist im Shader-Code. Auch der Hintergrund wurde etwas dunkler gemacht, das man den Licht-Effekt besser sieht.
Bei dem Lichtpositions-Vector ist es egal, wie weit die Lichtquelle weg ist, da der Vektor nur die Lichtrichtung angeben muss.
Meistens nimmt man aber einen Einheitsvektor, das ist ein Vektor mit der Länge 1.0.
Die Lichtposition wird im Vertex-Shader als Konstante definiert.
Hier sieht man, das anstelle von arcos und Pi, clamp verwendet wurde.
Vertex-Shader:
#version 330
// Das Licht kommt von Rechts.
#define LightPos vec3(1.0, 0.0, 0.0)
layout (location = 0) in vec3 inPos; // Vertex-Koordinaten
layout (location = 1) in vec3 inNormal; // Normale
out vec4 Color; // Farbe, an Fragment-Shader übergeben.
uniform mat4 ModelMatrix; // Matrix des Modell, ohne Frustumeinfluss.
uniform mat4 Matrix; // Matrix für die Drehbewegung und Frustum.
float light(vec3 p, vec3 n) {
vec3 v1 = normalize(p); // Vektoren normalisieren,
vec3 v2 = normalize(n); // so das die Länge des Vektors immer 1.0 ist.
float d = dot(v1, v2); // Skalarprodukt aus beiden Vektoren berechnen.
float c = clamp(d, 0.0, 1.0); // Alles > 1.0 und < 0.0, wird zwischen 0.0 und 1.0 gesetzt.
return c; // Lichtstärke als Rückgabewert.
}
void main(void) {
gl_Position = Matrix * vec4(inPos, 1.0);
vec3 Normal = mat3(ModelMatrix) * inNormal;
float col = light(LightPos, Normal);
Color = vec4(col, col, col, 1.0);
}
Fragment-Shader
#version 330
in vec4 Color; // interpolierte Farbe vom Vertexshader
out vec4 outColor; // ausgegebene Farbe
void main(void) {
outColor = Color; // Die Ausgabe der Farbe
}
Autor: Mathias
Siehe auch
- Übersichtseite Lazarus - OpenGL 3.3 Tutorial