WebGPU05-Begin-The Pipeline,著色器準備!
Begin | WebGPU
3.The Pipeline-1
譯者注:建議在學習本節時開啟對應的Github程式碼庫進行對比學習
-
什麼是Pipeline?
如果你對 OpenGL 比較熟悉,你可能還記得使用 shader(著色器) 的時候。
你可以將 pipeline(傳遞通道)理解為一個更加健壯的 shader(著色器)。一個 傳遞通道 描述了 顯示卡 在對一組資料進行操作時將執行的所有操作。
在這一部分,我們將具體的建立一個
RenderPipeline
。 -
等等,shader是啥 ? _ ?
著色器是傳送至 GPU 以對資料執行操作的小程式。
著色器 主要有三種類型:vertex(頂點)、fragment(片段)、compute(計算)。
當然還有其他型別例如 geometry shader(幾何著色器),但它們更加高階,現在我們只需要瞭解三種主要型別。
-
那 vertex、fragment 這些是...
一個 頂點 是3D空間中的一個點(也適用於2D)。然後將這些 頂點 捆綁成 2組以形成線 或 3組以形成三角形。
大多數現代渲染均使用三角形來作所有形狀,從 簡單形狀(如立方體)到 複雜形狀(如人)。這些三角形以 頂點 的形式儲存起來,這些 頂點 構成了三角形角的點。
為了將形狀轉換為我們想要的樣子,我們使用 vertex shader(頂點渲染)來操作 頂點。
之後我們將 頂點 轉換為 片段。每一個結果圖中的畫素都會有至少一個 片段。而每一個 片段 都有一種顏色,該顏色將被複制到其對應的畫素。fragment shader(片段著色器)決定了我們的 片段 將會變成什麼顏色。
-
WGSL(WebGPU Shading Language)
WGSL 是 WebGPU 的 shader language(著色器語言)。
WGSL 的開發重點是讓它能夠輕鬆轉換成後端對應的著色器語言。
例如,SPIR-V 用於 Vlukan,MSL 用於 Metal,HLSL 用於 DX12,GLSL 用於 OpenGL。
轉換完成於內部,通常我們無需關注其細節。
在 wgpu 種,轉換由庫 naga 所完成。注意:在我寫下這篇嚮導的時候,一些 WebGPU 的實現尚且支援 SPIR-V,但這只是向 WGSL 過渡期間的臨時舉措,它將在不久後被刪除。(如果你對 SPIR-V 和 WGSL 背後的劇情感興趣,請參閱此博文:
此處不譯,與此嚮導歷史版本有關,可考慮檢視
If you've gone through this tutorial before you'll likely notice that I've switched from using GLSL to using WGSL. Given that GLSL support is a secondary concern and that WGSL is the first class language of WGPU, I've elected to convert all the tutorials to use WGSL. Some showcase examples still use GLSL, but the main tutorial and all examples going forward will be using WGSL.
The WGSL spec and it's inclusion in WGPU is still in development. If you run into trouble using it, you may want the folks at https://app.element.io/#/room/#wgpu:matrix.orgto take a look at your code.
-
編寫著色器
-
頂點著色器
在
main.rs
的同級目錄下,新建檔案shader.wgsl
,將下列程式碼寫入檔案shader.wgsl
// Vertex shader struct VertexOutput { [[builtin(position)]] clip_position: vec4<f32>; }; [[stage(vertex)]] fn vs_main( [[builtin(vertex_index)]] in_vertex_index: u32, ) -> VertexOutput { var out: VertexOutput; let x = f32(1 - i32(in_vertex_index)) * 0.5; let y = f32(i32(in_vertex_index & 1u) * 2 - 1) * 0.5; out.clip_position = vec4<f32>(x, y, 0.0, 1.0); return out; }
在上述程式碼中,首先我們聲明瞭一個
struct
用於儲存我們的頂點著色器(vertex shader)的輸出。現在此唯一域的組成是我們頂點的
clip_position(剪輯位置)
。[[builtin(position)]]
塊告訴 WGPU 這是我們想要用作 頂點剪輯座標(vertex's clip coordinates) 的值。這與 GLSL 的
gl_Position
變數相似。此處不譯,但需要檢視
Vector types such as
vec4
are generic. Currently, you must specify the type of value the vector will contain. Thus, a 3D vector using 32bit floats would bevec3<f32>
.著色器程式碼中的下一部分是
vs_main
函式。我們使用
[[stage(vertex)]]
來標記此函式作為 頂點著色器 的有效入口點。期望一個名為in_vertext_index
的u32
型別從[[builtin(vertex_index)]]
獲取它的值。之後我們宣告一個名為
out
的變數來使用我們的VertexOutput
結構。又創造了兩個其他的變數用於一個三角形的x
和y
。此處不譯,但需要檢視
The
f32()
andi32()
bits are examples of casts.Variables defined with
var
can be modified, but must specify their type. Variables created withlet
can have their types inferred, but their value cannot be changed during the shader.現在我們可以將我們的
clip_position
存入out
。之後我們只需返回out
,這樣就完成了 頂點著色器!此處不譯,但需要檢視
We technically didn't need a struct for this example, and could have just done something like the following:
[[stage(vertex)]] fn vs_main( [[builtin(vertex_index)]] in_vertex_index: u32 ) -> [[builtin(position)]] vec4<f32> { // Vertex shader code... } Copied!
We'll be adding more fields to
VertexOutput
later, so we might as well start using it now. -
片段著色器
接下來讓我們配置 片段著色器。
仍然在
shader.wgsl
中新增下列程式碼:// Fragment shader [[stage(fragment)]] fn fs_main(in: VertexOutput) -> [[location(0)]] vec4<f32> { return vec4<f32>(0.3, 0.2, 0.1, 1.0); }
這會使當前片段的顏色設定為棕色。
此處不譯,注意檢視
Notice that the entry point for the vertex shader was named
vs_main
and that the entry point for the fragment shader is calledfs_main
. In earlier versions of wgpu it was ok to both name these functions the same, but newer versions of the WGSL spec (opens new window)require these names to be different. Therefore, the above mentioned naming scheme (which is adopted from thewgpu
examples) is used throughout the tutorial.[[location(0)]]
位 告訴 WGPU 將這個函式返回的vec4
值儲存在第一個顏色目標中。稍後我們再深入討論。
-
該部落格由本人個人翻譯自Learn Wgpu,因此可能有部分文字不易理解或出現錯誤,如有發現還望告知,本人必定及時更改。