Shader di cielo

Gli shader di cielo sono un tipo speciale di shader utilizzato per disegnare sfondi cielo e per aggiornare le cubemap di radianza, le quali sono utilizzate per l'illuminazione basata su immagini (IBL). Gli shader di cielo hanno una sola funzione di elaborazione, la funzione sky().

Lo shader di cielo è utilizzato in tre situazioni.

  • First the sky shader is used to draw the sky when you have selected to use a Sky as the background in your scene.

  • Secondo, lo shader di cielo è utilizzato per aggiornare la cubemap di radianza quando si utilizza il cielo per il colore ambientale o per i riflessi.

  • Terzo, lo shader di cielo è utilizzato per disegnare i sotto-passaggi a bassa risoluzione che si possono utilizzare nello sfondo ad alta risoluzione o nel passaggio di cubemap.

In totale, ciò significa che lo shader di cielo può essere eseguito fino a sei volte per frame, tuttavia, in pratica, il numero di ripetizioni sarà molto inferiore, perché la cubemap di radianza non deve essere aggiornata a ogni frame e non saranno utilizzati tutti i sotto-passaggi. È possibile modificare il comportamento dello shader in base a dove è richiamato, verificando i valori booleani AT_*_PASS. Per esempio:

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);
    }
}

Quando si utilizza lo shader di cielo per disegnare uno sfondo, lo shader sarà richiamato per tutti i frammenti non occlusi sullo schermo. Tuttavia, per i sotto-passaggi dello sfondo, lo shader sarà richiamato per ogni pixel del sotto-passaggio.

When using the sky shader to update the radiance cubemap, the sky shader will be called for every pixel in the cubemap. On the other hand, the shader will only be called when the radiance cubemap needs to be updated. The radiance cubemap needs to be updated when any of the shader parameters are updated. For example, if TIME is used in the shader, then the radiance cubemap will update every frame. The following list of changes force an update of the radiance cubemap:

  • TIME è utilizzato.

  • POSITION è utilizzato e la posizione della telecamera cambia.

  • Se una qualunque proprietà LIGHTX_* viene utilizzata e un qualunque DirectionalLight3D viene modificato.

  • Se un'uniforme viene modificata nello shader.

  • Se lo schermo viene ridimensionato e uno dei sotto-passaggi viene utilizzato.

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.

Note that the process mode only affects the rendering of the radiance cubemap. The visible sky is always rendered by calling the fragment shader for every pixel. With complex fragment shaders, this can result in a high rendering overhead. If the sky is static (the conditions listed above are met) or changes slowly, running the full fragment shader every frame is not needed. This can be avoided by rendering the full sky into the radiance cubemap, and reading from this cubemap when rendering the visible sky. With a completely static sky, this means that it needs to be rendered only once.

The following code renders the full sky into the radiance cubemap and reads from that cubemap for displaying the visible sky:

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;
    }
}

This way, the complex calculations happen only in the cubemap pass, which can be optimized by setting the sky's process mode and the radiance size to get the desired balance between performance and visual fidelity.

Modalità di rendering

Subpasses allow you to do more expensive calculations at a lower resolution to speed up your shaders. For example the following code renders clouds at a lower resolution than the rest of the sky:

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;
    }
}

Modalità di rendering

Descrizione

use_half_res_pass

Allows the shader to write to and access the half resolution pass.

use_quarter_res_pass

Allows the shader to write to and access the quarter resolution pass.

disable_fog

If used, fog will not affect the sky.

Variabili integrate

I valori marcati come in sono di sola lettura. I valori marcati come out sono scrivibili facoltativamente e non contengono necessariamente valori sensati. I campionatori non sono scrivibili, quindi non sono marcati.

Variabili integrate globali

Le variabili integrate globali sono disponibili ovunque, comprese le funzioni personalizzate.

There are 4 LIGHTX lights, accessed as LIGHT0, LIGHT1, LIGHT2, and LIGHT3.

Integrato

Descrizione

in float TIME

Tempo globale dall'avvio del motore, in secondi. Si ripete ogni 3.600 secondi (che può essere modificato con l'impostazione rollover). È influenzato da time_scale ma non dalla pausa. Se è necessaria una variabile TIME che non sia influenzata dalla scala temporale, aggiungere il proprio uniforme di shader globale da aggiornare a ogni frame.

in vec3 POSITION

Posizione della telecamera, nello spazio mondiale.

samplerCube RADIANCE

Radiance cubemap. Can only be read from during background pass. Check !AT_CUBEMAP_PASS before using.

in bool AT_HALF_RES_PASS

true when rendering to half resolution pass.

in bool AT_QUARTER_RES_PASS

true when rendering to quarter resolution pass.

in bool AT_CUBEMAP_PASS

true durante il rendering della cubemap di radianza.

in bool LIGHTX_ENABLED

true if LIGHTX is visible and in the scene. If false, other light properties may be garbage.

in float LIGHTX_ENERGY

Moltiplicatore di energia per LIGHTX.

in vec3 LIGHTX_DIRECTION

Direzione verso cui LIGHTX è rivolto.

in vec3 LIGHTX_COLOR

Colore di LIGHTX.

in float LIGHTX_SIZE

Diametro angolare di LIGHTX nel cielo. Espresso in radianti. Per riferimento, il Sole dalla Terra è a circa 0,0087 radianti (0,5 gradi).

in float PI

Una costante PI (3.141592). Il rapporto tra la circonferenza di un cerchio e il suo diametro, e la quantità di radianti in mezzo giro.

in float TAU

Una costante TAU (6.283185). Equivalente a PI * 2 e alla quantità di radianti in un giro completo.

in float E

Una costante E (2.718281). Numero di Eulero e base del logaritmo naturale.

Sky built-ins

Integrato

Descrizione

in vec3 EYEDIR

Direzione normalizzata del pixel attuale. Da utilizzare come direzione di base per gli effetti procedurali.

in vec2 SCREEN_UV

Coordinate UV dello schermo per il pixel attuale. Utilizzata per mappare una texture a tutto schermo.

in vec2 SKY_COORDS

UV di sfera . Utilizzata per mappare una texture panoramica sul cielo.

in vec4 HALF_RES_COLOR

Color value of corresponding pixel from half resolution pass. Uses linear filter.

in vec4 QUARTER_RES_COLOR

Color value of corresponding pixel from quarter resolution pass. Uses linear filter.

out vec3 COLOR

Colore in uscita.

out float ALPHA

Valore alfa in output, può essere utilizzato solo nei sotto-passaggi.

out vec4 FOG