CanvasItem 著色器

畫布組件著色器用於繪製Godot中的所有二維元素. 這包括從畫布組件繼承的所有節點, 以及所有圖形化使用者介面元素.

畫布元件著色器比 空間著色器 包含更少的內建變數和功能, 但它們與頂點, 片段和光處理器功能保持相同的基本結構.

算繪模式

算繪模式

說明

blend_mix

混合混合模式(Alpha 為透明度),預設。

blend_add

加法混合模式。

blend_sub

減法混合模式。

blend_mul

乘法混合模式。

blend_premul_alpha

預乘 Alpha 混合模式。

blend_disabled

禁用混合,值(包括 Alpha)會按原樣寫入。

unshaded

結果只使用反照率。材質中不會發生照明/陰影。

light_only

僅在光通過時繪製.

skip_vertex_transform

VERTEX/NORMAL/等需要在頂點函式中手動轉換.

world_vertex_coords

VERTEX/NORMAL 等是以世界座標而不是局部座標修改的。

內建變數

標記為 in 的值為唯讀。標記為 out 的值可以選擇寫入,且不一定包含合理的預設值。標記為 inout 的值則有預設值,可以選擇寫入。取樣器(sampler)無法寫入,因此未標註。

並非所有內建變數都能在所有處理函式中使用。若要在 fragment() 函式中存取頂點階段內建變數,可以利用 varying。同理,若需在 light() 函式中存取片段階段的內建變數,也請使用 varying。

全域內建變數

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

內建變數

說明

in float TIME

自引擎啟動以來的全域時間(秒)。每 3,600 秒會重設(可透過 rollover 設定變更)。該值會受到 time_scale 影響,但不受暫停影響。如果你需要不受 time_scale 影響的 TIME,請自訂 全域著色器 uniform 並於每幀更新。

in float PI

常數 PI(3.141592),為圓周長與直徑的比值,也是一半圈的弧度數。

in float TAU

常數 TAU(6.283185),等於 PI * 2,也是一整圈的弧度數。

in float E

常數 E(2.718281),歐拉數,也是自然對數的底數。

頂點階段內建變數

頂點資料( VERTEX )是以局部空間(像素座標, 相對於相機)呈現. 如果不寫入, 這些值將不會被修改, 並按其來時的樣子傳遞.

使用者可以禁用內建的modelview變換(以後仍然會發生投影), 並通過以下程式碼手動完成:

shader_type canvas_item;
render_mode skip_vertex_transform;

void vertex() {

    VERTEX = (MODEL_MATRIX * vec4(VERTEX, 0.0, 1.0)).xy;
}

其他內建程式, 如UV和COLOR, 如果沒有修改, 也會傳遞給片段函式.

在產生實體(instancing)時,INSTANCE_CUSTOM 變數包含自訂實例資料。用於粒子時內容通常如下:

  • x:旋轉角度,單位為弧度。

  • y:生命週期進度階段(0.0 ~ 1.0)。

  • z:動畫影格索引。

內建變數

說明

in mat4 MODEL_MATRIX

局部空間到世界空間的變換。世界空間是您通常在編輯器中使用的座標。

in mat4 CANVAS_MATRIX

世界空間到畫布空間的變換。在畫布空間中,原點是螢幕的左上角,座標範圍從 (0, 0) 到視窗大小。

in mat4 SCREEN_MATRIX

畫布空間到剪輯空間。在剪輯空間中,座標範圍從 (-1.0, -1.0)(1.0, 1.0)

in int INSTANCE_ID

產生實體(instancing)時的實例 ID。

in vec4 INSTANCE_CUSTOM

實例自訂資料.

in bool AT_LIGHT_PASS

總是 false.

in vec2 TEXTURE_PIXEL_SIZE

預設 2D 紋理的標準化像素大小。對於紋理大小為 64x32px 的 Sprite,TEXTURE_PIXEL_SIZE = vec2(1/64, 1/32)

inout vec2 VERTEX

頂點, 在圖像空間.

in int VERTEX_ID

目前頂點在頂點緩衝區中的索引。

inout vec2 UV

標準化紋理座標。範圍從 0 到 1。

inout vec4 COLOR

頂點圖元的顏色乘以 CanvasItem 的 modulate,再乘以 CanvasItem 的 self_modulate

inout float POINT_SIZE

點繪圖的點大小.

in vec4 CUSTOM0

來自頂點原始資料的自訂值。

in vec4 CUSTOM1

來自頂點原始資料的自訂值。

片段階段內建變數

COLOR 與 TEXTURE

內建變數 COLOR 有以下幾種用途:

  • vertex() 函式中,COLOR 包含來自頂點圖元的顏色,乘以 CanvasItem 的 modulate,再乘以 CanvasItem 的 self_modulate

  • fragment() 函式中,輸入值 COLOR 為上述顏色再乘以預設 TEXTURE 的顏色(若有設定)。

  • fragment() 函式中,COLOR 也是最終的輸出值。

某些節點(如 Sprite2D)預設會顯示一張材質,例如 texture。使用自訂的 fragment() 函式時,您有數種方式可以取樣該材質。

若只需讀取預設材質的內容,忽略頂點 COLOR

void fragment() {
  COLOR = texture(TEXTURE, UV);
}

若需讀取預設材質內容並乘以頂點 COLOR

void fragment() {
  // Equivalent to an empty fragment() function, since COLOR is also the output variable.
  COLOR = COLOR;
}

若需在 fragment() 中只讀取頂點 COLOR 而忽略主材質,必須將 COLOR 作為 varying 傳遞,然後在 fragment() 內讀取:

varying vec4 vertex_color;
void vertex() {
  vertex_color = COLOR;
}
void fragment() {
  COLOR = vertex_color;
}

NORMAL

同樣地,若在 CanvasTexture 使用法線貼圖,Godot 會預設將其值指派給內建的 NORMAL 變數。如果你使用的是 3D 專用的法線貼圖,顯示時會顛倒。要在你的著色器中使用,必須將其指派給 NORMAL_MAP 屬性,Godot 會自動轉換成 2D 專用並覆寫 NORMAL

NORMAL_MAP = texture(NORMAL_TEXTURE, UV).rgb;

內建變數

說明

in vec4 FRAGCOORD

像素中心的座標。在螢幕空間中,xy 表示視窗中的位置,如果沒有用 DEPTH,則 z 表示片段深度。原點位於左下角。

in vec2 SCREEN_PIXEL_SIZE

單個像素的大小. 等於解析度的倒數.

in vec2 POINT_COORD

所繪製點的座標。

sampler2D TEXTURE

預設的2D紋理.

in vec2 TEXTURE_PIXEL_SIZE

預設 2D 紋理的標準化像素大小。對於紋理大小為 64x32px 的 Sprite,TEXTURE_PIXEL_SIZE = vec2(1/64, 1/32)

in bool AT_LIGHT_PASS

總是 false.

sampler2D SPECULAR_SHININESS_TEXTURE

該物件的鏡面光澤紋理。

in vec4 SPECULAR_SHININESS

鏡面光澤顏色,從紋理取樣。

in vec2 UV

來自頂點功能的UV.

in vec2 SCREEN_UV

當前像素的螢幕 UV 座標。

sampler2D SCREEN_TEXTURE

已於 Godot 4 移除。請改用帶有 hint_screen_texturesampler2D

inout vec3 NORMAL

從 ** NORMAL_TEXTURE ** 中正常讀取. 可寫的.

輸入sampler2D NORMAL_TEXTURE

預設 2D 法線紋理。

out vec3 NORMAL_MAP

配置用於三維的法線貼圖, 以便在二維中使用. 如果使用, 則覆蓋 法線 .

out float NORMAL_MAP_DEPTH

用於縮放的法線貼圖深度.

inout vec2 VERTEX

法向量, 在視圖空間中.

inout vec2 SHADOW_VERTEX

與 VERTEX 相同,但可以寫入來改變陰影。

inout vec3 LIGHT_VERTEX

與“VERTEX”相同,但可以寫入來改變照明。 Z 分量代表高度。

inout vec4 COLOR

從頂點函式和輸出片段顏色. 如果未使用, 將設定為 紋理 顏色.

燈光階段內建變數

光處理器函式在 Godot 4.x 中的運作方式與在 Godot 3.x 中的工作方式不同。在 Godot 4.x 中,所有照明都是在常規繪製過程中完成的。換句話說,Godot 不再為每個光重新繪製物體。

光照處理器功能在 2D 中與在 3D 中工作不同。在 CanvasItem 著色器中,這個著色器會為被繪製的物件呼叫一次,然後再為每一束接觸場景中該物體的光呼叫一次。如果您不希望該物件發生任何光傳遞,請使用 render_mode unshaded。如果您只想讓光通過該物件,使用 render_mode light_only;當您只想讓被光覆蓋的物件可見時,這是非常有用的。

如果你定義了 light() 函式,即使該函式是空的,也會取代內建的光照函式。

以下是考慮 CanvasItem 法線貼圖的燈光著色器範例:

void light() {
  float cNdotL = max(0.0, dot(NORMAL, LIGHT_DIRECTION));
  LIGHT = vec4(LIGHT_COLOR.rgb * COLOR.rgb * LIGHT_ENERGY * cNdotL, LIGHT_COLOR.a);
}

內建變數

說明

in vec4 FRAGCOORD

像素中心的座標。在螢幕空間中,xy 表示視窗中的位置,如果沒有用 DEPTH,則 z 表示片段深度。原點位於左下角。

in vec3 NORMAL

輸入法線。

in vec4 COLOR

輸入顏色. 這是片段函式的輸出(如果在著色器的任何函式中沒有使用 MODULATE , 則應用最終調變).

in vec2 UV

來自頂點函式的UV, 相當於片段函式中的UV.

sampler2D TEXTURE

CanvasItem使用的目前紋理.

in vec2 TEXTURE_PIXEL_SIZE

預設 2D 紋理的標準化像素大小。對於紋理大小為 64x32px 的 Sprite,TEXTURE_PIXEL_SIZE = vec2(1/64, 1/32)

in vec2 SCREEN_UV

當前像素的螢幕 UV 座標。

in vec2 POINT_COORD

點精靈的UV.

in vec4 LIGHT_COLOR

Light2DColor。若為 PointLight2D,則再乘以該光源的 texture

in float LIGHT_ENERGY

Light2DEnergy multiplier

in vec3 LIGHT_POSITION

燈光在螢幕空間中 Light2D 的位置。如果使用的是 DirectionalLight2D ,則始終為 (0.0, 0.0, 0.0)

in vec3 LIGHT_DIRECTION

Light2D 在螢幕空間中的方向。

in bool LIGHT_IS_DIRECTIONAL

如果 true 代表是 DirectionalLight2D .

in vec3 LIGHT_VERTEX

world_position 可用於頂點函式或片段函式.

inout vec4 LIGHT

Light2D 的輸出顏色.

in vec4 SPECULAR_SHININESS

鏡面光澤度,在物件紋理中設定。

out vec4 SHADOW_MODULATE

將此時投射的陰影乘以該顏色。

函式

也實作了一些附加函式來對自動產生的有符號距離場紋理進行取樣。這些函式可用於 CanvasItem 著色器的片段和燈光函式。

帶符號的距離場是從場景中存在的 LightOccluder2D 節點產生的,並且啟用了 SDF Collision 屬性(這是預設)。有關更多信息,請參閱 2D 燈光和陰影 說明文件。

函式

說明

float texture_sdf (vec2 sdf_pos)

執行2D紋理讀取。

vec2 texture_sdf_normal (vec2 sdf_pos)

預設 2D 法線紋理。

vec2 sdf_to_screen_uv (vec2 sdf_pos)

將 SDF 轉換為螢幕 UV。

vec2 screen_uv_to_sdf (vec2 uv)

轉換螢幕UV為SDF。