6.結語
本文主要講解以下unity shader的一些基礎內容,以無光照shader為例進行說明,後續進行詳細分析與說明。此shader可以直接複製到unity中使用(unity2018/2018親測可用),建議邊使用邊看如下分析。shader如下所示:
shader "ll/unlit/unlitshader_basicdismiss"
_dissolvetex
("dissolve texture"
,2d)
="white"
_dissolvecutoff
("dissolve cutoff"
,range(0
,1))
=1_dismiss
("model dismiss"
,range(-
1,1)
)=0}
subshader ;
struct v2f
;v2f vert
(a2v v)
float4 frag
(v2f f)
:sv_target
endcg
}}}
名稱如下所示,此shader名稱為unlitshader_basicdismiss,通過路徑ll/unlit/即可找到。
shader "ll/unlit/unlitshader_basicdismiss"
屬性為暴露在inspector面板中的引數,可以人為更改的,基本格式為:屬性名稱(「顯示名稱」,變數型別)= 預設值,如下所示。
屬性基本格式以_maintex("main texture",2d)="white"{}
為例進行解釋:_maintex為變數名稱,括號內雙引號內第乙個值"main texture"為面板上顯示內容,第二個值2d為此變數所表示的內容,即為2d紋理。「white」{}則為預設值為白色紋理,寫法使用雙引號加{},但是對於其他變數則不是,比如_dissolvetex為float型別,則值為1,每乙個變數後無需加分號。
properties
_dissolvetex
("dissolve texture"
,2d)
="white"
_dissolvecutoff
("dissolve cutoff"
,range(0
,1))
=1_dismiss
("model dismiss"
,range(-
1,1)
)=0}
變數型別以及使用型別如下表所示:
屬性型別
例子說明
int_int(「int」,int)=2
int型別,預設值為2
float
_float(「float」,float)=2.0
float型別,預設值為2
range
_range(「range」,range(0,1))=0.5
float型別,預設值為0.5,並鎖定範圍
color
_color(「color」,color)=(1,1,1,1)
color型別,預設值為白色
vector
_vector(「vector」,vector)=(1,1,1,1)
vector型別(四維向量),預設值為白色(1,1,1,1)
2d_maintex(「main texture」,2d)=「white」{}
2d紋理,預設值為白色紋理
cube
_cube(「skybox」,cube)=「white」{}
cube紋理,預設值為白色紋理
3d_maintex(「main texture」,3d)=「white」{}
3d紋理,預設值為白色紋理
其中:range型別是乙個slider樣式,支援滑動修改和手動直接輸入,但是在2018以後無slider樣式;vector型別看名稱雖然是向量,其實代表的為四維資料,也可以當作位置輸入;cube則表示此紋理為六面體紋理。
乙個unity shader中可以包含多個subshader**塊,最少乙個,載入時unity選擇與目標平台匹配的第乙個subshader執行,如果都不支援,則會使用fallback語義指定的shader。乙個subshader中可以包含多個pass。pass中語句定義在 cgprogram endcg之間,表示使用cg/hlsl編寫的,當然也可以用其他的語言去寫。
subshader
}
通過#pragma vertex定義頂點著色方法vert(此為方法名稱,可以隨意修改),同時新增實現。同理通過#pragma fragment定義片元著色器frag,並實現改方法。其中#include "unitycg.cginc"表示引入此檔案中定義的方法、變數以及語義塊。此檔案獲取章節會詳細講解。
#pragma vertex vert
#pragma fragment frag
#include
"unitycg.cginc"
float _dissolvecutoff;
float _dismiss;
sampler2d _maintex;
sampler2d _dissolvetex;
struct a2v
;struct v2f
;v2f vert
(a2v v)
float4 frag
(v2f f)
:sv_target
在上述**中,定義了兩個float以及sampler2d格式變數,這兩個變數與屬性模組中變數同名,這樣變可獲取到屬性面板變數的值。
在上述**中定義了兩個struct型別a2v與v2f。其中struct中定義變數時格式為:變數型別+變數名稱+變數語義,如下所示:
float4 vertex:position;
變數型別如下表所示
型別釋義
float
最高位數資料變數
half
中間位數資料變數
fixed
最低位數精度資料變數(由於顏色值為0-1,所以顏色可用fixed4型別)
變數型別+數字n表示乙個n維變數,每一維度的數值為相應的型別,如fixed4,表示4維變數,每一維度型別為fixed。
vert方法最基本的任務是將頂點座標轉換到裁剪空間下(即gpu呼叫此vert方法對每乙個頂點進行處理),所以其入口引數至少包含乙個語義為position的頂點座標,輸出值包含語義為sv_position變數,最基本的vert方法如下所示,可根據需要傳入其他變數,比如本例還傳入了uv和法線。以如下為例通過unitycg.cginc中的unityobjecttoclippos方法將頂點座標轉化到裁剪空間中。也可以通過mul(unity_matrix_mvp,v.vertex)方法實現,即通過mvp矩陣直接成以座標變數。其實unityobjecttoclippos就是用的mvp矩陣直接計算。
float4 vert
(float4 vertex:position)
:sv_position
本例中在計算裁剪空間下頂點座標之前對頂點座標做了處理,即在其法線方向移動_dismiss距離,如果其值為0,則不移動。
片元著色器最根本的所用是產生乙個畫素的顏色,所以可以不用入口引數,直接返回乙個顏色值,如下所示:
float4 frag()
:sv_target
本例中相對複雜一些,即根據uv值,通過tex2d(_maintex,f.uv)方法,對主紋理進行取樣,獲取相應的顏色值進行返回,並根據_dissolvetex紋理,做了畫素的捨棄clip(dissolvetexcolor.rgb-_dissolvecutoff);即當clip的值小於0時discard掉此值,即frag在此位置不會返回顏色值,此時對應的位置就不會顯示任何顏色,因為顏色rgb分量值範圍為0-1,所以對應的_dissolvecutoff值也為0-1。
通過乙個基本的shader將shader的基本語法解釋清楚了,後續會不斷拓展。並推薦兩個學習blog:含完整**版和原文版
頂點著色器與片元著色器
頂點著色器 在管線中的位置 1號 這圖作的跟病毒似的 可以替代下面這些傳統的操作 頂點變換 法線變化及規範化 紋理座標生成 紋理座標變換 光照彩色材質應用 頂點著色器可以用來指定一系列完全通用的 並將應用於各個頂點及相關資料上的操作。理解這點很重要。頂點著色器不會取代一次需要多個頂點的情況或者需要拓...
頂點著色器 片段著色器
一 著色器 著色器只是一種把輸入轉化為輸出的程式。著色器也是一種非常獨立的程式,因為它們之間不能相互通訊 它們之間唯一的溝通只有通過輸入和輸出。在最簡配置下,至少都得有兩個著色器 乙個叫頂點著色器 vertex shader 它將作用於每個頂點上 另乙個叫片段著色器 fragment shader ...
著色器(Shader)之頂點著色器
頂點著色器其實就是我們自己編寫的一段在gpu中執行的程式,有了頂點著色器,我們就可以從固定的功能流水線中代替一些模組,從而獲得更多的頂點操作的靈活性。對於頂點位置進行操作的的能力具有廣泛的應該場合 織物模擬 粒子系統的點尺寸處理等。可程式設計流水線中的頂點結構比固定的流水線具有更加豐富的資料。首先我...