跳轉到內容

Mewa 使用者指南/使用自定義著色器擴充套件 Mewa

來自 Wikibooks,開放世界開放書籍

本章解釋如何使用自定義 GLSL 著色器擴充套件 Mewa。在 Mewa 中,GLSL 著色器由一個節點持有。

Mewa 的核心是一個指令碼引擎,它執行 Mewa 指令碼檔案。Mewa 指令碼是具有 .mw 副檔名的文字檔案。節點是透過執行指令碼建立的。

可用的指令碼在 節點選單 中列出。選單中顯示的名稱是指令碼的檔名。單擊選單條目將執行相應的指令碼。

節點庫按鈕

在建立 Mewa 節點時,最好檢視示例並修改它們。Mewa 指令碼檔案位於 指令碼目錄 中。開啟任何指令碼檔案,應用一些更改並執行它以觀察結果。

讓我們從一個簡單的指令碼開始。

在這個示例中,我們將建立一個指令碼,它將生成一個名為 MyImage 的新節點。要建立指令碼,請建立一個名為 MyImage.mw 的新文字檔案,並將下面的文字貼上到該檔案中。

// this is a mewa script that creates a node with a custom shader
shaderSource = "
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{  
    vec3 col = 0.5 + 0.5*cos( iTime + fragCoord.xyx + vec3(0,2,4) );
    fragColor = vec4(col,1.0);
}";

addShaderNode("MyImage", shaderSource);

上面的 Mewa 指令碼檔案包含 GLSL 著色器程式碼(在引號內)和一個 Mewa API 呼叫以建立 Mewa 節點。

著色器程式碼實現 mainImage() 函式。此函式對每個畫素呼叫一次。fragCoord 引數包含畫素座標(以歸一化座標表示)。fragCoord 值始終介於 0 到 1 之間,並覆蓋整個視口。每個畫素的輸出顏色儲存在 fragColor 中。

變數 iTime 是 Mewa 提供的一個 輸入變數


現在讓我們安裝它並執行它。

指令碼目錄

[編輯 | 編輯原始碼]
關於對話方塊視窗

Mewa 指令碼檔案位於一個目錄中,我們稱之為 指令碼目錄。它的位置取決於 Mewa 執行的平臺。

要查詢 指令碼目錄,請在 Mewa 的主視窗中單擊 。將開啟一個常規資訊視窗,顯示 指令碼目錄

執行指令碼

[編輯 | 編輯原始碼]

要執行我們新建立的指令碼,請透過單擊節點按鈕 開啟 節點選單。將顯示位於 指令碼目錄 中的所有指令碼的列表。

選擇 MyImage 指令碼

節點選單中顯示的名稱是指令碼的檔名。要啟動我們指令碼的執行,請單擊 MyImage 條目。一個名為 MyImage0 的節點將新增到節點圖中。單擊輸出按鈕(節點右側的方形按鈕)將開啟輸出視窗,顯示我們節點的輸出。見下圖截圖。

MyImage 節點及其輸出

著色器輸入

[編輯 | 編輯原始碼]

以下是 Mewa 向所有著色器提供的所有輸入變數的列表

型別 名稱 描述
vec3 iResolution 視口解析度(以畫素為單位)。z 是縱橫比(寬度/高度)
float iTime 播放時間(以秒為單位)
int iFrame 播放幀號
vec3 iChannelResolution0, iChannelResolution1 每個通道的輸入紋理解析度。z 是縱橫比(寬度/高度)
sampler2D iChannel0, iChannel1 輸入通道
vec4 iChannelRect0, iChannelRect1 紋理座標中的通道矩形。矩形以 vec4( 左,右,下,上 ) 表示。


新增節點輸入

[編輯 | 編輯原始碼]

在我們上面建立的 示例 中,結果節點沒有輸入。

要生成一個接受輸入影像的著色器節點,我們將變數 iChannel0 引入我們的著色器原始碼。

現在讓我們建立一個名為 MyFilter.mw 的新文字檔案,其內容如下

shaderSource = "
   void mainImage( out vec4 fragColor, in vec2 fragCoord )
   {
       vec3 col = texture2D(iChannel0, fragCoord).rgb;
       fragColor = vec4(col,1.0);
   }";

node = addShaderNode("MyFilter", shaderSource);
node.setRenderArea( "iChannel0" );

MyFilter.mw 檔案放在指令碼目錄中,並從節點選單中執行它。

檔案:MyFilterNode.png
MyFilter 節點

MyFilter 節點現在提供了 1 個輸入和 1 個輸出。

著色器只是將輸入紋理渲染到其輸出中。

新增 GUI 控制元件

[編輯 | 編輯原始碼]

現在我們已經有一個執行著色器的節點,讓我們向著色器新增一個輸入變數,並使用 GUI 控制元件更改其值。

下面的指令碼將輸入變數 uNumber 新增到著色器原始碼中,並新增一個 uiControl 來控制 uNumber 變數的值。

shaderSource = "
   void mainImage( out vec4 fragColor, in vec2 fragCoord )
   {
       vec3 col = texture2D(iChannel0, fragCoord).rgb;
       col.r = uNumber; // uNumber is a variable of type float
       fragColor = vec4(col,1.0);
   }";

myNode = newShaderNode("MyFilter", shaderSource);
myNode.setRenderArea( "iChannel0" );

// Slider control
uiControl = node.addFloatControl("uNumber", 0.5);
uiControl.setText("MyControl");
uiControl.setStep(0.01);
uiControl.setRange(0, 1);

指令碼的最後 4 行設定了 GUI 控制元件。

addFloatControl 建立 GUI 小部件並將其新增到節點引數視窗。它的引數是著色器原始碼中使用的變數名,它的第二個引數是它的初始值。

GUI 控制元件透過節點引數在 Mewa 中可見。要開啟節點引數,請單擊節點右側的圓形按鈕。

MyFilter 節點引數

更改引數值並在輸出視窗中觀察結果。

設定著色器渲染區域

[編輯 | 編輯原始碼]

在構建節點圖時,平移/縮放影像是一個常見的操作,能夠限制影像矩形內的著色器處理區域對於防止渲染整個視口非常重要。

根據節點的用例,我們必須選擇 3 個選項中的 1 個

  • "iResolution"
    • 主函式 mainImage( fragColor, fragCoord ) 接受 2 個輸入引數,其中 fragCoord 始終從 0 到 1,並覆蓋整個視口。
    • 用於透過計算每個畫素的顏色來生成過程影像。
  • "iChannel0"
    • 在此選項中,著色器僅處理影像 iChannel0 覆蓋的區域。主函式 mainImage( fragColor, fragCoord ) 接受 2 個輸入引數,其中 fragCoord 包含輸入影像的紋理座標。fragCoord 範圍不一定從 0 開始到 1 結束,但它將在 0 和 1 限制內的任何範圍內。
    • 用於對影像應用影像處理濾鏡
  • "iChannel0+iChannel1"
    • 主函式 mainImage( fragColor, fragCoord0, fragCoord1 ) 接受 3 個輸入引數,其中 fragCoord0fragCoord1 是 2 個輸入影像的紋理座標
    • 用於混合/合併 2 個輸入影像

所選選項使用 setRenderArea() 函式設定。

setRenderArea options
setRenderArea 選項

有關如何使用 "iChannel0+iChannel1" 選項的示例,請參見位於您的 指令碼目錄 中的 OverlayBlend.mw 指令碼。

使用 ShaderToy 開發

[編輯 | 編輯原始碼]

ShaderToy 是一個瀏覽器內的著色器開發環境。在 ShaderToy 中開發的著色器只需稍作修改即可輕鬆在 Mewa 中使用。

Mewa 著色器與 ShaderToy 著色器之間存在一些差異

  • 在 main() 函式中傳遞的 fragColor 引數儲存畫素值。在 Mewa 中,fragColor 包含歸一化畫素值,範圍在 0 到 1 之間。
  • ShaderToy 使用 texture 函式來獲取輸入紋理的顏色,而 Mewa 使用 GLSL 函式 texture2D


釋出您的指令碼

[編輯 | 編輯原始碼]

指令碼可以在 Mewatools WebStore 中釋出,這是一個 Mewa 附加元件的線上儲存庫。

華夏公益教科書