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 影響的 |
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 |
畫布空間到剪輯空間。在剪輯空間中,座標範圍從 |
in int INSTANCE_ID |
產生實體(instancing)時的實例 ID。 |
in vec4 INSTANCE_CUSTOM |
實例自訂資料. |
in bool AT_LIGHT_PASS |
總是 |
in vec2 TEXTURE_PIXEL_SIZE |
預設 2D 紋理的標準化像素大小。對於紋理大小為 64x32px 的 Sprite,TEXTURE_PIXEL_SIZE = |
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 |
像素中心的座標。在螢幕空間中, |
in vec2 SCREEN_PIXEL_SIZE |
單個像素的大小. 等於解析度的倒數. |
in vec4 REGION_RECT |
精靈區域的可見範圍,格式為 |
in vec2 POINT_COORD |
所繪製點的座標。 |
sampler2D TEXTURE |
預設的2D紋理. |
in vec2 TEXTURE_PIXEL_SIZE |
預設 2D 紋理的標準化像素大小。對於紋理大小為 64x32px 的 Sprite,TEXTURE_PIXEL_SIZE = |
in bool AT_LIGHT_PASS |
總是 |
sampler2D SPECULAR_SHININESS_TEXTURE |
該物件的鏡面光澤紋理。 |
in vec4 SPECULAR_SHININESS |
鏡面光澤顏色,從紋理取樣。 |
in vec2 UV |
來自 |
in vec2 SCREEN_UV |
當前像素的螢幕 UV 座標。 |
sampler2D SCREEN_TEXTURE |
已於 Godot 4 移除。請改用帶有 |
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 |
像素中心的座標。在螢幕空間中, |
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 = |
in vec2 SCREEN_UV |
當前像素的螢幕 UV 座標。 |
in vec2 POINT_COORD |
點精靈的UV. |
in vec4 LIGHT_COLOR |
Light2D 的 Color。若為 PointLight2D,則再乘以該光源的 texture。 |
in float LIGHT_ENERGY |
|
in vec3 LIGHT_POSITION |
燈光在螢幕空間中 Light2D 的位置。如果使用的是 DirectionalLight2D ,則始終為 |
in vec3 LIGHT_DIRECTION |
Light2D 在螢幕空間中的方向。 |
in bool LIGHT_IS_DIRECTIONAL |
如果 |
in vec3 LIGHT_VERTEX |
|
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。 |