多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php開源 > 綜合技術 > UnityShader快速上手指南(二)

UnityShader快速上手指南(二)

來源:程序員人生   發布時間:2016-06-16 08:44:05 閱讀次數:3035次

簡介

前1篇介紹了如果編寫最基本的shader,接下來本文將會簡單的深入1下,我們先來看下效果吧

這里寫圖片描述

呃,gif效果不好,實際效果是很平滑的動態過渡

實現思路

1.首先我們要實現1個彩色方塊
2.讓色采動起來
over

實現1個RGB CUBE

先看代碼吧:

Shader "LT/Lesson2" { Properties { _OffsetX ("Offset X", Range (-1.5, 1.5) ) = 0 _OffsetY ("Offset Y", Range (-1.5, 1.5) ) = 0 _OffsetZ ("Offset Z", Range (-1.5, 1.5) ) = 0 } SubShader { Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct VertextOutput { float4 pos : SV_POSITION ; fixed4 col : COLOR ; }; uniform float _OffsetX; uniform float _OffsetY; uniform float _OffsetZ; VertextOutput vert ( appdata_base input ) { VertextOutput result; result.pos = mul(UNITY_MATRIX_MVP , input.vertex ) ; result.col = input.vertex + float4( _OffsetX, _OffsetY, _OffsetZ, 0); return result; } fixed4 frag ( VertextOutput input ) : COLOR { return input.col; } ENDCG } } }

恩~~,首先呢,我們這次輸出的色彩不同的位置色彩不同,所以我們需要1個同時能存位置和色彩的結構體:

struct VertextOutput { float4 pos : SV_POSITION ; // 位置信息, 后面的: SV_POSITION是必須的,固然你也能夠換成: POSITION fixed4 col : COLOR ; // 色彩信息, 后面的: COLOR不是必須的,你可以隨意取名字比如 : FUCK // 但是嘛,為了代碼方便瀏覽,還是寫成COLOR吧 };

然后呢我們只有這樣1個模型:
這里寫圖片描述
24個頂點(每一個面頂點單算的),12個3角形,兩個空的UV(這個是unity自帶的cube模型)
這個模型是沒有任何色彩信息,所以我們需要自己在shader中生成他的色彩
出于方便斟酌,我們將這個模型的頂點(XYZ)變成RGB的色彩,由于恰好3個值都有變化嘛
因而有了這樣的代碼
result.col = input.vertex + float4( _OffsetX, _OffsetY, _OffsetZ, 0);
前面頂點位置就不作處理了,直接換算成Unity坐標就完了
result.pos = mul(UNITY_MATRIX_MVP , input.vertex ) ;

然后我們來講說傳入參數中的appdata_base
對VertextOutput vert ( appdata_base input )這個函數命名
學過C語言的應當知道前面是返回值類型 括號里面是傳入值類型和名字吧
然后這個appdata_base呢是定義在#include “UnityCG.cginc”的1個結構體
(強行帶節奏引入了UnityCG.cginc,其實也能夠像前面1篇1樣使用float4 position : POSITION,只是這里為了早點引入UnityCG.cginc而已)
我們可以看1下UnityCG.cginc的部份代碼:

// Dynamic & Static lightmaps contain indirect diffuse ligthing, thus ignore SH #define UNITY_SHOULD_SAMPLE_SH ( defined (LIGHTMAP_OFF) && defined(DYNAMICLIGHTMAP_OFF) ) struct appdata_base { float4 vertex : POSITION; float3 normal : NORMAL; float4 texcoord : TEXCOORD0; }; struct appdata_tan { float4 vertex : POSITION; float4 tangent : TANGENT; float3 normal : NORMAL; float4 texcoord : TEXCOORD0; }; struct appdata_full { float4 vertex : POSITION; float4 tangent : TANGENT; float3 normal : NORMAL; float4 texcoord : TEXCOORD0; float4 texcoord1 : TEXCOORD1; float4 texcoord2 : TEXCOORD2; float4 texcoord3 : TEXCOORD3; #if defined(SHADER_API_XBOX360) half4 texcoord4 : TEXCOORD4; half4 texcoord5 : TEXCOORD5; #endif fixed4 color : COLOR; };

全部有點小長,我只粘貼1部份,其實就是1大堆Unity的定義而已,
我們再來看看

struct appdata_base { float4 vertex : POSITION; //位置 float3 normal : NORMAL; //法線 float4 texcoord : TEXCOORD0; // 紋理 };

其實這是1個簡化的模型數據,包括了1些經常使用的參數,如果我們寫的shader主要是給手機使用的話,這些數據基本也就夠了,而且目前我們也就用了他的位置的信息,固然你也能夠傳入1個appdata_full 類型,區分不大

至于_OffsetX,_OffsetY,_OffsetZ3個外接屬性的定義就不多做贅述了
然后我們就通過

VertextOutput vert ( appdata_base input ) { VertextOutput result; result.pos = mul(UNITY_MATRIX_MVP , input.vertex ) ; result.col = input.vertex + float4( _OffsetX, _OffsetY, _OffsetZ, 0); return result; }

計算出了相應頂點的色彩
然后直接在面片渲染函數中把對應點的色彩賦值給他就好了
return input.col;
注意這里我們的傳入參數變成了vert 的返回值
fixed4 frag ( VertextOutput input ) : COLOR

好來看下初步的效果:
這里寫圖片描述
這里我們就完成了1個RBG CUBE了。
下面對1些原理性的東西簡單解釋1下

光柵化?插值?

前面我解釋過vert函數是1個頂點調用1次,這里我們的模型1共才24個頂點,但是為啥出來這么多個色彩呢,這里就跟渲染流程的光柵化有關。默許情況下,光柵化會保持平滑過渡,如果兩邊不匹配就會在中間插值,然后對我們的模型而言,1個面上每一個頂點的色彩都不同,所以他就會自動插入很多個頂點,并且自動漸變色彩來滿足平滑過渡(也就是說如果你色彩都1樣,就不會插點了,固然你也能夠手動不讓它插點,概念比較多,這里就不展開了,我們要快速上手嘛)

讓色彩隨著時間變化而變化

這里是我強行要加的1個功能,不然感覺這篇blog就太少內容咯,哈哈
有兩種實現方法:
1.unity中通過C#代碼去控制剛才開放出來的參數
2.shader中自己通過時間去更改色彩
我們既然是學shader,固然是在shader中進行更改啦
直接上代碼:

result.col = input.vertex + float4( _SinTime.w + 0.5, _SinTime.w + 0.5, _SinTime.w + 0.5, 0);

呃,對,就改這1行。效果就是實現啦,大家可以自己行試1下
下面解釋1小下下:
_SinTime是unity為shader內置的1個時間的sin值得變量(看名字也看的出來吧)
需要引入#include “UnityCG.cginc” (這也是為啥我前面強行帶節奏的緣由)
然后來普及下Unity為我們內置了哪些東西吧:

Transformations 變換

float4x4 UNITY_MATRIX_MVP
Current model*view*projection matrix 
當前物體*視*投影矩陣。(注:物體矩陣為 本地->世界)
float4x4 UNITY_MATRIX_MV
Current model*view matrix 
當前物體*視矩陣
float4x4 UNITY_MATRIX_P
Current projection matrix 
當前物體*投影矩陣
float4x4 UNITY_MATRIX_T_MV
Transpose of model*view matrix 
轉置物體*視矩陣
float4x4 UNITY_MATRIX_IT_MV 
Inverse transpose of model*view matrix 
逆轉置物體*視矩陣
float4x4 UNITY_MATRIX_TEXTURE0 to UNITY_MATRIX_TEXTURE3
Texture transformation matrices 
貼圖變換矩陣
float4x4 _Object2World
Current model matrix 
當前物體矩陣
float4x4 _World2Object
Inverse of current world matrix 
物體矩陣的逆矩陣
float3 _WorldSpaceCameraPos
World space position of the camera 
世界坐標空間中的攝像機位置
float4 unity_Scale
xyz components unused; .w contains scale for uniformly scaled objects. 
不適用xyz份量,而是通過w份量包括的縮放值等比縮放物體。

_ModelLightColor    float4  Material's Main * Light color 材質的主色彩*燈光色彩
_SpecularLightColor float4  Material's Specular * Light color 材質的鏡面反射(高光)*燈光色彩。
_ObjectSpaceLightPos    float4  Light's position in object space. w component is 0 for directional lights, 1 for other lights 
物體空間中的燈光為,平行光w份量為零其燈光為1;
_Light2World    float4x4    Light to World space matrix 燈光轉世界空間矩陣
_World2Light    float4x4    World to Light space matrix 世界轉燈光空間矩陣
_Object2Light   float4x4    Object to Light space matrix 物體轉燈光空間矩陣

float4 _Time : Time (t/20, t, t*2, t*3), use to animate things inside the shaders 
時間: 用于Shasder中可動畫的地方。
float4 _SinTime : Sine of time: (t/8, t/4, t/2, t) 
時間的正弦值。
float4 _CosTime : Cosine of time: (t/8, t/4, t/2, t) 
時間的余弦值
float4 _ProjectionParams : 投影參數
x is 1.0 or ⑴.0, negative if currently rendering with a flipped projection matrix 
x為1.0 或⑴.0如果當前渲染使用的是1個反轉的投影矩陣那末為負。 
y is camera's near plane y是攝像機的近剪裁平面
z is camera's far plane z是攝像機遠剪裁平面
w is 1/FarPlane. w是1/遠剪裁平面
float4 _ScreenParams : 屏幕參數
x is current render target width in pixels x是當前渲染目標在像素值中寬度
y is current render target height in pixels y是當前渲染目標在像素值中的高度
z is 1.0 + 1.0/width z是1.0+1.0/寬度
w is 1.0 + 1.0/height w是1.0+1.0/高度

呃,格式不是很好看的模樣,這里有鏈接,自己去看吧http://www.ceeger.com/Components/SL-BuiltinValues.html
有了這些東西以后呢,我們就能夠簡單的根據時間變化做1些動態shader了,比如甚么UV活動啊,色彩動態變化啊,動態模型(是動態模型不是模型動畫哈)啥的,瞬間就高大上了有不有,性能嘛取決于你寫的代碼(一樣的代碼級別下,shader速度秒殺你在c#中寫)

總結

這1篇感覺寫的比較亂,主要是知識點比較雜(這理由不是很好找啊….諒解我語文老師是數學老師教大的)
主要知識點是介紹1下光柵化那個插值,這個很重要https://en.wikibooks.org/wiki/Cg_Programming/Rasterization(雖然我講的1筆帶過,大家去看看官方解釋吧)
然后介紹1下UnityCG.cginc,我們既然是寫的unityshader,固然還是要常常使用這個庫的啦,后面還有光照,空間矩陣啥的,基本我們要想做高級殊效離不開這個庫的,大家可以去看看這個庫源碼
了解了這些以后,就是單純的算法了(比如怎樣通過時間更改模型頂點位置實現好看的動畫啥的)
恩~~~再次坦白下寫的比較亂,如有疑問歡迎聯系QQ:8215804671起探討

生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 亚洲国产2017男人a天堂 | 国产成人免费手机在线观看视频 | www视频在线观看com | 爱爱www在线观看视频高清 | 黑人xxxx日本 | 亚洲综合精品一区二区三区中文 | 午夜视频啪啪 | 亚洲第一影院 | 久久免费久久 | 欧美一区二区三区视频在线 | 国产h视频在线观看免费 | 欧美日韩一区二区三区自拍 | 逼逼爱爱 | 欧美成人高清性色生活 | 国产精品一区欧美激情 | 黄色天堂网| 久久爱18 | 亚洲 欧美 日韩 综合aⅴ视频 | 国产高清不卡一区二区三区 | 国产精品久久久久久爽爽爽 | 成人99国产精品一级毛片 | 亚洲第一影院 | 亚洲一区 欧美 | 福利国产在线 | 中文字幕日本不卡一二三区 | 国产深夜福利在线观看网站 | 五月天校园春色 | 亚州五月天 | 大色欧美 | 成人免费淫片免费观看 | 精品中文字幕一区二区三区四区 | 亚洲免费网站 | 秋霞理论在线视频 | 性的小视频在线观看免费 | www.爱操| 亚洲国产成人久久99精品 | 色老久久精品偷偷鲁一区 | 性欧美videos俄罗斯 | 国产香蕉97碰碰久久人人 | 久久99精品久久久久久野外 | 一级做a级爰片性色毛片视频 |