?

基于U3D和Shader下模型光束效果的設計與實現

2023-07-26 09:13陳翔宇
電腦知識與技術 2023年16期
關鍵詞:著色器高光頂點

陳翔宇

(華東師范大學 計算機科學與技術學院,上海200333)

0 引言

Unity是實時3D互動內容創作和運營平臺。包括游戲開發、美術、建筑、汽車設計、影視在內的所有創作者,借助Unity將創意變成現實[1]。Unity平臺提供一整套完善的軟件解決方案,可用于創作、運營和變現任何實時互動的2D 和3D 內容,支持包括手機、平板電腦、PC、游戲主機、增強現實和虛擬現實設備,同時支持Windows、Android和Mac等多平臺[2]。

Unity3D 開發相比于其他游戲引擎,有更多優勢特點:1) 支持多種格式導入:整合多種DCC文件格式,包含3dsMax、Maya、Lightwave、Collade 等文檔,可直接拖拽到Unity中,除原有內容外,還包含Mesh、多UVs、Vertex、Colors、骨骼動畫等功能,提升游戲制作的資源應用[3]。2) 逼真的粒子系統:Unity 開發的游戲可以達到難以置信的運行速度,在良好硬件設備下,每秒可以運算數百萬面以上的多邊形。高質量的粒子系統,內置的Shuriken 粒子系統,可以控制粒子顏色、大小及粒子運動軌跡,可以快速創建下雨、火焰、灰塵、爆炸、煙花等效果。3) 支持外源制作的各種插件,導入Unity 后方便制作者使用。4) 支持多平臺發布:Unity3D 游戲開發支持的平臺,無疑是當下較為流行的平臺,滿足絕大部分項目需求。早期的引擎,多以PC 和CONSOLE 為主[4],同時支持了Windows、XBOX、PS2 等平臺。U3D 便利的多平臺發布特性,也是它成為當前性價比最高的引擎的原因之一。5) AssetStore商店提供了大量的資源,使U3D的生態圈更加穩固[5]。用戶可以制作插件網上售賣,賺取一些利益,也可以購買別人的插件,作為使用或者參考。有時候,購買一些插件,可以讓用戶快速脫離當前的困境,一個是解決進度問題,一個是解決思路問題,這是之前其他引擎不具備的。

1 Shader下光束的設計

1.1 Shader原理

Shader 是運行在GPU 上可編程的圖形程序,在Unity 中可以使用Cg/HLSL 語言編寫頂點著色器和片元著色器。頂點著色器和片元著色器被分離為可編程的單元,兩者都擁有強大的并行計算能力,擅長于矩陣計算(不高于四階),片元著色器可以高速查詢紋理數據信息,但頂點著色器不行[6]。頂點著色器(Vert)負責處理頂點坐標轉換信息,片元著色器(Frag)負責處理像素顏色數據計算信息,且前者的輸出是后者的輸入。頂點著色程序從GPU 前端模塊(寄存器)中提取圖元信息(頂點位置、法向量、紋理坐標等),并完成頂點坐標空間轉換、法向量空間轉換、光照計算等操作,最后將計算好的數據傳送到指定寄存器中;然后片元著色程序從中獲取需要的數據,通常為紋理坐標、光照信息等,并根據這些信息以及從應用程序傳遞的紋理信息(如果有)進行每個片元的顏色計算,最后將處理后的數據送光柵操作模塊[7]。片元著色程序對每個片元進行獨立的顏色計算,最后輸出顏色值的就是該片段最終顯示的顏色,具體渲染流程見圖1。

圖1 Shader渲染流程

1.2 Shaderlab編程開發的結構

ShaderLab 開發是Unity 內置的一段Shader 代碼,在Unity 中賦予材質上的Shader 著色器進而實現效果。內部結構偏復雜,詳細闡述易于理解。

1) Properties{}:Properties的{}內是定義著色器的相關屬性,輸入的屬性會呈現在Unity平臺內Material下的Inspector 面板下供調試,定義格式為_Name(“Inspector Name”,type)=Value[option}],其中_Name 表示屬性名,有_NormalMap、_MainTex、_Color、_BumpScale等?!盜nspector Name”代表在Inspector面板下顯示的屬性名?!癟ype”則是屬性類型(Vector、Float、Range(min,max)、Cube、Rect、2D、Color等);Properties面板見圖2。

圖2 Shader下Properties面板

2) SubShader{},SubShader 是子Shader,可以有多個,運行效果時,從第一個SubShader開始[8],如果第一個SubShader的效果都可以實現,就使用第一個,如果不可以,就會自動運行下一個SubShader,直到最后的Fallback回滾;

3) pass 塊,隸屬于SubShader 中,一個pass 塊相當于一個方法,在它內部的CGPROGRAM 至ENDCG 區域編寫Shaderlab代碼;

4) CGPROGRAM 到ENDCG 部分,這個區域是Shaderlab 代碼的核心內容,必須將屬性塊Properties里需要的屬性值重新定義一遍。區域的主要內容再細分為:①#pragram vertex vert,聲明頂點函數,頂點函數名為vert,它的基本作用是完成頂點坐標從模型空間到剪裁空間的轉換(從游戲環境轉換到視野相機屏幕上)。②#pragram fragment frag,聲明片元函數,它的基本作用是返回模型對應的屏幕上每一個像素的顏色值[9]。③struct a2v,從應用程序傳遞到頂點函數的結構體。④struct v2f,從頂點函數傳遞給片元函數的結構體。⑤v2f vert(a2v v),即頂點函數,內部書寫從模型空間轉換到剪裁空間的代碼,比如法線、頂點坐標、紋理坐標等。⑥frag(v2f f),即片元函數,內部實現從剪裁空間返回到Unity世界空間的像素值。

2 游戲需求下涉及的算法

當前游戲的邏輯模式已經完成,原人物角色模型見圖3。本文的主要需求是運用Shaderlab 將場景內游戲角色的服裝加上光束的特效以及高光反射的效果,令人物角色在場景中擁有更出色的3D外觀表現。

圖3 場景下原人物角色模型

在游戲場景中,為了給人物角色添加特殊的光束效果,本文創新地采用光照融合疊加原理。

1) 漫反射公式:Diffuse=_LightColor0.rgb*max(dot(normalDir,lightDir),0);

其中,直射光_LightColor0 表示Unity 內置環境光(平行光),其后加上.rgb 則代表的是直射光的顏色值。需要在注入“Lighting.cginc”的條件下再調出。Max(,)函數取最大值,dot(,)函數來進行點乘運算,此處在漫反射公式內則是求|normalDir|*|lightDir|*cos<normalDir,LightDir>的乘積值。normalDir 表示法向量的單位向量,lightDir代表入射光方向的單位向量。

2) 高光反射公式:specular=_LightColor.rgb*pow(max(dot(normalDir,halfDir),0),_Gloss)。

公式內Pow(a,b) 函數計算的是ab的值,_Gloss表示的是高光參數值,值的大小和高光反射的區域大小成反比。這里的halfDir 是由viewDir(觀察方向單位向量)和lightDir(入射光方向單位向量)的疊加單位向量。

3) 矩陣轉換算法:對于頂點從模型空間下坐標轉換到世界空間的坐標,需要用到四維矩陣轉換,其代碼行為 f.vertex=mul(v.vertex,unity_ObjectToWorld);通過mul 函數將模型空間下的模型頂點坐標v.vertex 作為行向量,與四維矩陣unity_ObjectToWorld 進行乘積,獲得剪裁空間下的模型頂點坐標f.vertex[10]。

4) 透明度alpha 值:alpha=min(1,abs(((bottom+top)/2-i.uv.x*tan(_lightAngle))-i.uv.y)/(Length/2));

這一值是實現人物角色自發光的重點之處,min(,)函數取括號內兩數之間最小值,abs()函數取括號內數值的絕對值,tan()函數求_LightAngle(閃光角度)的正切值,隨后和i.uv.x(紋理坐標的X分量)一起計算得出透明度alpha值。

3 主要片元函數代碼

物體角色模型在導入Unity場景時已配有紋理貼圖,對于光束效果來說區分為逐頂點和逐像素的效果追求。在如3dsMax、Maya等三維模型的繪制中,模型是由無數個三角形面組成。一個三角形的面是由三條線和三個頂點拼接而成,逐頂點會取三個頂點間的插值來緩和過渡顏色差。而逐像素則是計算每個像素點的精確值后再繪制在世界空間中,圖像上的處理會更精細但相比逐頂點會消耗更多的資源性能。本文中的兩個光束效果都是以逐像素為核心,通過改變片元函數中像素值來達到特定的效果。

3.1 人物角色自發光的片元函數代碼

屬性Properties中已經定義了_MainTex(主貼圖),2D 類型且默認值為白色,在SubShader 的pass 塊內的CGPROGRAM~ENDCG段進行了Sample2D _MainTex的再定義。整體Shaderlab的局部片元函數代碼如下:

通過(1) 處的Shaderlab 內置tex2D 函數傳入參數_MainTex以及剪裁空間下的f.uv參數,再賦給col,獲得col 的初始顏色值。(2) 處定義一個float 類型的alpha值,通過min 函數取得每個紋理采樣點之間的最小值再賦予alpha。在(3) 處通過返回系數為(1-alpha)的RGB 為(0.5,0.5,0.5)的顏色值和系數為alpha 的紋理顏色值,再與屬性Properties 中已定義的_Color(閃光顏色)進行加法疊加,再賦予col,最后再返還給世界空間下的像素值,實現了人物角色自發光的特效。

3.2 人物角色面部高光反射的片元函數代碼

經過Shaderlab 代碼的初始區域的結構體定義以及頂點函數轉換獲取到了f.worldnormal(世界空間下法線)、f.worldvertex(世界空間下頂點)、_MainTex(主貼圖)等。整體Shaderlab的局部片元函數代碼如下:

(1) 將f.worldnormal 通過normalize 函數來單位化獲得世界下法線的單位向量(normalDir) 。(2) 將f.worldvertex經過世界空間下入射光方向的函數World-SpaceLightDir 轉換來獲取世界空間下每個點對應的入射光方向的單位向量(lightDir) 。計算漫反射顏色值見(3)經過dot點乘計算出每個點的世界法線向量和入射光方向的cos余弦值,再和0相比較取最大值,再乘以環境光的顏色值(_LightColor0.rgb) 以及紋理顏色值(texColor) 來得到最終的漫射光顏色值(diffuse) 。(4) 計算視角方向(即攝像機方向),高光反射的重點就在于視角方向。因為人觀察事物某個頂點區域從不同的角度會有不同的反射效果。將f.worldvertex 傳入世界空間下觀察方向函數UnityWorldSpaceViewDir 的轉換后再通過normalize 函數單位化后獲得世界空間下的單位視角方向向量。(5) 以局部變量halfDir(半融合向量)接受了經過視角方向和入射光方向的疊加后的單位化向量值。(6)隨后以normalDir(世界法線單位向量)和halfDir(半融合單位向量)的點乘余弦值和0比較后的最大值作為pow函數的底數,再以_Gloss(高光參數)作為函數的冥次方計算得值,隨后將得到的值和環境光顏色以及高光顏色值做乘法融合。這里的顏色值之間的乘法融合相比加法疊加會有更少量化值的影響。(7) 最后,將漫射光顏色值(diffuse) 、高光顏色值(specular)、環境光顏色值(UNITY_LIGHTMODEL_AMBIENT) 與紋理顏色值(texColor)的乘法融合值再相加,最后再返還給世界空間下的像素值,實現了人物角色面部高光反射的特效。

4 Shader下結果測試

4.1 自發光測試

對應Unity 場景,在Shaderlab 中對人物角色的自發光RGB值進行多次更改后,顏色值呈正常相關變化,主要表現為人物模型保持為紋理原色,但自發光的顏色會受RGB值的影響,測試結果見表1。

表1 自發光測試結果統計

4.2 高光測試

人物角色面部的高光會受到高光顏色值的直接影響,但主要是由高光參數決定面部的光澤效果。在實際應用中,高光參數區域的大小會和高光參數的值成反比,測試結果見表2。

表2 高光測試結果統計

5 U3D下Shader實現后結果

5.1 自發光效果

由于對人物角色模型添加了自發光的Shaderlab,可以看到衣服模型自上向下會有呈周期性變化的閃爍光芒效果,模型的紋理原圖會作為底層紋理與自發光相互融合產生不錯的特效,具體效果見圖4。

圖4 場景下附加自發光效果后人物角色模型

5.2 高光效果

相比圖3 的原人物模型,可以發現人物面部色彩更細膩,面部輪廓也有了明顯的光澤,整體給用戶呈現出了一個更精氣神的角色,Unity場景中展示見圖5。

圖5 場景下附加高光效果后人物角色模型

5.3 自發光和高光效果融合

同時可以調整場景內的渲染顯示質量。在菜單欄下Edit 的Project Setting 的Quality 面板進行設置 ,Pixel Light Count像素燈數量取標準值4,Texture Quality 紋理質量取Full Res(完整分辨率),Shadow Distance 陰影距離值取50,超過這個距離陰影將不會被顯示。這樣可以將渲染的性能開到一個很高的級別,同時也保證了渲染效率的穩定,詳細設置可見圖6。

圖6 渲染顯示Quality設置

將自發光和高光效果共同施加在人物角色模型上,呈現在Unity場景中的效果見圖7。

圖7 兩種效果共同附加后人物角色模型

6 結束語

在日常游戲開發中,不僅看重游戲的可玩程度和邏輯性,也越來越重視游戲的場景特效和三維模型特效。Shader 著色器的應運而生為此提供了充分的擴展性,本文通過Unity3D 和Shader 的結合實現了用戶想要的效果,通過自發光測試和高光測試也驗證了效果的可行性。在今后的開發中,不應止步于此,還可以通過Shaderlab來書寫各種各樣的渲染特效,與場景搭配融合出令用戶驚嘆贊絕、美輪美奐的游戲畫面。

猜你喜歡
著色器高光頂點
見證彼此高光
過非等腰銳角三角形頂點和垂心的圓的性質及應用(下)
想做聯名爆款?超級飛俠、熊出沒、奧特曼等“高光”IP等你來聊
基于UE4 實時射線追蹤技術的研究與探討
基于Unity Shader石油泄漏現象模擬的研究
基于IMx6的opengl圖形著色器開發研究
關于頂點染色的一個猜想
釋放出來自HDR的高光力量 Optoma奧圖碼UHZ880
基于Moldflow 的高光無痕電視前殼注射模具設計
基于可編程渲染管線的雷達圖像分層模型設計與實現
91香蕉高清国产线观看免费-97夜夜澡人人爽人人喊a-99久久久无码国产精品9-国产亚洲日韩欧美综合