本系列文章由@淺墨_毛星云 出品,轉(zhuǎn)載請注明出處。 文章鏈接: http://blog.csdn.net/poem_qianmo/article/details/41175585 作者:毛星云(淺墨) 微博:http://weibo.com/u/1723155442 郵箱: happylifemxy@163.com
本文介紹了Unity中子著色器、通道和標簽相關的詳細概念與寫法,以及紋理的設置方法,基本的紋理混合寫法,寫了5個Shader作為本文Shader講解的實戰(zhàn)內(nèi)容,最后創(chuàng)建了一個夢幻的光之城堡場景進行了Shader的測試。依舊是國際慣例,先上本文配套程序的截圖。
光之城堡: 
山坡上遠眺: 
通向森林的路: 
古墓: 
霧氣氤氳的森林:  來一張上帝視角: 
OK,圖先就上這么多。文章末尾有更多的運行截圖,并提供了原工程的下載??蛇\行的exe下載在這里: 【游戲場景可運行的exe請點擊這里下載試玩】 我們正式開始。
一、子著色器(SubShader)相關內(nèi)容講解
話不多說,我們接著上篇文章繼續(xù)講。 Unity中的每一個著色器都包含一個subshader的列表,當Unity需要顯示一個網(wǎng)格時,它能發(fā)現(xiàn)使用的著色器,并提取第一個能運行在當前用戶的顯示卡上的子著色器。 我們知道,子著色器定義了一個渲染通道的列表,并可選是否為所有通道初始化所需要的通用狀態(tài)。子著色器的寫法如下: Subshader{ [Tags] [CommonState] Passdef [Passdef ...] } 也就是通過可選標簽,通用狀態(tài) 和 一個Pass 定義的列表構(gòu)成了子著色器。 當Unity選擇用于渲染的子著色器時,它為每一個被定義的通道渲染一次對象(可能會更多,這取決于光線的交互作用)。當對象的每一次渲染都是很費資源之時,我們便使用盡量少的通道來定義一個著色器。當然,有時在一些顯示硬件上需要的效果不能通過單次通道來完成。自然就得使用多通道的子著色器了。 另外,通道定義的類型包括a regular Pass, a Use Pass or aGrab Pass。 任何出現(xiàn)在通道定義的狀態(tài)同時也能整個子著色器塊中可見。這將使得所有通道共享狀態(tài)。
1.1 關于子著色器標簽(SubShader Tags) 子著色器使用標簽來告訴渲染引擎期望何時和如何渲染對象。其語法如下: Tags { 'TagName1' ='Value1' 'TagName2' = 'Value2' } 也就是,為標簽'TagName1'指定值'Value1'。為標簽'TagName2'指定值'Value2'。我們可以設定任意多的標簽。 標簽是標準的鍵值對,也就是可以根據(jù)一個鍵值獲得對應的一個值的。SubShader 中的標簽是用來決定渲染的次序和子著色器中的其他變量的。
1.1.1 決定渲染次序——隊列標簽(Queue tag)
我們可以使用 Queue 標簽來決定對象被渲染的次序。著色器決定它所歸屬的對象的渲染隊列,任何透明渲染器可以通過這個辦法保證在所有不透明對象渲染完畢后再進行渲染。
有四種預定義(predefined)的渲染隊列,在預定義隊列之間還可以定義更多的隊列。這四種預定義的標簽如下: - 后臺(Background) - 這個渲染隊列在所有隊列之前被渲染,被用于渲染天空盒之類的對象。
- 幾何體(Geometry,默認值)- 這個隊列被用于大多數(shù)對象。 不透明的幾何體使用這個隊列。
- 透明(Transparent) - 這個渲染隊列在幾何體隊列之后被渲染,采用由后到前的次序。任何采用alpha混合的對象(也就是不對深度緩沖產(chǎn)生寫操作的著色器)應該在這里渲染(如玻璃,粒子效果等)
- 覆蓋(Overlay) - 這個渲染隊列被用于實現(xiàn)疊加效果。任何需要最后渲染的對象應該放置在此處。(如鏡頭光暈等)
一個使用Tags的示例如下:
Shader 'Transparent QueueExample'{ SubShader{//寫上Tags標簽 Tags {'Queue' = 'Transparent' } //開始一個通道 Pass{ // 寫Shader實體內(nèi)容 } }}
1.1.2 自定義中間隊列
讓我們來舉例說明如何在透明隊列中渲染對象。一般情況下,幾何體渲染隊列為了達到最優(yōu)的性能優(yōu)化了對象的繪制次序。而其他渲染隊列依據(jù)舉例排序?qū)ο?,從最遠的對象開始渲染到最近的對象。 而對于特殊的需要,可以使用中間隊列來滿足。在Unity實現(xiàn)中每一個隊列都被一個整數(shù)的索引值所代表。后臺為1000,幾何體為2000,透明為3000,疊加層為4000. 著色器可以自定義一個隊列,如: Tags { 'Queue' ='Geometry+1' } 因為渲染隊列是從小到大來數(shù)的,這就會使對象在所有不透明的對象渲染之后但卻在所有透明物體前被渲染,該渲染隊列的索引值為2001。當我們希望某些對象總是在其他某些對象前被繪制的情況下,這用起來就很方便了。比如,在絕大多數(shù)時候,透明的水總是應該在所有不透明的物體之后并在透明對象前被渲染,這就可以通過中間隊列來滿足渲染需求。
1.1.3 關于忽略投影標簽(IgnoreProjector tag)
后面我們會接觸到,若設置IgnoreProjector(忽略投影)標簽為'True',那么使用這個著色器的對象就不會被投影機制(Projectors)所影響。這對半透明的物體來說是一個福利,因為暫時沒有對他們產(chǎn)生投影的比較合適的辦法,那么直接忽略掉就行了。
二、 通道(Pass)相關內(nèi)容講解
Pass通道塊控制被渲染的對象的幾何體。其語法定義是這樣的: Pass { [Name and Tags] [RenderSetup][TextureSetup] } 基本通道命令包含一個可選的渲染設置命令的列表,和可選的被使用的紋理的列表。
2.1 通道中的名稱與標簽(Name and tags )
一個通道能定義它的Name 和任意數(shù)量的Tags。通過使用tags來告訴渲染引擎在什么時候該如何渲染他們所期望的效果。語法如下: Tags { 'TagName1' ='Value1' 'TagName2' = 'Value2' } 指定TagName1 的值為Value1 ,TagName2 的值為 Value2 你可以指定很多自己喜歡的標簽,下面會詳細來列舉。
標簽基本上是鍵-值對的形式。 內(nèi)部的Pass標簽用來控制光照管道(環(huán)境光照,頂點光照和像素光照)中pass 的任務和一些其它選項。注意以下的標簽必須在pass段內(nèi)部,而不是在SubShader中被識別。
2.1.1 光照模式標簽(LightMode tag) LightMode 標簽定義了Shader的光照模式,具體含義以后會在講渲染管線時講到。下面我們先簡單了解一下有哪些光照模式可選,以及他們的具體作用: - Always: 總是渲染。沒有運用光照。
- ForwardBase:用于正向渲染,環(huán)境光、方向光和頂點光等
- ForwardAdd:用于正向渲染,用于設定附加的像素光,每個光照對應一個pass
- PrepassBase:用于延遲光照,渲染法線/鏡面光。
- PrepassFinal:用于延遲光照,通過結(jié)合紋理,光照和自發(fā)光渲染最終顏色
- Vertex: 用于頂點光照渲染,當物體沒有光照映射時,應用所有的頂點光照
- VertexLMRGBM:用于頂點光照渲染,當物體有光照映射的時候使用頂點光照渲染。在平臺上光照映射是RGBM 編碼
- VertexLM:用于頂點光照渲染,當物體有光照映射的時候使用頂點光照渲染。在平臺上光照映射是double-LDR 編碼(移動平臺,及老式臺式CPU)
- ShadowCaster: 使物體投射陰影。
- ShadowCollector: 為正向渲染對象的路徑,將對象的陰影收集到屏幕空間緩沖區(qū)中。
2.1.2 條件選項標簽 (RequireOptions tag )
若想要在一些外部條件得到滿足時某pass才渲染,就可以通過使用RequireOptions標簽,它的值是一個空格分割的字符串,目前由Unity3d支持的選項只有一個,就是渲染植被之時: SoftVegetation: 如果在QualitySettings中開啟渲染軟植被(Edit->Project Settings->Quality),則該pass可以渲染 2.2 關于渲染設置 (Render Setup ) 通道設定顯示硬件的各種狀態(tài),例如能打開alpha混合,能使用霧,等等。這些命令如下: Material { Material Block } 定義一個使用頂點光照管線的材質(zhì),詳情參考上次我們講的Material Lighting On | Off 開啟或關閉頂點光照。開啟燈光之后,頂點光照才會有作用 Cull Back | Front | Off 設置多邊形剔除模式,詳細內(nèi)容后面的文章會講解到。 ZTest (Less | Greater | LEqual | GEqual |Equal | NotEqual | Always) 設置深度測試模式,詳細內(nèi)容后面的文章會講解到。 ZWrite On | Off 設置深度寫模式,詳細內(nèi)容后面的文章會講解到。 Fog { Fog Block } 設置霧參數(shù),詳細內(nèi)容后面的文章會講解到。 AlphaTest (Less | Greater | LEqual | GEqual| Equal | NotEqual | Always) CutoffValue 開啟alpha測試 Blend SourceBlendMode |DestBlendMode 設置alpha混合模式 Color Color value 設置當頂點光照關閉時所使用的顏色 ColorMask RGB | A | 0 | any combination of R, G, B, A 設置顏色寫遮罩。設置為0將關閉所有顏色通道的渲染 Offset OffsetFactor , OffsetUnits 設置深度偏移 SeparateSpecular On | Off 開啟或關閉頂點光照相關的平行高光顏色。 ColorMaterial AmbientAndDiffuse | Emission 當計算頂點光照時使用每頂點的顏色
2.3 關于紋理設置(Texture Setup )
在完成渲染設定后,我們可以指定一定數(shù)量的紋理和當使用 SetTexture 命令時所采用的混合模式: SetTexture [texture property]{ [Combineoptions] } 紋理設置,用于配置固定函數(shù)多紋理管線,當自定義fragment shaders 被使用時,這個設置也就被忽略掉了。
2.4 一些細節(jié)
2.4.1 關于每像素光照(Per-pixel Lighting ) 每像素光照管線通過多次通道渲染對象來完成。Unity渲染對象一次來獲取陰影色和任何頂點光照。然后再在額外的并行通道中渲染出每像素光照的效果。
2.4.2 關于每頂點光照(Per-vertex Lighting)
每頂點光照是標準的Direct3D/OpenGL光照模式,通過計算每個頂點的光照來完成。Lighting on命令開啟光照。而我們知道,光照被材質(zhì)塊,顏色材質(zhì)和平行高光等命令所影響。
2.5 一些高端特效的通道命令 有時候,我們會寫一些特殊的通道,要多次反復利用普通的功能或是實現(xiàn)高端的特效。應對這些情況,Unity中就有一些高級點武器可以選用,這里簡單講一講吧,現(xiàn)在先稍微有個概念就好。
2.5.1 UsePass——包含已經(jīng)寫好的通道
UsePass 可以包含來自其他著色器的通道,來減少重復的代碼。 例如,在許多像素光照著色器中,陰影色或頂點光照通道在在相應的頂點光照著色器中是相同的。UsePass命令只是包含了另一個著色器的給定通道。例如如下的命令可以使用內(nèi)置的高光著色器中的名叫'Base'的通道: UsePass 'Specular/BASE' 而為了讓UsePass能夠認識到指定的是誰,必須給希望使用的通道命名,弄個身份證。通道中的Name命令就是這個功能: Name 'MyPassName'
2.5.2 GrabPass——捕獲屏幕內(nèi)容到紋理中
GrabPass 可以捕獲物體所在位置的屏幕的內(nèi)容并寫入到一個紋理中,通常在靠后的通道中使用,這個紋理能被用于后續(xù)的通道中完成一些高級圖像特效。 一個示例如下: Shader 'GrabPassInvert'{SubShader{ //在所有不透明幾何體之后繪制 Tags { 'Queue' = 'Transparent' } //捕獲對象后的屏幕到_GrabTexture中 GrabPass { } //用前面捕獲的紋理渲染對象,并反相它的顏色 Pass { SetTexture [_GrabTexture] { combine one-texture } } }}
三、紋理(Texturing)相關內(nèi)容講解
紋理在基本的頂點光照計算完成之后被應用,這也就是SetTexture 命令必須放置在通道的末尾的原因了。在著色器中通過SetTexture 命令來完成。 需要注意的是,SetTexture 命令在使用了片段著色器時不會生效;因為在片段著色器下像素操作被完全描述在著色器中。
 材質(zhì)貼圖可以用來實現(xiàn)舊式風格的混合器效果。我們可以在一個通道中使用多個SetTexture命令, SetTexture所有紋理都是按代碼順序來添加的,也就是如同Photoshop中的圖層操作一樣。SetTexture的語法如下:
SetTexture [TexturePropertyName] { TextureBlock }
解釋:分配一個紋理,其中TexturePropertyName必須為一個紋理,也就是在shader最開始的Properties中的屬性。在TextrueBlock中設置如何應用紋理,即紋理塊控制紋理如何被應用。而在紋理塊中能執(zhí)行3種命令:合并操作,矩陣操作、與常量顏色進行混合操作。
3.1 紋理合并命令
combine src1 * src2 將源1和源2的元素相乘。結(jié)果會比單獨輸出任何一個都要暗 combine src1 + src2 將將源1和源2的元素相加。結(jié)果會比單獨輸出任何一個都要亮 combine src1 - src2 源1 減去 源2 combine src1 +- src2 先相加,然后減去0.5(也就是添加了一個符號) combine src1 lerp (src2) src3 使用源2的透明度通道值在源3和源1中進行差值,注意差值是反向的:當透明度值是1是使用源1,透明度為0時使用源3 combine src1 * src2 + src3 源1和源2的透明度相乘,然后加上源3 combine src1 * src2 +- src3 源1和源2的透明度相乘,然后和源3做符號加 combine src1 * src2 - src3 源1和源2的透明度相乘,然后和源3相減 其中,所有src屬性都可以是previous,constant, primary or texture其中的一個。
- Previous 是上一次SetTexture的結(jié)果
- Primary 是來自光照計算的顏色或是當它綁定時的頂點顏色
- Texture是在SetTexture中被定義的紋理的顏色
- Constant是被ConstantColor定義的顏色
一些小技巧:
1.上述的公式都均能通過關鍵字 Double 或是 Quad 將最終顏色調(diào)高亮度2倍或4倍。 2.所有的src屬性,除了差值參數(shù)都能被標記一個“-”負號來使最終顏色反相。 3.所有src屬性能通過跟隨 alpha 標簽來表示只取用alpha通道。 3.2 顏色常量命令
ConstantColor color 定義在combine命令中能被使用的常量顏色 3.3 紋理矩陣命令
matrix [MatrixPropertyName] 使用給定矩陣變換紋理坐標 3.4 一些細節(jié)
較老的顯卡對紋理一般會使用分層的操作方案,而紋理在每一層后被應用一次顏色的修改。對每一個紋理,一般來說紋理都是和上一次操作的結(jié)果混合,如圖:  需要注意的是,對于“純正”的“固定功能流水線”設備(比如說OpenGL, OpenGL ES 1.1, Wii),每個SetTexture階段的值被限制為0到1的范圍之間。而其他的設備(如Direct3D, OpenGL ES 2.0)中,這個范圍就不一定是固定的。這種情況就可能會影響SetTexture階段,可能使產(chǎn)生的值高于1.0。
3.4.1 關于分離的透明度和顏色混合(Separate Alpha & Color computation)
在默認情況下,混合公式被同時用于計算紋理的RGB通道和透明度。同時,我們也能指定針對透明度來單獨計算,比如這樣,將RGB操作和Alpha操作隔開:
SetTexture [_MainTex] { combine previous *texture, previous + texture }
如上所述,我們對RGB的顏色做乘然后對Alpha透明度相加
3.4.2 關于反射高光(Specular highlights)
默認情況下primary顏色是漫反射,陰影色和高光顏色(在光線計算中定義)的加和。如果我們將通道設置中的SeparateSpecular On 寫上,高光色便會在混合計算后被加入,而不是之前。PS:Unity內(nèi)置的頂點著色器就是加上SeparateSpecular On的。 3.4.3 關于顯卡的硬件支持情況說明
我們上篇文章中已經(jīng)講到過,一些舊的顯示卡不能支持某些紋理混合模式,且不同的卡有不同數(shù)目的SetTexture階段可用。所以我們應該為想支持的顯卡來分開寫SubShader,適應各種情況 。 PS::支持像素著色器1.1版本的顯卡(即NVIDIA GeForce 3 或更高, ATI Radeon 8500 或更高, Intel 9xx)支持所有的混合器模式,并且可以擁有至少4級渲染階段。下表簡述了硬件支持情況。 Card 顯卡 | Stage count 級數(shù) | Combiner modes not supported不支持的結(jié)合模式 | NVIDIA GeForce 3/4Ti and up | 4 | In OpenGL on Windows, src1*src2-src3 is not supported | NVIDIA TNT2, GeForce 256, GeForce 2, GeForce 4MX | 2 | In OpenGL on Windows, src1*src2-src3 is not supported | ATI Radeon 9500 and up | 4-8 | 8 in OpenGL, 4 in D3D9 | ATI Radeon 8500-9250 | 4-6 | 6 in OpenGL, 4 in D3D9 | ATI Radeon 7500 | 3 | | ATI Rage | 2 | src1*src2+src3 src1*src2+-src3 src1*src2-src3 |
四、Shader書寫實戰(zhàn)
上面講了一堆一堆的概念和寫法,估計大家一遍看下來頭都大了。沒關系,依舊是讓我們看一些示例Shader的寫法,弄清楚上面這一堆堆的概念是如何應用的。主要是紋理相關內(nèi)容的Shader書寫 1. Alpha紋理混合 先看看如何用本文講解的寫法,寫出一個簡單的紋理混合Shader。首先設置第一個混合器只使用_MainTex,然后使用_BlendTex的Alpha通道來淡入_BlendTex的RGB顏色: Shader '淺墨Shader編程/Volume3/7.Alpha紋理混合'{ //-------------------------------【屬性】----------------------------------------- Properties { _MainTex ('基礎紋理(RGB)', 2D) = 'white' {} _BlendTex ('混合紋理(RGBA) ', 2D) = 'white' {} } //--------------------------------【子著色器】-------------------------------- SubShader { Pass { // 【1】應用主紋理 SetTexture [_MainTex] { combine texture } // 【2】使用相乘操作來進行Alpha紋理混合 SetTexture [_BlendTex] {combine texture * previous} } }}
進行混合的兩張紋理如下: 
此Shader編譯后賦給材質(zhì)的效果如下: 
2.紋理的Alpha通道與自發(fā)光相混合 這個著色器使用_MainTex的Alpha來描述什么地方應用光照。它通過分兩個階段應用紋理來實現(xiàn);第一個階段,紋理的Alpha值被用來在頂點顏色和純白色之間混合。第二階段,乘入紋理的RGB通道: Shader '淺墨Shader編程/Volume3/8.紋理的Alpha通道與自發(fā)光相混合'{ //-------------------------------【屬性】----------------------------------------- Properties { _MainTex ('基礎紋理 (RGB)-自發(fā)光(A)', 2D) = 'red' { } } //--------------------------------【子著色器】---------------------------------- SubShader { Pass { //【1】設置白色的頂點光照 Material { Diffuse (1,1,1,1) Ambient (1,1,1,1) } //【2】開光照 Lighting On //【3】使用紋理的Alpha通道來插值混合顏色(1,1,1,1) SetTexture [_MainTex] { constantColor (1,1,1,1) combine constant lerp(texture) previous } //【4】和紋理相乘 SetTexture [_MainTex] { combine previous * texture } } }}
此Shader編譯后賦給材質(zhì)的效果如下:  3. 紋理Alpha與自發(fā)光混合可調(diào)色版 這次我們給出一個Color屬性,讓自發(fā)光顏色可調(diào): Shader '淺墨Shader編程/Volume3/9.紋理Alpha與自發(fā)光混合可調(diào)色版' { //-------------------------------【屬性】--------------------------------------- Properties { _IlluminCol ('自發(fā)光(RGB)', Color) = (1,1,1,1) _MainTex ('基礎紋理 (RGB)-自發(fā)光(A)', 2D) = 'white' {} } //--------------------------------【子著色器】-------------------------------- SubShader { Pass { //【1】設置白色的頂點光照 Material { Diffuse (1,1,1,1) Ambient (1,1,1,1) } //【2】開啟光照 Lighting On // 【3】將自發(fā)光顏色混合上紋理 SetTexture [_MainTex] { // 使顏色屬性進入混合器 constantColor [_IlluminCol] // 使用紋理的alpha通道混合頂點顏色 combine constant lerp(texture) previous } // 【4】乘以紋理 SetTexture [_MainTex] {combine previous * texture } } }}
此Shader編譯后賦給材質(zhì)的效果如下,可以自由調(diào)節(jié)顏色: 
4. 頂點光照+紋理Alpha自發(fā)光混合 我們將本文中介紹的知識點和上一篇文章中頂點光照相關的內(nèi)容結(jié)合起來,主要是在Pass中添加了一句,讓頂點光照可以和紋理顏色結(jié)合起來: //---------------------開啟獨立鏡面反射----------------SeparateSpecular On
完整的Shader代碼如下: Shader '淺墨Shader編程/Volume3/10.頂點光照+紋理Alpha自發(fā)光混合' { //-------------------------------【屬性】--------------------------------------- Properties { _IlluminCol ('自發(fā)光色', Color) = (1,1,1,1) _Color ('主顏色', Color) = (1,1,1,0) _SpecColor ('高光顏色', Color) = (1,1,1,1) _Emission ('光澤顏色', Color) = (0,0,0,0) _Shininess ('光澤度', Range (0.01, 1)) = 0.7 _MainTex ('基礎紋理 (RGB)-自發(fā)光(A)', 2D) = 'white' { } } //--------------------------------【子著色器】-------------------------------- SubShader { Pass { //【1】設置頂點光照值 Material { Diffuse [_Color] Ambient [_Color] Shininess [_Shininess] Specular [_SpecColor] Emission [_Emission] } //【2】開啟光照 Lighting On //【3】---------------------開啟獨立鏡面反射---------------- SeparateSpecular On // 【4】將自發(fā)光顏色混合上紋理 SetTexture [_MainTex] { // 使顏色屬性進入混合器 constantColor [_IlluminCol] // 使用紋理的alpha通道插值混合頂點顏色 combine constant lerp(texture) previous } // 【5】乘上紋理 SetTexture [_MainTex] { combine previous * texture } //【6】乘以頂點紋理 SetTexture [_MainTex] { Combine previous * primary DOUBLE, previous * primary} } }}
此Shader編譯后賦給材質(zhì)的效果如下:  5. 頂點光照+自發(fā)光混合+紋理混合
在剛剛介紹的第四個Shader的基礎上,加上第一個Shader中講解的紋理混合,就做成了本文最終的頂點光照+自發(fā)光混合+紋理混合Shader: Shader '淺墨Shader編程/Volume3/11.頂點光照+自發(fā)光混合+紋理混合' { //-------------------------------【屬性】----------------------------------------- Properties { _IlluminCol ('自發(fā)光色', Color) = (0,0,0,0) _Color ('主顏色', Color) = (1,1,1,0) _SpecColor ('高光顏色', Color) = (1,1,1,1) _Emission ('光澤顏色', Color) = (0,0,0,0) _Shininess ('光澤度', Range (0.01, 1)) = 0.7 _MainTex ('基礎紋理 (RGB)-自發(fā)光(A)', 2D) = 'white' {} _BlendTex ('混合紋理(RGBA) ', 2D) = 'white' {} } //--------------------------------【子著色器】-------------------------------- SubShader { //----------------通道--------------- Pass { //【1】設置頂點光照值 Material { //可調(diào)節(jié)的漫反射光和環(huán)境光反射顏色 Diffuse [_Color] Ambient [_Color] //光澤度 Shininess [_Shininess] //高光顏色 Specular [_SpecColor] //自發(fā)光顏色 Emission [_Emission] } //【2】開啟光照 Lighting On //【3】--------------開啟獨立鏡面反射-------------- SeparateSpecular On //【4】將自發(fā)光顏色混合上紋理 SetTexture [_MainTex] { // 使顏色屬性進入混合器 constantColor [_IlluminCol] // 使用紋理的alpha通道插值混合頂點顏色 combine constant lerp(texture) previous } //【5】乘上基本紋理 SetTexture [_MainTex] { combine previous * texture } //【6】使用差值操作混合Alpha紋理 SetTexture [_BlendTex] { combine previous*texture } //【7】乘以頂點紋理 SetTexture [_MainTex] {Combine previous * primary DOUBLE, previous * primary } } }} 此Shader編譯后賦給材質(zhì)的效果如下: 
換些高光顏色玩一玩: 

正常白色高光版: 
五、最終游戲場景效果演示——光之城堡
上一次我們處于盛大的暴風雪之中,這次的場景,不妨讓我們來到夢幻又神秘的的光之城堡,領略一番不一樣的味道。以大師級美工鬼斧神工的場景作品為基礎,淺墨加入了音樂,并調(diào)整了場景布局,加入了更多高級特效,于是便得到了如此這次讓人頗顯震撼的夢幻場景。 運行游戲,我們來到繁花盛開的光之城堡: 
抬頭,看陽光透過樹梢: 
低頭,是花草搖曳: 
左側(cè),是通向森林的路: 
右側(cè),是綿延的花海: 
來到霧氣氤氳的森林: 
回望,一線天: 
陽光透過樹梢,滿滿的生機: 
絢爛的花海:  走出森林,前方是一片幽暗之地: 
走進去,原來是一個小型古墓: 
在小山坡上遠眺:  來一張上帝視角,大好河山盡收眼底: 
依舊是一張今天所講的Shader的全家福:-  透過洞口的可見光線偏移:  OK,美圖就放這么多。游戲場景可運行的exe可以在文章開頭中提供的鏈接下載。 另外,本次的工程載入后會報Mismatched serialization in thebuiltin class 'Mesh'. (Read 100788 bytes but expected 100789 bytes)系列錯誤,沒關系,這是unity4.6之前版本的一個bug,不影響正常使用,clear掉就行了。
本篇文章的示例程序請點擊此處下載: 【淺墨Unity3D Shader編程】之三 光之城堡篇配套Unity工程下載  淺墨最近事情實在是有些多,所以只好下周停更一次了。 下下個周一,我們不見不散。
|