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.
Checking the stable version of the documentation...
GLSL 轉換為 Godot 著色器
本文件說明 Godot 著色器語言與 GLSL 之間的差異,並提供實用建議,協助你將來自其他來源(如 Shadertoy、The Book of Shaders)的著色器移植到 Godot。
如需 Godot 著色器語言的詳細資訊,請參考 著色器語言 參考資料。
GLSL
Godot 採用以 GLSL 為基礎的著色器語言,並加入了一些便利性功能。因此,GLSL 中大多數功能都能在 Godot 著色器語言中使用。
著色器程式
在 GLSL 中,每個著色器都是一個獨立的程式:一個用於頂點著色器,一個用於片段著色器。而在 Godot 中,你只需要寫一個著色器檔案,裡面可以包含 vertex 和/或 fragment 函式。如果你只撰寫其中一個,Godot 會自動補足另一個。
Godot 允許你在同一個著色器檔案中定義頂點與片段著色器,因此 uniform 變數與函式可以共用。在 GLSL 中,頂點與片段程式無法共用變數,除非透過 varying 傳遞。
頂點屬性
在 GLSL 中,你可以使用 attribute 傳遞每個頂點的資訊,並且彈性決定提供的內容。在 Godot 中,則有一套固定的輸入屬性,包括 VERTEX``(位置)、``COLOR、UV、UV2、NORMAL。各種著色器所支援的頂點屬性,請參考文件的著色器語言參考章節。
gl_Position
gl_Position 由頂點著色器指定,代表頂點在裁剪空間的最終位置。通常在 GLSL 中,模型空間的頂點位置會透過 position attribute 傳入,並由你自行負責將其從模型空間轉換至裁剪空間。
在 Godot 中,VERTEX 代表 vertex 函式開頭時的模型空間座標。你執行自訂的 vertex 函式後,Godot 會自動將結果轉換到裁剪空間。如果你想跳過從模型到視圖空間的轉換,可以將 render_mode 設為 skip_vertex_transform。若要完全跳過所有變換,則除了設定 render_mode 為 skip_vertex_transform 外,還需將 PROJECTION_MATRIX 設為 mat4(1.0),使從視圖到裁剪空間的最終變換失效。
Varying(變量)
Varying 是一種可以從頂點著色器傳遞到片段著色器的變數。在現代 GLSL(3.0 以上)中,varying 以 in 和 out 關鍵字定義。從頂點著色器輸出的變數以 out 宣告,在片段著色器中以 in 接收。
主函式
在 GLSL 中,每個著色器程式都像是一個獨立的 C 語言程式,主入口為 main。若你要複製頂點著色器,請將 main 改名為 vertex;如果是片段著色器,則改名為 fragment。
巨集
Godot 著色器前處理器 支援以下巨集:
#define/#undef#if、#elif、#else、#endif、defined()、#ifdef、#ifndef#include``(只允許 ``.gdshaderinc檔案,最多遞迴 25 層)#pragma disable_preprocessor,停用本檔案剩餘部分的前處理
變數
GLSL 有許多內建的硬編碼變數。這些變數不是 uniform,因此無法從主程式端編輯。
變數 |
型別 |
對應 |
說明 |
|---|---|---|---|
gl_FragColor |
out vec4 |
COLOR |
每個像素的輸出顏色。 |
gl_FragCoord |
vec4 |
FRAGCOORD |
用於全螢幕四邊形。若為較小的四邊形,請改用 UV。 |
gl_Position |
vec4 |
VERTEX |
頂點的位置,由頂點著色器輸出。 |
gl_PointSize |
浮點數 |
POINT_SIZE |
點基元的大小。 |
gl_PointCoord |
vec2 |
POINT_COORD |
繪製點基元時在點上的位置。 |
gl_FrontFacing |
bool |
FRONT_FACING |
若為基元正面則為 true。 |
座標
GLSL 的 gl_FragCoord 與 Godot 著色器語言的 FRAGCOORD 使用相同的座標系統。若在 Godot 中使用 UV,y 座標會上下顛倒。
精度
在 GLSL 中,你可用 precision 關鍵字於著色器頂端設定型別(如 float 或 int)的精度。Godot 則允許你在變數型別前加上 lowp、mediump、highp,針對個別變數指定精度。詳情請見 著色器語言 參考資料。
Shadertoy
Shadertoy 是一個讓你輕鬆撰寫片段著色器並創作各種酷炫視覺效果的網站,像是這個 pure magic。
Shadertoy 並未讓使用者完全控制著色器。它會處理所有輸入和 uniform,只允許你編寫片段著色器。
型別
Shadertoy 採用 WebGL 規範,因此 GLSL 版本略有不同。不過它仍支援一般型別、常數及巨集。
mainImage
Shadertoy 著色器的主要進入點是 mainImage 函式。此函式有兩個參數 fragColor 和 fragCoord,分別對應 Godot 的 COLOR 與 FRAGCOORD。這些參數在 Godot 會自動處理,因此移植時只需將 mainImage 內的內容複製到 fragment 函式即可。
變數
為了讓編寫片段著色器更加簡單,Shadertoy 會自動將許多有用的主程式資訊傳遞進片段著色器。有些變數在 Godot 沒有對應,因為 Godot 預設不提供這些內容。但這沒問題,Godot 允許你自訂 uniform。對於表格中標註為「提供 Uniform」的變數,請自行新增 uniform。說明欄位會提示你可以用哪些內容作為替代。
變數 |
型別 |
對應 |
說明 |
|---|---|---|---|
fragColor |
out vec4 |
COLOR |
每個像素的輸出顏色。 |
fragCoord |
vec2 |
FRAGCOORD.xy |
用於全螢幕四邊形。若為較小的四邊形,請改用 UV。 |
iResolution |
vec3 |
1.0 / SCREEN_PIXEL_SIZE |
也可以手動傳入。 |
iTime |
浮點數 |
TIME |
著色器開始執行後經過的時間。 |
iTimeDelta |
浮點數 |
提供Uniform |
上一影格的渲染時間。 |
iFrame |
浮點數 |
提供Uniform |
影格編號。 |
iChannelTime[4] |
浮點數 |
提供Uniform |
該紋理啟動以來經過的時間。 |
iMouse |
vec4 |
提供Uniform |
滑鼠的像素座標位置。 |
iDate |
vec4 |
提供Uniform |
目前日期,單位為秒。 |
iChannelResolution[4] |
vec3 |
1.0 / TEXTURE_PIXEL_SIZE |
特定紋理的解析度。 |
iChanneli |
Sampler2D |
TEXTURE |
Godot 只提供一個內建;你可以自行新增更多。 |
座標
fragCoord 的行為與 GLSL 的 gl_FragCoord 及 Godot 的 FRAGCOORD 相同。
The Book of Shaders(著色之書)
與 Shadertoy 類似,The Book of Shaders 讓你可以在瀏覽器中互動式編輯片段著色器,但只能使用預設的 uniform 無法新增自訂 uniform。
若需進一步瞭解如何將著色器移植到不同框架,The Book of Shaders 在 這一頁 有相關說明。
型別
The Book of Shaders 採用 WebGL 規範,因此使用的 GLSL 版本略有不同。不過一般型別、常數與巨集皆有支援。
主函式
Book of Shaders 的片段著色器入口點為 main,與 GLSL 相同。請將 main 函式內容完整複製到 Godot 的 fragment 函式中。
變數
The Book of Shaders 比 Shadertoy 更貼近標準 GLSL,且預設提供的 uniform 也較少。
變數 |
型別 |
對應 |
說明 |
|---|---|---|---|
gl_FragColor |
out vec4 |
COLOR |
每個像素的輸出顏色。 |
gl_FragCoord |
vec4 |
FRAGCOORD |
用於全螢幕四邊形。若為較小的四邊形,請改用 UV。 |
u_resolution |
vec2 |
1.0 / SCREEN_PIXEL_SIZE |
也可以手動傳入。 |
u_time |
浮點數 |
TIME |
著色器開始執行後經過的時間。 |
u_mouse |
vec2 |
提供Uniform |
滑鼠的像素座標位置。 |
座標
The Book of Shaders 使用與 GLSL 相同的座標系統。