簡介
引言
其實網上有不少shader教程,可是大概看了下,也不知是網上各位大神已經脫離了代碼層面的高度仍是啥緣由。貌似沒有找到從代碼方面做爲入門講解的,致使了shader對於苦逼程序員入門有必定要求,鄙人不才,來寫個比較低級的從代碼入門的shader教程吧。
寫在前面的話
瞭解過unityshader的人都知道,unityshader分三種,固定管線、表面着色器、頂點和片斷着色器,具體區別書面上以及網上大神已經解釋的很清楚了,我就很少作贅述了,我這一系列教程只從頂點和片斷着色器教程開始,跟其餘教程可能也有些區別(一來就上比較坑爹的部分),若是您沒聽過頂點和片斷着色器的,請止步於此。
寫Shader的工具
若是已經習慣了本身的IDE請直接跳過,只是推薦一下
1.下載安裝sublime text
2.下載該插件https://github.com/cjsjy123/Unity-Shader
3.將文件夾更名爲Unity-Shader(就是去掉後面的-master)而後複製到sublime的packages路徑下
4.在sublime下設置unity的shader include路徑
preferences ->Packages settting -> Unity-Shader - >setting - Default
路徑是:D:/Program Files/Unity/Editor/Data/CGIncludes(自行類比)
5.愉快的用sublime編寫shader吧(支持代碼跳轉及基本自動完成功能)
20行的Shader
效果:
Shader "LT/Lesson1"
{
SubShader
{
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
float4 vert ( float4 position : POSITION ) : SV_POSITION
{
return mul( UNITY_MATRIX_MVP, position );
}
fixed4 frag ( void ) : COLOR
{
return float4 (1,0,0,1);
}
ENDCG
}
}
}
這裏咱們大概解釋一下咱們要用的shader的代碼結構:
Shader的語法是
Shader "名字" // 這個名字本身隨便取,相似於類名,不須要與文件名相同
{
Properties {} // 能夠從unity中設置的外接屬性,後面具體講怎麼設置
SubShader {
// 執行的渲染PASS,能夠有多個Pass,都會被執行
Pass{
// 具體代碼
}
}
.
. // 能夠有不少個,gpu執行的時候從上往下,找到第一個能夠執行的SubShader執行
.
SubShader {
// 執行的渲染
}
// 備胎,在沒有任何Subshader能夠執行時,用該shader代替
Fallback "Diffuse"
}
以上就是咱們大概要用的代碼結構,其實還有其餘的,可是爲了快速上手,後續要擴展再引入
其中除了SubShader不能刪,其餘的不用的均可以刪掉
因此精簡出咱們的第一個shader的結構:
Shader "名字"
{
SubShader
{
Pass
{
// 代碼
}
}
}
下面講代碼部分:
咱們要用的CG語言,先後必須用CGPROGRAM和ENDCG包起來,
而後中間的部分就是咱們真正的cg代碼了
#pragma vertex vert
// 這一行是定義處理頂點信息的函數名
// 模型中每個頂點會調用一次該函數,GPU執行運算,注意性能
// 格式是: #pragma vertex 函數名,函數名字能夠本身隨意取
#pragma fragment frag
// 這一行是定義處理片面信息的函數名
// 具體調用時機不是很肯定,應該是跟面數相關
// 格式是: #pragma fragment 函數名,函數名字能夠本身隨意取
float4 vert ( float4 position : POSITION ) : SV_POSITION
// 對應的上面頂點處理的函數,傳入對象是一個float4
// 實際上是一個頂點的詳細信息,只是咱們這裏經過: POSITION單獨選取了位置信息而已
// 後面的: SV_POSITION表示return的float4做爲SV_POSITION(不可變頂點)
// 其實傳出爲POSITION也是能夠的,DX10以後纔有區別,SV_POSITION性能更高
{
return mul( UNITY_MATRIX_MVP, position );
// 這裏作了一個與UNITY的矩陣世界作了一個乘法操做
// 用於將模型座標換算成世界座標,若是須要經過shader更改頂點位置,須要在這裏進行操做
}
fixed4 frag ( void ) : COLOR
// 對應上面的面片處理的函數,這裏爲了簡單,不處理任何數據
// : COLOR 表示返回的fixed4類型做爲COLOR處理
{
return float4 (1,0,0,1);
// 直接返回一個固定顏色(float4能夠強轉成fixed4,這裏爲了教程演示強轉使用)
}
咱們想在Unity中改顏色
先來明確編寫思路:
從上面的解釋能夠看出,咱們的顏色處理是在frag 函數中返回的
因此咱們要想改變物體顏色,只須要更改這個返回值便可
那麼要從unity中更改顏色,咱們就須要一個外接屬性
恩,上面也講了,從Properties 中設置!
直接上代碼吧
Shader "LT/Lesson1"
{
Properties {
_Color ("Main Color", Color ) = (1,0,0,1)
}
SubShader
{
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
uniform float4 _Color;
float4 vert ( float4 position : POSITION ) : SV_POSITION
{
return mul( UNITY_MATRIX_MVP, position );
}
fixed4 frag ( void ) : COLOR
{
return _Color;
}
ENDCG
}
}
}
好~
來解釋一下:
_Color ("Main Color", Color ) = (1,0,0,1)
表示我在Unity的Shader面板中定義了一個_Color的外接屬性
格式爲 [變量名字] ("Unity中顯示的名字", [類型]) = (值)
具體後面還有其餘的,我也背不下來,用到再講,也能夠自行查閱
而後定義了以後,並不能直接被CG代碼識別,
須要用到 uniform float4 _Color;申明一下該變量名(名字必須徹底一致)
而後後續操做就不解釋了吧,直接該顏色,返回就行
咱們來看看效果
我想更改頂點渲染位置
哈哈,這裏就是shader開始牛逼的地方了:
咱們能夠很高效的對模型頂點數據進行特殊處理!
此次咱們要更改vert函數(這個應該不難想吧,頂點相關的操做通常都在這裏作了)
直接來代碼:
Shader "LT/Lesson1"
{
Properties {
_Color ("Main Color", Color ) = (1,0,0,1)
}
SubShader
{
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
uniform float4 _Color;
float4 vert ( float4 position : POSITION ) : SV_POSITION
{
return mul( UNITY_MATRIX_MVP, position * float4 (2,0.5,1,1));
}
fixed4 frag ( void ) : COLOR
{
return _Color;
}
ENDCG
}
}
}
來,先看效果再解釋
能夠很清楚地看到,X軸被放大到了2倍,y變爲了0.5倍,z沒有變化,
而後對比一下position * float4 (2,0.5,1,1)這個操做,應該很容易猜出這個操做的含義了吧
float4 (x,y,z,u)這個float4的xyz分別對應三個軸上的縮放量,u呢則是咱們的單位長度
具體的縮放關係體現爲 座標位置 = 原始位置 * (x / u)
固然,你也能夠在這個函數中對頂線信息進行其餘操做,這裏只是最簡單一個例子
總結
到這裏,今天的blog就到此結束了,但願你們能看懂,不明白的歡迎加QQ:821580467一塊兒探討