頂點(diǎn)與片段著色器

一、頂點(diǎn)與片段著色器簡介

Vertex and FragmentShader:最強(qiáng)大的Shader類型,也是本系列的重點(diǎn),下文中簡稱V&FShader,屬于可編程渲染管線.使用的是CG/HLSL語法。分為2個(gè)部分vertex頂點(diǎn)部分和Fragment像素部分。下面依然通過寫幾個(gè)簡單的Shader來學(xué)習(xí)。

二、 CG語言一些關(guān)鍵詞和常用函數(shù)解釋

1、Cg頂點(diǎn)程序必須在結(jié)構(gòu)中傳遞頂點(diǎn)數(shù)據(jù)。幾種常用的頂點(diǎn)結(jié)構(gòu)定義在文件UnityCG.cginc中。在大部分情況下僅僅使用它們就夠了。結(jié)構(gòu)如下:

1、appdata_base: 包含頂點(diǎn)位置,法線和一個(gè)紋理坐標(biāo)。
2、appdata_tan:包含頂點(diǎn)位置,切線,法線和一個(gè)紋理坐標(biāo)。
3、appdata_full:包含位置、法線、切線、頂點(diǎn)色和兩個(gè)紋理坐標(biāo)。
4、appdata_img:包含位置和一個(gè)紋理坐標(biāo)。

2、如果你想訪問個(gè)別的頂點(diǎn)數(shù)據(jù),你必須自己聲明頂點(diǎn)結(jié)構(gòu)。結(jié)構(gòu)中的成員必須是屬于以下列表中的:

1、float4 vertex:頂點(diǎn)位置
2、float3 normal:頂點(diǎn)法線
3、float4 texcoord:第一UV坐標(biāo)
4、float4 texcoord1:第二UV坐標(biāo)
5、float4 tangent:切線向量(用在法線貼圖中)
6、float4 color:每個(gè)頂點(diǎn)(per-vertex)顏色

3、內(nèi)置矩陣

1、UNITY_MATRIX_MVP:當(dāng)前模型投影矩陣。(注:模型矩陣為 本地->世界)
2、UNITY_MATRIX_MV:當(dāng)前模型視圖矩陣
3、UNITY_MATRIX_V:當(dāng)前視圖矩陣
4、UNITY_MATRIX_P:當(dāng)前投影矩陣
5、UNITY_MATRIX_VP:當(dāng)前視圖
投影矩陣
6、UNITY_MATRIX_T_MV:轉(zhuǎn)置模型視圖矩陣
7、UNITY_MATRIX_IT_MV:逆轉(zhuǎn)置模型
視矩陣
8、UNITY_MATRIX_TEXTURE0 to UNITY_MATRIX_TEXTURE3:紋理變換矩陣

4、內(nèi)置向量

1、UNITY_LIGHTMODEL_AMBIENT:當(dāng)前環(huán)境色

三、圖形渲染的流程

20140929143233_9843.jpg

這是GPU對(duì)游戲物體進(jìn)行渲染時(shí)的流程,解釋一下為:

1、Transform:要渲染的物體在空間中的位置變換,從局部坐標(biāo)-世界坐標(biāo)-觀察坐標(biāo)系-視口坐標(biāo)系
2、TexGen:表示紋理坐標(biāo)生成,當(dāng)需要對(duì)游戲?qū)ο筮M(jìn)行貼圖時(shí),需要確定貼圖部分的紋理位置
3、Lighting:表示光照處理
4、Vertex Shader:表示頂點(diǎn)著色,主要是處理圖形中的所有頂點(diǎn)位置
5、Culling:表示剔除,將游戲物體的部分不渲染
6、Depth Test:表示深度測(cè)試,判斷游戲?qū)ο笾g的深度和遮擋
7、Texturing:表示紋理處理,貼圖
8、Fog:表示霧效果,霧參數(shù)
9、Fragment Shader:表示片段著色,對(duì)游戲?qū)ο蟮念伾M(jìn)行處理
10、Alpha Test:表示透明測(cè)試
11、Blending:表示混合

四、Unity3d 著色器語法(Shader)

Shader "name" { [Properties] Subshaders [Fallback] } 定義了一個(gè)著色器。著色器擁有一個(gè) Properties 的列表。著色器包含一個(gè)子著色器的列表(SubShaders)。并且至少包含一個(gè)(SubShader)。當(dāng)加載一個(gè)著色器時(shí),Unity 將遍歷這個(gè)列表,獲取第一個(gè)能被用戶機(jī)器支持的著色器。如果沒有子著色器被支持,Unity 將嘗試使用降級(jí) Shader(Fallback )。

1、著色器文件中的 Properties 塊定義了這些參數(shù):

1、name ("display name", Range (min, max)) = number:定義浮點(diǎn)數(shù)范圍屬性。
2、name ("display name", Color) = (number,number,number,number):定義顏色屬性。
3、name ("display name", 2D) = "name" { options }:定義2D紋理屬性。
4、name ("display name", Rect) = "name" { options }:定義長方形(非2次方)紋理屬性。
5、name ("display name", Cube) = "name" { options }:定義立方貼圖紋理屬性。
6、name ("display name", Float) = number:定義浮點(diǎn)數(shù)屬性。
7、name ("display name", Vector) = (number,number,number,number):定義一個(gè)四元素的容器(Vector4)屬性。

2、Subshader { [Tags] [CommonState] Passdef [Passdef ...] } 通過可選標(biāo)簽,通用狀態(tài)和一個(gè)Pass 定義的列表構(gòu)成了子著色器。

3、Pass { [Name and Tags] [RenderSetup] [TextureSetup] } 基本通道命令包含一個(gè)可選的渲染設(shè)置命令的列表和可選的被使用的紋理的列表。

4、Name and tags 名稱和標(biāo)簽:一個(gè)通道能定義它的 Name 和任意數(shù)量的Tags(用于向渲染引擎?zhèn)鬟f通道的意圖的名稱/值的字符串)。

5、Render Setup 渲染設(shè)置:通道設(shè)定顯示硬件的各種狀態(tài)。這些命令如下:

1、Material { Material Block }:定義一個(gè)使用頂點(diǎn)光照管線的材質(zhì)。
2、Lighting On | Off:開啟或關(guān)閉頂點(diǎn)光照。
3、Cull Back | Front | Off: 設(shè)置多邊形剔除模式。
4、ZTest (Less | Greater | LEqual | GEqual | Equal | NotEqual | Always):設(shè)置深度測(cè)試模式。
5、ZWrite On | Off:設(shè)置深度寫模式。
6、Fog { Fog Block }:設(shè)置霧參數(shù)。
7、AlphaTest (Less | Greater | LEqual | GEqual | Equal | NotEqual | Always) CutoffValue:開啟 alpha 測(cè)試。
8、Blend SourceBlendMode DestBlendMode:設(shè)置 alpha 混合模式。
9、Color Color value:設(shè)置當(dāng)頂點(diǎn)光照關(guān)閉時(shí)所使用的顏色。
10、ColorMask RGB | A | 0 | any combination of R, G, B, A:設(shè)置顏色寫遮罩。設(shè)置為0將關(guān)閉所有顏色通道的渲染。
11、Offset OffsetFactor , OffsetUnits:設(shè)置深度偏移。
12、SeparateSpecular On | Off:開啟或關(guān)閉頂點(diǎn)光照相關(guān)的平行高光顏色.
13、ColorMaterial AmbientAndDiffuse | Emission:當(dāng)計(jì)算頂點(diǎn)光照時(shí)使用每頂點(diǎn)顏色。

6、Texture Setup 紋理設(shè)置:在完成渲染設(shè)定后,你能指定一定數(shù)量的紋理和當(dāng)使用 SetTexture 命令時(shí)所采用的混合模式:

1、SetTexture texture property { [Combine options] }:紋理設(shè)置 配置了 固定函數(shù)多紋理管線,當(dāng)自定義fragment shaders 被使用時(shí),將忽略這個(gè)設(shè)置。
2、Per-pixel Lighting:每像素光照。每像素光照管線通過多次通道渲染對(duì)象來完成。Unity渲染對(duì)象一次來獲取陰影色和任何頂點(diǎn)光照。然后再在額外的并行通道中渲染出每像素光照的效果。
3、Per-vertex Lighting:每頂點(diǎn)光照。每頂點(diǎn)光照是標(biāo)準(zhǔn)的Direct3D/OpenGL光照模式,通過計(jì)算每個(gè)頂點(diǎn)的光照來完成。Lighting on命令開啟光照。光照被材質(zhì)塊,顏色材質(zhì)和平行高光命令所影響。

7、有幾個(gè)特殊的通道能用于反復(fù)利用普通功能或是實(shí)現(xiàn)幾種高端的特效:

1、UsePass:包含來自其他著色器的通道。
2、GrabPass:捕獲屏幕到一個(gè)紋理,通常使用在靠后的通道中。

8、頂點(diǎn)顏色和燈光(Color, Material, Lighting)是對(duì)任何已渲染過后的幾何體所添加的第一步效果。這個(gè)操作處在頂點(diǎn)級(jí)別,用于計(jì)算在紋理被應(yīng)用之前被使用的基礎(chǔ)顏色。頂層命令控制是否采用固定函數(shù)光照,和一些控制選項(xiàng),細(xì)節(jié)如下:

1、Color Color:設(shè)定對(duì)象的純色。顏色即可以是括號(hào)中的四值(RGBA),也可以是被方框包圍的顏色屬性名。
2、Material { Material Block }:材質(zhì)塊被用于定義對(duì)象的材質(zhì)屬性。
3、Lighting On | Off:定義材質(zhì)塊中的設(shè)定是否有效,你必須使用 Lighting On 命令開啟光照,而顏色則通過 Color 命令直接給出。
4、SeparateSpecular On | Off:這個(gè)命令會(huì)添加高光光照到著色器通道的末尾,因此貼圖對(duì)高光沒有影響。只在光照開啟時(shí)有效。
5、ColorMaterial AmbientAndDiffuse | Emission:使用每頂點(diǎn)的顏色替代材質(zhì)中的顏色集。AmbientAndDiffuse 替代材質(zhì)的陰影光和漫反射值;Emission 替代材質(zhì)中的光發(fā)射值。

9、Material Block 材質(zhì)塊,包含材質(zhì)如何和光線產(chǎn)生作用的設(shè)定。這些屬性都是可以被忽略的,默認(rèn)為值都被設(shè)定為黑色(不產(chǎn)生作用):

1、Diffuse Color:漫反射顏色構(gòu)成。這是對(duì)象的基本顏色。
2、Ambient Color:環(huán)境色顏色構(gòu)成.這是當(dāng)對(duì)象被RenderSettings. 中設(shè)定的環(huán)境色所照射時(shí)對(duì)象所表現(xiàn)的顏色。
3、Specular Color:對(duì)象反射高光的顏色。
4、Shininess Number:加亮?xí)r的光澤度,在0和1之間。0的時(shí)候你會(huì)發(fā)現(xiàn)更大的高亮也看起來像漫反射光照,1的時(shí)候你會(huì)獲得一個(gè)細(xì)微的亮斑。
5、Emission Color:自發(fā)光顏色,當(dāng)不被任何光照所照到時(shí),對(duì)象的顏色。
6、最終的計(jì)算效果是:Ambient * RenderSettings ambient setting + (Light Color * Diffuse + Light Color * Specular) + Emission。

10、剔除(Culling)是一種通過避免渲染背對(duì)觀察者的幾何體面來提高性能的優(yōu)化措施。所有幾何體都包含正面和反面。剔除基于大多數(shù)對(duì)象都是封閉的事實(shí);如果你有一個(gè)立方體,你不會(huì)看到背離你的那一面(總是只有一面在你的前方),因此我們不需要繪制出背面。因此也被稱做背面剔除。另一個(gè)使得渲染看起來正確的是深度測(cè)試(Depth Testing)。深度測(cè)試確保只有場(chǎng)景內(nèi)的對(duì)象的最靠近的表面參與繪制。

1、Cull Back(不繪制背離觀察者的幾何體面)| Front(不繪制面向觀察者的幾何體面,用于由內(nèi)自外的旋轉(zhuǎn)對(duì)象) | Off(顯示所有面,用于特殊效果):控制幾何體的那一面會(huì)被剔除(不繪制)
2、ZWrite On | Off:控制是否將來之對(duì)象的像素寫入深度緩沖(默認(rèn)開啟),如果你正繪制純色物體,將此項(xiàng)打開。如果你正繪制半透明效果,關(guān)閉深度緩沖。
3、ZTest Less | Greater | LEqual | GEqual | Equal | NotEqual | Always:深度測(cè)試如何執(zhí)行。缺省是LEqual (繪制和存在的對(duì)象一致或是在其中的對(duì)象;隱藏他們背后的對(duì)象)
4、Offset Factor , Units:允許你定義用兩個(gè)參數(shù)深度偏移。因子和單位。Factor 縮放Z的最大斜率,幾何體的X和Y也一樣,units縮放可計(jì)算的深度緩沖值。這允許你迫使一個(gè)幾何體繪制在另一個(gè)的上層,盡管他們實(shí)際上是在同一個(gè)位置。例如偏移0,-1使得靠近攝像機(jī)的幾何體忽略幾何體的斜率,而偏移-1,-1則會(huì)幾何體在一個(gè)幾乎擦過的角度被觀察使看起來更近些。

11、紋理(Texturing)在基本的頂點(diǎn)光照被計(jì)算后被應(yīng)用。在著色器中通過 SetTexture 命令來完成。SetTexture 命令在片面程序被使用時(shí)不會(huì)生效;這種模式下像素操作被完全描述在著色器中。材質(zhì)貼圖可以用來做老風(fēng)格的混合器效果。你能在一個(gè)通道中使用多個(gè)SetTexture 命令 - 所有紋理被順序的應(yīng)用,如同繪畫程序中的層一樣。SetTexture 命令必須放置在通道的末尾。

12、SetTexture [TexturePropertyName] { Texture Block }:分配一個(gè)紋理,TextureName 必須定義為一個(gè)紋理屬性。如何應(yīng)用紋理被定義在 TextrueBlock 中。紋理塊控制紋理如何被應(yīng)用。在紋理塊中能執(zhí)行3種命令:合并,矩陣和不變色。

13、紋理塊合并(Combine)命令:

1、combine src1 * src2:將源1和源2的元素相乘。結(jié)果會(huì)比單獨(dú)輸出任何一個(gè)都要暗。
2、combine src1 + src2:將將源1和源2的元素相加。結(jié)果會(huì)比單獨(dú)輸出任何一個(gè)都要亮。
3、combine src1 - src2:源1減去源2。
4、combine src1 +- src2:先相加,然后減去0.5(添加了一個(gè)符號(hào))。
5、combine src1 lerp (src2) src3:使用源2的透明度通道值在源3和源1中進(jìn)行差值,注意差值是反向的:當(dāng)透明度值是1是使用源1,透明度為0時(shí)使用源3。
6、combine src1 * src2 + src3:源1和源2的透明度相乘,然后加上源3。
7、combine src1 * src2 +- src3:源1和源2的透明度相乘,然后和源3做符號(hào)加。8、combine src1 * src2 - src3:源1和源2的透明度相乘,然后和源3相減。所有源屬性都可以是 Previous(上一次 SetTexture 的結(jié)果)、Constant(被 ConstantColor 定義的顏色)、 Primary(來自光照計(jì)算的顏色或是當(dāng)它綁定時(shí)的頂點(diǎn)顏色)、Texture(在 SetTexture 中被定義的紋理的顏色)其中的一個(gè)。

14、紋理塊不變色(ConstantColor)命令:

1、ConstantColor color:定義在combine命令中能被使用的不變顏色。

15、紋理塊矩陣(Matrix)命令:

1、matrix [MatrixPropertyName]:使用給定矩陣變換紋理坐標(biāo)。

16、霧(Fog)參數(shù)用于霧命令控制。霧化是通過混合已生成的像素的顏色和基于到鏡頭的距離來確定的一個(gè)不變色來完成。霧化不會(huì)改變已經(jīng)混合的像素的透明度值,只是改變RGB值。

17、Fog { Fog Commands }:在大括號(hào)中設(shè)定霧命令的內(nèi)容

1、Mode Off | Global | Linear | Exp | Exp2:定義霧模式。缺省是全局的,依據(jù)霧在渲染設(shè)定中是否打開確定可從無變化到平方值。
2、Color ColorValue:設(shè)定霧的顏色。
3、Density FloatValue:以指數(shù)的方式 設(shè)定霧的密度。
4、Range FloatValue , FloatValue:為 linear 的霧設(shè)定遠(yuǎn)近距離。

18、透明度測(cè)試(Alpha testing)是阻止像素被寫到屏幕的最后機(jī)會(huì)。在最終渲染出的顏色被計(jì)算出來之后,可選擇通過將顏色的透明度值和一個(gè)固定值比較。如果比較的結(jié)果失敗,像素將不會(huì)被寫到顯示輸出中。

1、AlphaTest Off:渲染所有像素(缺?。?。
2、AlphaTest Greater(大于)| GEqual(大于等于)| Less(小于)| LEqual(小于等于)| Equal(等于)| NotEqual(不等于)| Always(渲染所有像素)| Never(不渲染任何像素) AlphaValue(一個(gè)范圍在0到1之間的浮點(diǎn)值。也可以是一個(gè)指向浮點(diǎn)屬性或是范圍屬性的索引,在后一種情況下需要使用標(biāo)準(zhǔn)的方括號(hào)寫法標(biāo)注索引名字,如([變量名])):設(shè)定透明度測(cè)試只渲染在某一確定范圍內(nèi)的透明度值的像素。

19、混合(Blending)被用于制作透明物體。當(dāng)圖像被渲染時(shí),所有著色器被執(zhí)行以后,所有貼圖被應(yīng)用后,像素將被寫到屏幕。通過 Blend 命令控制和已有的圖像合并:

1、Blend Off:關(guān)閉混合。
2、Blend SrcFactor DstFactor: 配置并啟動(dòng)混合。產(chǎn)生的顏色被乘以 SrcFactor,已存在于屏幕的顏色乘以 DstFactor,并且兩者將被疊加在一起。
3、Blend SrcFactor DstFactor, SrcFactorA DstFactorA:同上,但是使用不同的要素來混合 alpha 通道。4、BlendOp Min | Max | Sub | RevSub:不是添加混合顏色在一起,而是對(duì)它們做不同的操作。

20、以下所有屬性對(duì)SrcFactor或DstFactor都可用。Source 指的是被計(jì)算的顏色,Destination 是已經(jīng)在屏幕上的顏色。

1、One:值為1,使用此設(shè)置來讓源(Source)或是目標(biāo)顏色(Destination)完全的通過。
2、Zero:值為0,使用此設(shè)置來刪除源(Source)或目標(biāo)值(Destination)。
3、SrcColor:此階段的值是乘以源顏色(Source)的值。
4、SrcAlpha:此階段的值是乘以源(Source)alpha 的值。
5、DstColor:此階段的值是乘以幀緩沖區(qū)源顏色(Source)的值。
6、DstAlpha:此階段的值是乘以幀緩沖區(qū)源(Source)alpha 的值。
7、OneMinusSrcColor:此階段的值是乘以(1 - 源顏色(Source))。
8、OneMinusSrcAlpha:此階段的值是乘以(1 - 源(Source)alpha)。
9、OneMinusDstColor:此階段的值是乘以(1 - 目標(biāo)顏色(Destination))。
10、OneMinusDstAlpha:此階段的值是乘以(1 - 目標(biāo)(Destination)alpha)。

21、Tags { "TagName1" = "Value1" "TagName2" = "Value2" }:指定TagName1 的值為 Value1 ,TagName2 的值為 Value2 你可以指定很多你喜歡的標(biāo)簽。通過使用標(biāo)簽(Pass Tags)來告訴渲染引擎在什么時(shí)候該如何渲染他們所期望的效果。

22、LightMode 標(biāo)簽定義了光照點(diǎn)中的 Pass 任務(wù)。可選值如下:

1、Always:總是渲染。沒有光照應(yīng)用。
2、ForwardBase:用于正向渲染,環(huán)境主要方向燈和定點(diǎn)光/SH 等的應(yīng)用。
3、ForwardAdd:用于正向渲染,附加的像素光被應(yīng)用,每個(gè)光照一個(gè) pass。
4、PrepassBase:用于延遲光照,渲染法線/鏡面指數(shù)。
5、PrepassFinal:用于延遲光照,通過結(jié)合紋理,光照和自發(fā)光渲染最終顏色。
6、Vertex:用于頂點(diǎn)光照渲染,當(dāng)物體沒有光照映射時(shí),所有頂點(diǎn)光照被應(yīng)用。
7、VertexLMRGBM:用于頂點(diǎn)光照渲染,當(dāng)物體有光照映射的時(shí)候使用頂點(diǎn)光照渲染。在平臺(tái)上光照映射是 RGBM 編碼。
8、VertexLM:用于頂點(diǎn)光照渲染,當(dāng)物體有光照映射的時(shí)候使用頂點(diǎn)光照渲染。在平臺(tái)上光照映射是double-LDR 編碼(移動(dòng)平臺(tái),及老式臺(tái)式CPU)。
9、ShadowCaster:將物體當(dāng)做陰影產(chǎn)生者來渲染。
10、ShadowCollector:為了正向渲染對(duì)象的路徑,將對(duì)象的陰影收集到屏幕空間緩沖區(qū)中。

23、Name "PassName":為當(dāng)前通道命名 PassName。一個(gè)通道能被賦予一個(gè)名字以便UsePass 命令能索引到它。

24、BindChannels { Bind "source", target }:允許你指定頂點(diǎn)數(shù)據(jù)如何映射到顯卡中。

25、Source 可以是下面其中一個(gè):

1、Vertex: vertex position 頂點(diǎn):頂點(diǎn)的位置。
2、Normal: vertex normal 法線:頂點(diǎn)的法線。
3、Tangent: vertex tangent 切線:頂點(diǎn)的切線。
4、Texcoord: primary UV coordinate 主要的UV坐標(biāo)。
5、Texcoord1: secondary UV coordinate 次要的UV坐標(biāo)。
6、Color: per-vertex color 顏色:每個(gè)頂點(diǎn)顏色。

26、Target 可以是下面其中的一個(gè):

1、Vertex: vertex position 頂點(diǎn):頂點(diǎn)的位置。
2、Normal: vertex normal 法線:頂點(diǎn)的法線。
3、Tangent: vertex tangent 切線:頂點(diǎn)的切線。
4、Texcoord0, Texcoord1, ...: texture coordinates for corresponding texture stage 各個(gè)紋理處理階段的紋理坐標(biāo)。
5、Texcoord: texture coordinates for all texture stages 所有紋理處理階段的紋理坐標(biāo)。
6、Color: vertex color 顏色:頂點(diǎn)顏色。

五、使用頂點(diǎn)和片段著色器寫幾個(gè)小例子

1、顏色的變換

1)、渲染一個(gè)面片的顏色

使用unity,Asset>右鍵創(chuàng)建一個(gè)shader>創(chuàng)建一個(gè)Material>將shader添加到Material上>在Heriarchy中創(chuàng)建一個(gè)Quad>將Material添加到Quad上>打開創(chuàng)建的Shader

//Shader的名字和儲(chǔ)存的位置
Shader "Custom/VertexFragmentBase1" {
//子著色器
   SubShader
   {
       //子著色器的Tags值,渲染方式為Opaque,可以渲染大部分不透明的游戲?qū)ο?       Tags{"RenderType"="Opaque"}
       //LOD通道
       LOD 200
       //渲染通道
       Pass
       {
           //cg語言開始標(biāo)識(shí)
           CGPROGRAM
           //可以理解為引用定義一個(gè)vertex的方法,方法名vert(頂點(diǎn)著色方法)
           #pragma vertex vert
           //片段著色方法
           #pragma fragment frag
           //應(yīng)用UnityCG庫中的cginc,包含大多可以用的結(jié)構(gòu)體
           #include "UnityCG.cginc"
           //自定義一個(gè)儲(chǔ)存頂點(diǎn)位置的結(jié)構(gòu)體v2f
           struct v2f
           {
               //定義一個(gè)float4的頂點(diǎn)位置變量
               float4 pos:POSITION;
           };
           //自定義一個(gè)儲(chǔ)存顏色的結(jié)構(gòu)體v2c
           struct v2c
           {
               //定義一個(gè)fixed4的顏色變量
               fixed4 col:Color;
           };
           //vert方法,將頂點(diǎn)的空間坐標(biāo)轉(zhuǎn)換為屏幕坐標(biāo),appdata_base是UnityCG.cginc中的一個(gè)結(jié)構(gòu)體,儲(chǔ)存了位置、法線和紋理
           v2f vert(appdata_base v)
           {
               v2f o;
               //將頂點(diǎn)的本地坐標(biāo)轉(zhuǎn)換為世界坐標(biāo)(屏幕坐標(biāo))
               o.pos=mul(UNITY_MATRIX_MVP,v.vertex);
               return o;
           }
           //片段方法,給游戲?qū)ο蟮乃许旤c(diǎn)著色
           v2c frag()
           {
               v2c c;
               //著色
               c.col=fixed4(0,1,1,0);
               return c;
           }
           //cg語言結(jié)束標(biāo)識(shí)
           ENDCG
       }
       
   }
}

效果如圖:
![~V@])V67WVD(@$A7G8AVUSQ.png](http://upload-images.jianshu.io/upload_images/2381726-204d10d7182c5114.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

2)、實(shí)現(xiàn)游戲?qū)ο蟮念伾S程序的運(yùn)行而變化

使用unity,Asset>右鍵創(chuàng)建一個(gè)shader>創(chuàng)建一個(gè)Material>將shader添加到Material上>在Heriarchy中創(chuàng)建一個(gè)Quad>將Material添加到Quad上>打開創(chuàng)建的Shader
效果如圖:


顏色變換.gif

實(shí)現(xiàn)的秘密是將顏色的rgb值由常量改為隨程序運(yùn)行時(shí)間變化的變量,實(shí)現(xiàn)的代碼如下(將frag方法改寫):

//片段方法,給游戲?qū)ο蟮乃许旤c(diǎn)著色
        v2c frag(v2f IN)
        {
            v2c c;
            fixed r=abs(sin(_Time*10));
            fixed g=abs(cos(_Time*10));
            fixed b=abs(tan(_Time*10));
            c.col=fixed4(r,g,b,1);
            return c;
        }

3)、實(shí)現(xiàn)游戲?qū)ο蟮念伾S游戲?qū)ο笤谄聊坏奈恢玫淖兓兓?/h4>

使用unity,Asset>右鍵創(chuàng)建一個(gè)shader>創(chuàng)建一個(gè)Material>將shader添加到Material上>在Heriarchy中創(chuàng)建一個(gè)Quad>將Material添加到Quad上>打開創(chuàng)建的Shader
效果如圖:


顏色隨屏幕位置變換.gif

實(shí)現(xiàn)的秘密是將顏色的rgb值由常量改為隨游戲?qū)ο笤谄聊簧衔灰谱兓淖兞?,?shí)現(xiàn)的代碼如下(將frag方法改寫):

//片段方法,給游戲?qū)ο蟮乃许旤c(diǎn)著色
        v2c frag(v2f IN)
        {
            v2c c;
            //用頂點(diǎn)的xy除以屏幕參數(shù)的xy
            c.col=fixed4(IN.pos.xy/_ScreenParams.xy,0,1);
            return c;
        }

2、添加紋理貼圖

有了顏色之后,我們?nèi)绾翁砑右粡埣y理貼圖呢?還是相同的邏輯,先定義一張紋理貼圖,然后獲得紋理貼圖的頂點(diǎn)坐標(biāo)和片段顏色,進(jìn)行賦值處理即可,具體看下面代碼:

Shader "Custom/VertexFragmentBase2" {
    Properties {
        //定義一個(gè)紋理貼圖
        _MainTex ("MainTex", 2D) = "white" {}
    }
    SubShader {
        Tags { "RenderType"="Opaque" }
        LOD 200
        Pass
        {
            CGPROGRAM
            //聲明
            #pragma vertex vert 
            #pragma fragment frag
            #include "UnityCG.cginc"

            //使用sampler2D來儲(chǔ)存貼圖
            sampler2D _MainTex;
            //_MainTex_ST的ST是SamplerTexture的意思 ,就是聲明_MainTex是一張采樣圖,也就是會(huì)進(jìn)行UV運(yùn)算
            float4 _MainTex_ST;

            struct v2f 
            {
                float4 pos:POSITION;
                fixed2 uv:TEXCOORD;
            };

            struct v2c
            {
                fixed4 col:Color;
            };

             v2f vert(appdata_base v)
            {
                v2f o;
                //將游戲?qū)ο蟮捻旤c(diǎn)坐標(biāo)轉(zhuǎn)換為世界坐標(biāo)
                o.pos=mul(UNITY_MATRIX_MVP,v.vertex);
                //TRANSFORM_TEX主要作用是拿頂點(diǎn)的uv去和材質(zhì)球的tiling和offset作運(yùn)算, 確保材質(zhì)球里的縮放和偏移設(shè)置是正確的
                //v.texcoord就是頂點(diǎn)的uv
                o.uv =TRANSFORM_TEX(v.texcoord,_MainTex);
                return o;
            }

            v2c frag(v2f o)
            {
                v2c c ;
                c.col = tex2D(_MainTex,o.uv);
                return c ;
            }
            ENDCG
            
        }
        
    }
    FallBack "Diffuse"
}

貼出效果圖:


Y6U@X1GA(HK(7KI25@G2%OT.png

3、制作動(dòng)態(tài)地球

地球旋轉(zhuǎn).gif

不細(xì)說了,主要看代碼,很詳細(xì),如何使地球自轉(zhuǎn),如何制作出云霧效果

Shader "Custom/EarthShader" {
    Properties
    {
        //主貼圖(地球)
        _MainTex("MainTex",2D)=""{}
        //云貼圖(云)
        _CloudTex("CloudTex",2D)=""{}
    }

    SubShader
    {
        Tags{"RenderType" = "Transparent" "Queue" = "Transparent "}
        LOD 200 
        //混合
        /*
        Alpha Blending,中文譯作Alpha混合
        Blending就是控制透明的。處于光柵化的最后階段。
        這里例如我們給一個(gè)模型貼一個(gè)材質(zhì),那么在某個(gè)點(diǎn)計(jì)算出來顏色值稱為源,而該點(diǎn)之前累積的顏色值,叫目標(biāo)。

        語法
        Blend Off     不混合
        Blend SrcFactor DstFactor  SrcFactor是源系數(shù),DstFactor是目標(biāo)系數(shù)
        最終顏色 = (Shader計(jì)算出的點(diǎn)顏色值 * 源系數(shù))+(點(diǎn)累積顏色 * 目標(biāo)系數(shù))

        屬性(往SrcFactor,DstFactor 上填的值)
        one                          1
        zero                         0
        SrcColor                         源的RGB值,例如(0.5,0.4,1)
        SrcAlpha                         源的A值, 例如0.6
        DstColor                   混合目標(biāo)的RGB值例如(0.5,0.4,1)
        DstAlpha                         混合目標(biāo)的A值例如0.6
        OneMinusSrcColor          (1,1,1) - SrcColor
        OneMinusSrcAlpha          1- SrcAlpha
        OneMinusDstColor          (1,1,1) - DstColor
        OneMinusDstAlpha          1- DstAlpha

        運(yùn)算法則示例:
        (注:r,g,b,a,x,y,z取值范圍為[0,1])
        (r,g,b) * a = (r*a , g*a , b*a)
        (r,g,b) * (x,y,z) = (r*x , g*y , b*z)
        (r,g,b) + (x,y,z) = (r+x , g+y , b+z)
        (r,g,b) - (x,y,z)  = (r-x , g-y , b-z)
        */
        
        Blend SrcAlpha OneMinusSrcAlpha
        Pass
        {
            CGPROGRAM
            //聲明
            #pragma vertex vert 
            #pragma fragment frag 
            #include "UnityCG.cginc"

            //儲(chǔ)存貼圖
            sampler2D _MainTex;
            sampler2D _CloudTex;
            //聲明
            float4 _MainTex_ST;

            struct v2f
            {
                float4 pos:POSITION;
                fixed2 uv:TEXCOORD;
            };
            
            v2f vert(appdata_base v )
            {
                v2f o;
                o.pos = mul(UNITY_MATRIX_MVP,v.vertex);
                o.uv = TRANSFORM_TEX(v.texcoord,_MainTex);
                return o;
            }

            fixed4 frag(v2f o):Color
            {
                //地球自轉(zhuǎn)
                fixed x = o.uv.x-_Time;
                fixed2 uv = fixed2(x,o.uv.y);
                fixed4 col=tex2D(_MainTex,uv);
                //云的旋轉(zhuǎn)速度比地球快
                x = o.uv.x -_Time*1.8;
                fixed2 uv2=fixed2(x,o.uv.y);
                fixed4 cloud =tex2D(_CloudTex,uv2);
                //將CloudTex貼圖上轉(zhuǎn)變成紅色通道(即將紅色轉(zhuǎn)變?yōu)榘咨?                cloud =fixed4(1,1,1,0)*cloud.r;
                return lerp(col,col + cloud,0.5f);
            }
            ENDCG
        
        }
    
    
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Babybus-u3d技術(shù)交流-【淺墨Unity3D Shader編程】之二 雪山飛狐篇:Unity的基本Shad...
    Babybus_Unity閱讀 5,883評(píng)論 4 61
  • <轉(zhuǎn)>我也忘了轉(zhuǎn)自哪里,抱歉,感謝原作者 什么是Shader Shader(著色器)是一段能夠針對(duì)3D對(duì)象進(jìn)行操作...
    星易乾川閱讀 5,851評(píng)論 1 16
  • 一天,賣花的小姑娘剩了兩朵玫瑰花,怎么也買不出去,看著天色已晚,小姑娘就把手里的花送給路邊的兩個(gè)乞丐,高高興興的回...
    心依舊每天1000字閱讀 769評(píng)論 2 4
  • 日日望兩眼,天天盼花顏。 沒現(xiàn)芳容面,卻見蕾萎蔫。 轉(zhuǎn)移戰(zhàn)場(chǎng)看,尚有野花鮮。 不聞不問管,花事照常燦。 一早又看蘭...
    相逢萍水閱讀 260評(píng)論 1 4
  • 每次去大海都很留戀 就像海子的詩里寫的那樣 我想有一所房子 面朝大海 春暖花開
    蘇小柚閱讀 372評(píng)論 0 3

友情鏈接更多精彩內(nèi)容