Shaders 頂點和片元程式

2021-10-08 07:29:09 字數 4794 閱讀 7356

此教程將會教你書寫unity shader裡的頂點和片元程式的基礎。請檢視 開始學習 以獲取更多關於shaderlab的介紹。如果你想編寫與燈光相互作用的著色器,那麼請去閱讀 [表面著色器](file:///d:/users/hoxily/documents/unitydocs/documentation.2018.4/en/manual/sl-su***ceshaders.html)。

讓我們簡要地概括一下著色器的一般結構:

shader "myshadername"

subshader // 相容圖形硬體a的子著色器

// 如有需要此處書寫更多pass指令

}// 如有需要此處書寫更多subshader

fallback "vertexlit" // 可選的回退指令

}

在這裡我們介紹了乙個新的指令:fallback 「vertexlit」。fallback可以用在shader的結尾處,它指出了當該著色器沒有乙個subshader能在使用者圖形硬體上使用時該使用哪個著色器。它的效果正如將回退著色器的所有subshader包含到該著色器的末尾一樣。舉例來說,如果你正在編寫乙個花俏的法線對映著色器,那麼相比再寫乙個非常基本的無法線對映的subshader用於老顯示卡,你可以直接使用fallback指令回退到內建的vertexlit著色器。

雖然我們已經在上一章介紹了著色器的基本構建單元,但是完整的 [properties](file:///d:/users/hoxily/documents/unitydocs/documentation.2018.4/en/manual/sl-properties.html), [subshaders](file:///d:/users/hoxily/documents/unitydocs/documentation.2018.4/en/manual/sl-subshader.html), [passes](file:///d:/users/hoxily/documents/unitydocs/documentation.2018.4/en/manual/sl-pass.html) 的文件也是可用的。

乙個快速構建subshader的方式就是使用其他著色器裡定義好的pass。usepass指令就是幹這件事的。因此你可以以簡潔的方式重用著色器**。例如接下來的這個指令使用了來自內建的specular著色器的forward pass:usepass "specular/forward"

為了使usepass起作用,需要給被引用的pass命名。在乙個pass內使用name指令可以給該pass設定名字:name "mypassname"

我們在上一章介紹了乙個僅僅使用乙個紋理combine指令的pass。現在是時候展示一下我們該如何在pass中使用頂點和片元程式。

當你使用頂點和片元程式(這被稱之為可程式設計管線)時,大部分硬編碼的功能(固定函式管線)就會被圖形硬體禁用。比如,使用頂點程式就會徹底關閉標準的3d變換、光照和紋理的座標生成。類似的,使用片元程式就會替換任何settexture指令裡的紋理combine模式,因此settexture就不再需要了。

書寫頂點、片元程式需要精通3d變換、光照以及座標空間,這些opengl api提供的固定函式都需你自己重寫。換句話說,相比內建的固定函式,你可以做的東西多得多!

在shaderlab裡著色器通常使用cg/hlsl程式語言書寫。cg和dx9風格的hlsl可用於所有使用目的,並且它們是同一種語言,因此我們將互換地使用這兩種說法(file:///d:/users/hoxily/documents/unitydocs/documentation.2018.4/en/manual/sl-shadinglanguage.html)。

通過在著色器文字裡嵌入cg/hlsl片段來書寫著色器**。這些片段被unity editor編譯成低階著色器彙編,然後在你的遊戲資料檔案裡只包含這些平台相關的低階彙編或位元組碼。當你在project檢視選中乙個著色器時,inspector面板會顯示乙個「show compiled code」的按鈕,這可以輔助你除錯。unity自動編譯cg片段,用於所有相關的平台(direct3d 9,opengl,direct3d 11, opengl es等)。請注意,由於cg/hlsl是由editor編譯,因此你無法在執行時建立著色器。

一般而言,片段嵌入到pass塊裡面。它們看起來就像這樣子:

pass
下面的例子展示了乙個完整的著色器,它可以以顏色的方式渲染物體的法線:

shader "tutorial/display normals" ;

fixed4 frag (v2f i) : sv_target

endcg}}

}

當將此著色器應用到物體上時,產生的效果如下所示:

我們的「display normals」著色器沒有任何屬性,只包含乙個subshader,subshader裡面只有乙個pass,這個pass裡面除了cg/hlsl**就是空的。讓我們來逐項地剖析**:

cgprogram

#pragma vertex vert

#pragma fragment frag

// ...

endcg

接下來的編譯指令就是簡單的cg/hlsl**。我們使用了#include指令包含了乙個內建的包含檔案:

#include "unitycg.cginc"
接下來我們定義了乙個「頂點到片元」的結構(此處命名為v2f),這個結構用於將資料從頂點函式傳送到片元函式。我們傳送了position和color兩個引數。這個顏色將會在頂點程式裡計算,然後直接在片元程式裡輸出。

接下來我們定義了頂點程式——乙個vert函式。在這裡,我們計算了position引數並將輸入的法線轉換成了顏色值:o.color = v.normal * 0.5 + 0.5;

法線的各分量的範圍在 -1 ~ 1 之間,而顏色的各分量則是在0~1之間,因此在上面的**裡我們將它先縮放再偏移。接下來我們定義了片元程式——frag函式,它直接將計算出來的顏色輸出,並使用了1作為顏色的alpha分量:

fixed4 frag (v2f i) : sv_target

就這樣,我們的著色器完成啦!即使是這樣乙個簡單的著色器對於視覺化網格的法線也是非常有用的。

當然這個著色器不會對燈光做出任何反應,而與燈光互動正是事情變得有趣的關鍵,請參閱 [表面著色器](file:///d:/users/hoxily/documents/unitydocs/documentation.2018.4/en/manual/sl-su***ceshaders.html) 。

當你在著色器裡定義屬性時,你給它們取了類似_color或者_maintex的名字。你需要在cg/hlsl裡定義與其相匹配的名字和型別的變數才能夠使用它們。詳見 [著色器程式裡的屬性](file:///d:/users/hoxily/documents/unitydocs/documentation.2018.4/en/manual/sl-propertiesinprograms.html) 。

接下來是乙個完整的著色器,展示了乙個被顏色調製過的紋理。當然,你也可以在紋理combiner指令裡幹同樣的事情,但是此處的關注點是演示了在cg裡如何使用屬性:

shader "tutorial/textured colored" 

}subshader ;

float4 _maintex_st;

fixed4 frag (v2f i) : sv_target

endcg}}

}

此著色器的結構與之前的例子相當。在這裡我們定義了兩個屬性,名為_color_maintex。在cg/hlsl**裡我們定義了相應的變數:

fixed4 _color;

sampler2d _maintex;

參見 [在cg/hlsl裡訪問著色器屬性](file:///d:/users/hoxily/documents/unitydocs/documentation.2018.4/en/manual/sl-propertiesinprograms.html) 以獲取更多關於資訊。

這裡的頂點和片元程式並沒有任何花俏的地方。頂點程式使用了來自unitycg.cginc的transform_tex巨集,用來確保正確應用了紋理的縮放和偏移。片元程式僅僅對紋理進行了取樣,並乘上了_color屬性。

我們展示了如何在簡單的幾個步驟裡編寫自定義的著色器程式。雖然這裡展示的例子都是非常簡單的,但是並沒有限制你編寫任何複雜的著色器程式!這能幫助你充分利用unity的優勢,獲取最佳的渲染結果。

完整的shaderlab參考手冊[在這裡](file:///d:/users/hoxily/documents/unitydocs/documentation.2018.4/en/manual/sl-reference.html),[頂點和片元著色器例子](file:///d:/users/hoxily/documents/unitydocs/documentation.2018.4/en/manual/sl-vertexfragmentshaderexamples.html)頁面有更多的例子。我們同時還有討論著色器的論壇,位址是 forum.unity3d.com,你可以去那裡獲取編寫著色器的幫助!程式設計快樂,享受unity和shaderlab的能力吧。

Shader 片元函式呼叫頂點函式

upgrade note replaced mul unity matrix mvp,with unityobjecttoclippos shader lxc 03 structshader struct v2f v2f vert a2v v fixed4 frag v2f f sv target ...

關於Unity中頂點片元Shader例項

補充 float4 fixed4 time 1 float4是內建向量 x,y,z,w float4 a 訪問單獨成員a.x,a.y,a.z,a.w 2 fixed4 是內建向量 r,g,b,a fixed4 c color.r,color.g,color.b,color.a 3 float3是內建...

(二)Unity頂點 片元著色器基礎

6.結語 本文主要講解以下unity shader的一些基礎內容,以無光照shader為例進行說明,後續進行詳細分析與說明。此shader可以直接複製到unity中使用 unity2018 2018親測可用 建議邊使用邊看如下分析。shader如下所示 shader ll unlit unlitsh...