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 相同的座標系統。