Sky-Shader
Sky-Shader sind eine spezielle Art von Shader, die zum Zeichnen von Himmelshintergründen und zum Aktualisieren von Strahlungs-Cubemaps verwendet werden, die für die bildbasierte Beleuchtung (IBL) eingesetzt werden. Himmels-Shader haben nur eine Verarbeitungsfunktion, die Funktion Sky().
Es gibt drei Stellen, an denen der Sky-Shader verwendet wird.
Zunächst wird der Sky-Shader verwendet, um den Himmel zu zeichnen, wenn Sie einen Himmel als Hintergrund in Ihrer Szene ausgewählt haben.
Zweitens wird der Sky-Shader verwendet, um die Radiance-Cubemap zu aktualisieren, wenn der Himmel für Umgebungsfarben oder Reflexionen verwendet wird.
Drittens wird der Sky-Shader verwendet, um die niedriger aufgelösten Subpasses zu zeichnen, die im hochauflösenden Hintergrund oder Cubemap-Pass verwendet werden können.
Insgesamt bedeutet dies, dass der Sky-Shader bis zu sechsmal pro Frame ausgeführt werden kann. In der Praxis wird es jedoch viel weniger sein, da die Radiance Cubemap nicht bei jedem Frame aktualisiert werden muss und nicht alle Subpasses verwendet werden. Man kann das Verhalten des Shaders ändern, je nachdem, wo er aufgerufen wird, indem man die AT_*_PASS Booleschen Werte überprüft. Zum Beispiel:
shader_type sky;
void sky() {
if (AT_CUBEMAP_PASS) {
// Sets the radiance cubemap to a nice shade of blue instead of doing
// expensive sky calculations
COLOR = vec3(0.2, 0.6, 1.0);
} else {
// Do expensive sky calculations for background sky only
COLOR = get_sky_color(EYEDIR);
}
}
Wenn Sie den Sky-Shader verwenden, um einen Hintergrund zu zeichnen, wird der Shader für alle nicht verdeckten Fragmente auf dem Bildschirm aufgerufen. Bei den Unter-Durchläufen des Hintergrunds wird der Shader jedoch für jedes Pixel des Unter-Durchlaufs aufgerufen.
Wenn Sie den Sky-Shader zur Aktualisierung der Radiance Cubemap verwenden, wird der Sky-Shader für jedes Pixel in der Cubemap aufgerufen. Andererseits wird der Shader nur aufgerufen, wenn die Radiance Cubemap aktualisiert werden muss. Die Radiance Cubemap muss aktualisiert werden, wenn einer der Shader-Parameter aktualisiert wird. Wenn zum Beispiel TIME im Shader verwendet wird, dann wird die Radiance Cubemap bei jedem Frame aktualisiert. Die folgende Liste von Änderungen erzwingt eine Aktualisierung der Radiance Cubemap:
TIMEwird verwendet.POSITIONwird verwendet und die Kameraposition ändert sich.Wenn irgendwelche
LIGHTX_*Propertys verwendet werden und sich irgendwelche DirectionalLight3D ändern.Wenn ein Uniform im Shader geändert wird.
Wenn die Größe des Bildschirms geändert wird und einer der Unter-Durchläufe verwendet wird.
Try to avoid updating the radiance cubemap needlessly. If you do need to update the radiance cubemap each frame, make sure your Sky process mode is set to PROCESS_MODE_REALTIME.
Beachten Sie, dass der Prozessierungmodus nur das Rendering der Radiance Cubemap beeinflusst. Der sichtbare Himmel wird immer durch den Aufruf des Fragment-Shaders für jedes Pixel gerendert. Bei komplexen Fragment-Shadern kann dies zu einem hohen Rendering-Overhead führen. Wenn der Himmel statisch ist (die oben genannten Bedingungen sind erfüllt) oder sich nur langsam ändert, ist es nicht erforderlich, den vollständigen Fragment-Shader für jedes Bild aufzurufen. Dies kann vermieden werden, indem der gesamte Himmel in die Radiance Cubemap gerendert und beim Rendern des sichtbaren Himmels aus dieser Cubemap gelesen wird. Bei einem völlig statischen Himmel bedeutet dies, dass er nur einmal gerendert werden muss.
Der folgende Code rendert den gesamten Himmel in die Radiance Cubemap und liest aus dieser Cubemap den sichtbaren Himmel aus:
shader_type sky;
void sky() {
if (AT_CUBEMAP_PASS) {
vec3 dir = EYEDIR;
vec4 col = vec4(0.0);
// Complex color calculation
COLOR = col.xyz;
ALPHA = 1.0;
} else {
COLOR = texture(RADIANCE, EYEDIR).rgb;
}
}
Auf diese Weise finden die komplexen Berechnungen nur im Cubemap-Durchlauf statt, der durch Einstellen des Prozessmodus und der Radianzgröße optimiert werden kann, um die gewünschte Balance zwischen Performance und visueller Wiedergabetreue zu erreichen.
Render-Modi
Mit Unter-Durchläufen können Sie aufwändigere Berechnungen mit einer niedrigeren Auflösung durchführen, um Ihre Shader zu beschleunigen. Der folgende Code rendert zum Beispiel die Wolken mit einer niedrigeren Auflösung als den Rest des Himmels:
shader_type sky;
render_mode use_half_res_pass;
void sky() {
if (AT_HALF_RES_PASS) {
// Run cloud calculation for 1/4 of the pixels
vec4 color = generate_clouds(EYEDIR);
COLOR = color.rgb;
ALPHA = color.a;
} else {
// At full resolution pass, blend sky and clouds together
vec3 color = generate_sky(EYEDIR);
COLOR = color + HALF_RES_COLOR.rgb * HALF_RES_COLOR.a;
}
}
Rendermodus |
Beschreibung |
|---|---|
use_half_res_pass |
Ermöglicht dem Shader das Schreiben in und den Zugriff auf den Halbe-Auflösungs-Durchlauf. |
use_quarter_res_pass |
Ermöglicht dem Shader das Schreiben in und den Zugriff auf den Viertel-Auflösungs-Durchlauf. |
disable_fog |
Wenn er verwendet wird, hat der Nebel keine Auswirkungen auf den Himmel. |
Built-ins
Values marked as in are read-only. Values marked as out can optionally
be written to and will not necessarily contain sensible values. Samplers cannot
be written to so they are not marked.
Globale Built-ins
Globale Built-ins sind überall verfügbar, auch in benutzerdefinierten Funktionen.
Es gibt 4 LIGHTX-Lichter, die als LIGHT0, LIGHT1, LIGHT2 und LIGHT3 angesprochen werden.
Built-in |
Beschreibung |
|---|---|
in float TIME |
Global time since the engine has started, in seconds. It repeats after every |
in vec3 POSITION |
Kamera-Position im World-Space. |
samplerCube RADIANCE |
Radiance Cubemap. Kann nur während des Hintergrund-Durchlaufs gelesen werden. Prüfen Sie |
in bool AT_HALF_RES_PASS |
|
in bool AT_QUARTER_RES_PASS |
|
in bool AT_CUBEMAP_PASS |
|
in bool LIGHTX_ENABLED |
|
in float LIGHTX_ENERGY |
Energiemultiplikator für |
in vec3 LIGHTX_DIRECTION |
Richtung, in die |
in vec3 LIGHTX_COLOR |
Farbe von |
in float LIGHTX_SIZE |
Winkeldurchmesser von |
in float PI |
Eine |
in float TAU |
Eine |
in float E |
Eine |
Himmels-Built-ins
Built-in |
Beschreibung |
|---|---|
in vec3 EYEDIR |
Normalisierte Richtung des aktuellen Pixels. Verwenden Sie dies als Grundrichtung für prozedurale Effekte. |
in vec2 SCREEN_UV |
Bildschirm-UV-Koordinate für das aktuelle Pixel. Wird verwendet, um eine Textur auf den gesamten Bildschirm abzubilden. |
in vec2 SKY_COORDS |
Kugel-UV. Wird verwendet, um eine Panoramatextur auf den Himmel abzubilden. |
in vec4 HALF_RES_COLOR |
Farbwert des entsprechenden Pixels aus dem Halbe-Auflösungs-Durchlauf. Verwendet einen linearen Filter. |
in vec4 QUARTER_RES_COLOR |
Farbwert des entsprechenden Pixels aus dem Viertel-Auflösungs-Durchlauf. Verwendet einen linearen Filter. |
out vec3 COLOR |
Farbe der Ausgabe. |
out float ALPHA |
Alphawert der Ausgabe, kann nur in Unterdurchläufen verwendet werden. |
out vec4 FOG |