Attention: Here be dragons

This is the latest (unstable) version of this documentation, which may document features not available in or compatible with released stable versions of Godot.

天空著色器

天空著色器是一種特殊類型的著色器,用於繪製天空背景及更新用於基於影像照明(IBL)的輻射立方體貼圖。天空著色器僅有一個處理函式,即 sky() 函式。

天空著色器會在三個地方被使用。

  • 首先,當你在場景中選擇使用天空作為背景時,天空著色器會用來繪製天空。

  • 其次,當使用天空作為環境光或反射來源時,天空著色器會用於更新輻射立方體貼圖。

  • 第三,天空著色器會用於算繪較低解析度的子通道,這些結果可用於高解析度背景或立方體貼圖通道。

總結來說,天空著色器每幀最多可執行六次。但實際上通常會少很多,因為輻射立方體貼圖不需每幀更新,而且不是所有子通道都會被用到。你可以透過檢查 AT_*_PASS 布林值來根據呼叫位置調整著色器行為。例如:

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

當用天空著色器繪製背景時,會對螢幕上所有未被遮蔽的片段呼叫著色器。但對於背景的子通道,會對該子通道每個像素呼叫一次著色器。

當使用天空著色器來更新輻射立方體貼圖時,會針對立方體貼圖內每個像素執行一次著色器。但只有當輻射立方體貼圖需要更新時才會呼叫著色器。只要著色器的任何參數有更新時,立方體貼圖就需要重新計算。例如,如果著色器中有使用 TIME,那麼輻射立方體貼圖將每幀都重新計算。以下情況會強制觸發輻射立方體貼圖更新:

  • 使用了 TIME

  • 使用了 POSITION 並且相機位置發生變化。

  • 如果有使用任何 LIGHTX_* 屬性,且任何 DirectionalLight3D 發生變化。

  • 如果著色器中的任何 uniform 參數有更動。

  • 若螢幕尺寸被調整,且有使用到任何子通道。

盡量避免不必要地更新輻射立方體貼圖。如果確實需要每幀更新輻射立方體貼圖,請確認你的 Sky 處理模式 已設為 PROCESS_MODE_REALTIME

請注意,處理模式 僅影響輻射立方體貼圖的算繪。可見的天空仍會針對每個像素呼叫片段著色器。如果你的片段著色器很複雜,這會造成顯著的算繪負擔。如果天空是靜態的(如前述條件),或變化速度很慢,其實無需每幀都執行完整片段著色器。你可以將完整天空算繪到輻射立方體貼圖,再在顯示可見天空時直接讀取此貼圖。若天空完全靜態,只需要算繪一次即可。

以下程式碼會將完整天空算繪到輻射立方體貼圖,並在顯示可見天空時從該貼圖讀取:

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

這樣一來,複雜的計算只會發生在立方體貼圖階段。你可以調整 天空處理模式輻射貼圖尺寸,在效能與視覺品質間取得理想平衡。

算繪模式

子通道可讓你以較低解析度進行較昂貴的計算,加速著色器運算。例如,以下程式碼會以比天空其餘部分更低的解析度算繪雲層:

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

算繪模式

說明

use_half_res_pass

允許著色器寫入及存取半解析度通道。

use_quarter_res_pass

允許著色器寫入及存取四分之一解析度通道。

disable_fog

啟用後,霧效將不會影響天空。

內建變數

標記為 in 的值為唯讀。標記為 out 的值可寫入,但不一定有合理初始值。取樣器(sampler)無法寫入,因此未標記。

全域內建變數

全域內建變數可於任何地方使用,包括自訂函式中。

有 4 個 LIGHTX 燈光,可分別以 LIGHT0LIGHT1LIGHT2LIGHT3 存取。

內建變數

說明

in float TIME

Global time since the engine has started, in seconds. It repeats after every 3,600 seconds (which can be changed with the rollover setting). It's affected by time_scale but not by pausing. If you need a TIME variable that is not affected by time scale, add your own global shader uniform and update it each frame.

in vec3 POSITION

相機在世界座標中的位置。

samplerCube RADIANCE

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

in bool AT_HALF_RES_PASS

true when rendering to the half resolution pass.

in bool AT_QUARTER_RES_PASS

true when rendering to the quarter resolution pass.

in bool AT_CUBEMAP_PASS

true when rendering to the radiance cubemap.

in bool LIGHTX_ENABLED

LIGHTX 在場景中且可見則為 true。若為 false,其他燈光屬性可能是無效值。

in float LIGHTX_ENERGY

LIGHTX 的能量乘數。

in vec3 LIGHTX_DIRECTION

LIGHTX 面向的方向。

in vec3 LIGHTX_COLOR

LIGHTX 的顏色。

in float LIGHTX_SIZE

天空中 LIGHTX 的角直徑,以弧度表示。作為參考,太陽在地球上看起來約為 0.0087 弧度(0.5 度)。

in float PI

A PI constant (3.141592). The ratio of a circle's circumference to its diameter and the number of radians in a half turn.

in float TAU

A TAU constant (6.283185). Equivalent to PI * 2 and the number of radians in a full turn.

in float E

An E constant (2.718281). Euler's number, the base of the natural logarithm.

天空內建變數

內建變數

說明

in vec3 EYEDIR

Normalized direction of the current pixel. Use this as your basic direction for procedural effects.

in vec2 SCREEN_UV

Screen UV coordinate for the current pixel. Used to map a texture to the full screen.

in vec2 SKY_COORDS

球面 UV。用於將全景紋理貼圖到天空。

in vec4 HALF_RES_COLOR

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

in vec4 QUARTER_RES_COLOR

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

out vec3 COLOR

輸出顏色。

out float ALPHA

輸出的 alpha 值,只能在子通道中使用。

out vec4 FOG