簡介
引言
其實網(wǎng)上有很多shader教程,但是大概看了下,也不知是網(wǎng)上各位大神已經(jīng)脫離了代碼層面的高度還是啥原因。貌似沒有找到從代碼方面作為入門講解的,導(dǎo)致了shader對于苦逼程序員入門有一定要求,鄙人不才,來寫個比較低級的從代碼入門的shader教程吧。
寫在前面的話
了解過unityshader的人都知道,unityshader分三種,固定管線、表面著色器、頂點和片段著色器,具體區(qū)別書面上以及網(wǎng)上大神已經(jīng)解釋的很清楚了,我就不多做贅述了,我這一系列教程只從頂點和片段著色器教程開始,跟其他教程可能也有些區(qū)別(一來就上比較坑爹的部分),如果您沒聽過頂點和片段著色器的,請止步于此。
寫Shader的工具
如果已經(jīng)習(xí)慣了自己的IDE請直接跳過,只是推薦一下
1.下載安裝sublime text
2.下載該插件https://github.com/cjsjy123/Unity-Shader
3.將文件夾改名為Unity-Shader(就是去掉后面的-master)然后復(fù)制到sublime的packages路徑下
4.在sublime下設(shè)置unity的shader include路徑
preferences ->Packages settting -> Unity-Shader - >setting - Default
路徑是:D:/Program Files/Unity/Editor/Data/CGIncludes(自行類比)
5.愉快的用sublime編寫shader吧(支持代碼跳轉(zhuǎn)及基本自動完成功能)
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的代碼結(jié)構(gòu):
Shader的語法是
Shader "名字" // 這個名字自己隨便取,類似于類名,不需要與文件名相同
{
Properties {} // 可以從unity中設(shè)置的外接屬性,后面具體講怎么設(shè)置
SubShader {
// 執(zhí)行的渲染PASS,可以有多個Pass,都會被執(zhí)行
Pass{
// 具體代碼
}
}
.
. // 可以有很多個,gpu執(zhí)行的時候從上往下,找到第一個可以執(zhí)行的SubShader執(zhí)行
.
SubShader {
// 執(zhí)行的渲染
}
// 備胎,在沒有任何Subshader可以執(zhí)行時,用該shader代替
Fallback "Diffuse"
}
以上就是我們大概要用的代碼結(jié)構(gòu),其實還有其他的,但是為了快速上手,后續(xù)要擴(kuò)展再引入
其中除了SubShader不能刪,其他的不用的都可以刪掉
所以精簡出我們的第一個shader的結(jié)構(gòu):
Shader "名字"
{
SubShader
{
Pass
{
// 代碼
}
}
}
下面講代碼部分:
我們要用的CG語言,前后必須用CGPROGRAM和ENDCG包起來,
然后中間的部分就是我們真正的cg代碼了
#pragma vertex vert
// 這一行是定義處理頂點信息的函數(shù)名
// 模型中每一個頂點會調(diào)用一次該函數(shù),GPU執(zhí)行運算,注意性能
// 格式是: #pragma vertex 函數(shù)名,函數(shù)名字可以自己隨意取
#pragma fragment frag
// 這一行是定義處理片面信息的函數(shù)名
// 具體調(diào)用時機(jī)不是很確定,應(yīng)該是跟面數(shù)相關(guān)
// 格式是: #pragma fragment 函數(shù)名,函數(shù)名字可以自己隨意取
float4 vert ( float4 position : POSITION ) : SV_POSITION
// 對應(yīng)的上面頂點處理的函數(shù),傳入對象是一個float4
// 其實是一個頂點的詳細(xì)信息,只是我們這里通過: POSITION單獨選取了位置信息而已
// 后面的: SV_POSITION表示return的float4作為SV_POSITION(不可變頂點)
// 其實傳出為POSITION也是可以的,DX10之后才有區(qū)別,SV_POSITION性能更高
{
return mul( UNITY_MATRIX_MVP, position );
// 這里做了一個與UNITY的矩陣世界做了一個乘法操作
// 用于將模型坐標(biāo)換算成世界坐標(biāo),如果需要通過shader更改頂點位置,需要在這里進(jìn)行操作
}
fixed4 frag ( void ) : COLOR
// 對應(yīng)上面的面片處理的函數(shù),這里為了簡單,不處理任何數(shù)據(jù)
// : COLOR 表示返回的fixed4類型作為COLOR處理
{
return float4 (1,0,0,1);
// 直接返回一個固定顏色(float4可以強(qiáng)轉(zhuǎn)成fixed4,這里為了教程演示強(qiáng)轉(zhuǎn)使用)
}
我們想在Unity中改顏色
先來明確編寫思路:
從上面的解釋可以看出,我們的顏色處理是在frag 函數(shù)中返回的
所以我們要想改變物體顏色,只需要更改這個返回值即可
那么要從unity中更改顏色,我們就需要一個外接屬性
恩,上面也講了,從Properties 中設(shè)置!
直接上代碼吧
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;申明一下該變量名(名字必須完全一致)
然后后續(xù)操作就不解釋了吧,直接該顏色,返回就行
我們來看看效果

我想更改頂點渲染位置
哈哈,這里就是shader開始牛逼的地方了:
我們可以很高效的對模型頂點數(shù)據(jù)進(jìn)行特殊處理!
這次我們要更改vert函數(shù)(這個應(yīng)該不難想吧,頂點相關(guān)的操作一般都在這里做了)
直接來代碼:
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變?yōu)榱?.5倍,z沒有變化,
然后對比一下position * float4 (2,0.5,1,1)這個操作,應(yīng)該很容易猜出這個操作的含義了吧
float4 (x,y,z,u)這個float4的xyz分別對應(yīng)三個軸上的縮放量,u呢則是我們的單位長度
具體的縮放關(guān)系體現(xiàn)為 坐標(biāo)位置 = 原始位置 * (x / u)
當(dāng)然,你也可以在這個函數(shù)中對頂線信息進(jìn)行其他操作,這里只是最簡單一個例子
總結(jié)
到這里,今天的blog就到此結(jié)束了,希望大家能看懂,不明白的歡迎加QQ:821580467一起探討
|