OpenGL Tutorial (Version 3.3) – spiegelnde Reflexion, Detail Mapping (Download)

Im letzten Programmbeispiel haben wir im Fragment Shader ausschließlich die ambiente und diffuse Beleuchtung berücksichtigt und dabei etwaige spiegelnde Reflexionen an glatten Oberflächen vernachlässigt. Dies wollen wir nun nachholen und zugleich eine Detail Mapping Technik vorstellen, bei welcher in jedem Textur-Farbkanal jeweils eine separate Detail Map gespeichert wird.






Spiegelnde Reflexion

float tempDot = dot( NormalPerTexel, negLightDir);

// Schritt 1: reflektierten Lichtvektor berechnen:
// reflektierter Lichtvektor = 2.0*tempDot*NormalPerTexel-negLightDir


// Je genauer die negative Richtung der reflektierten Lichtstrahlen mit der
// Blickrichtung übereinstimmt, umso stärker erscheinen die Spiegelungen:

// intense = -dot(reflektierter Lichtvektor, ViewDirection)

// kombiniert man beide Rechenschritte, dann erhält man:

float intense = max(-dot(2.0*tempDot*NormalPerTexel-negLightDir,
                    ViewDirection), 0.0);

// Durch die nachfolgenden Multiplikationsschritte wird die Fläche
// der Spiegelung schrittweise verkleinert:
intense *= intense;
intense *= intense;
intense *= intense;
intense *= intense;

// Im letzten Schritt wird die so berechnete Intensität noch mit den
// Reflexionseigenschaften der Oberfläche multipliziert, die in der
// Specular Map gespeichert sind:
vec4 SpecColor = intense*texture(SpecularTexture, gs_TexCoord[0].st);



Detail Mapping
Kommen wir nun zum Detail Mapping. Das hier gezeigte Verfahren haben wir speziell für die Darstellung von Planeten aus geringem Abstand implementiert:

// Wir benötigen für die !Planetendarstellung! die y-Komponente der
// der untransformierten Normale (gespeichert in gs_TexCoord[4].x). Am
// Äquator ist die Ausprägung der Details am größten und gleich null an den
// Polen:
float DetailIntensity = 1.0-abs(gs_TexCoord[4].x);

// Die Detail Map wrappen wir im Vergleich zur Surface Map zwanzig Mal

// auf unser Model:
vec4 DetailColor = texture(DetailTexture, 20.0*gs_TexCoord[0].st);

// In jedem Farbkanal der Detail Map ist eine separate Grausufen Detail Map
// gespeichert:
float Detail1 = min(0.25, DetailIntensity*SurfaceColor.r)*DetailColor.r;
float Detail2 = min(0.25, DetailIntensity*SurfaceColor.g)*DetailColor.g;
float Detail3 = min(0.25, DetailIntensity*SurfaceColor.b)*DetailColor.b;

vec4 DetailResult = vec4(Detail1, Detail1, Detail1, 1.0)+
                    vec4(Detail2, Detail2, Detail2, 1.0)+
                    vec4(Detail3, Detail3, Detail3, 1.0);

// neue Oberflächendetails mit der SurfaceColor kombinieren:
SurfaceColor = 0.5*(SurfaceColor+DetailResult) +
               0.5*SurfaceColor*DetailResult;



Hinweis:
Für die Ausführung dieses Programmbeispiels muss der Treiber Ihrer Grafikkarte die OpenGL Version 3.3 unterstützen.

Visual C++ 2010: DemoWithOpenGL2010_Tut13