unity透明通道加颜色_Unity-雪地效果的实现
本文使用unity實現雪地效果,主要參考了github上兩個已有的demo,將其結合并并增加了一些自己東西。
本文主要講雪地效果,簡單說就是雪地踩腳印的實現,并非雪面的渲染。然后因為是一段時間之前寫的,細節部分有些遺忘,所以爭取主要把原理講清楚,不會涉及太多代碼細節。可以下載github的demo參考更改。
如果有任何錯誤,歡迎指正,謝謝!~
參考demo
Demo1: https://github.com/thnewlands/unity-deformablesnow
Demo2: https://github.com/TheBeach54/SnowSimulation
雪地效果最基本原理
雪地效果的根本就是要踩出腳印。而實現這個的原理分兩步:第一步,在雪地plane的下方放置一個正交相機,從下往上拍攝,如下圖。目的是實時獲取上方物體生成一張深度圖;第二步,根據上一步生成深度圖,將雪地plane的頂點向下方位移,使用tessellation技術。參考Demo1就是根據這一基本原理實現。理解上不難哈。
本文實現流程
本文采用的方法比上文說的多兩個步驟。一個是參考了demo2的方法,具體則是在下方放置兩個攝像機,一個相機在第一幀的時候記錄下初始地面深度,因為初始地面可以是地形,本身就有一定高度。另外一個相機記錄實時拍攝的物體深度。這樣根據兩個深度就能在任何地形上計算出最后在真正的踩雪地方,將其結果保存在r通道內。當然需要兩個正交相機參數完全相同,具體計算方式后面會說。結果如下圖和視頻:
初始地形為平面初始地形為山丘初始地形為山丘最終效果https://www.zhihu.com/video/1217959942839558144另外一個步驟則是根據計算后的深度值圖,進行兩次輪廓線檢測,采用的是最基本簡單的sobel算子,然后用g和b通道分別存儲其顏色。這樣做的目的是,可以根據最后的深度圖的不同通道,將雪地分為基本雪面(無顏色值)、凸起部分(g通道)、側邊(b通道)、凹陷底部(a通道)四個部分,如圖。只需要在tessellation的過程中,將g通道的部分向上位移頂點,與a通道操作相反,則可以形成踩雪路徑左右兩邊的凸起部分。
然后根據不同的通道使用不同的diffuse、normal等貼圖渲染即可得到不同的雪面渲染效果。在這之前可以適當的將深度圖進行模糊處理,使邊界柔和。同時在雪面渲染地shader中使用lerp函數對貼圖進行插值。結果如下圖:
不同通道顏色的深度值對應的雪面貼圖實現細節
相機部分
這是下方放置的正交相機的腳本的截圖,是獲得物體深度的相機,另外一個獲得初始地形深度的相機大致相同,現在介紹其主要部分。代碼如下:
/// <summary>首先,下方相機獲取深度圖,這一步通過SetReplacementShader替換上方物體的材質為SnowDepthShader獲得,另外一個相機。SnowDepthShader中最基本的一個步驟就是講fragment shader中的顏色值替換為o.rgb = float3(1 - i.depth, 0,0);這樣就能使得相機獲取深度圖。
然后則是傳給CamRecieveMat,該材質的shader就是用來處理接受到的ObjDepthTex(物體深度圖)和FloorDepthTex(初始地形深度圖,另外一個相機生成)。然后根據這兩張圖生成一張計算后的深度值圖。計算代碼如下:
float其中floor是初始地形的深度值,current.x是當前拍攝到的物體深度值,_SnowMaxHeight似是設定的雪面高度,_SnowFarPlane是相機的遠平面距離,最終將計算出的深度值重新賦值給current.x。這樣生成的計算后的深度值圖,就能避免原始物體深度圖中,在雪面以上的深度值被提取。
最后則是在OnRenderImage中進行兩次后處理,分別用EdgeDetectMat和EdgeDetectMatOut,也就是兩次sobel算子的輪廓線檢測,分別存儲到g和b通道內部。
另外一個重點則是我們使用了兩張RT分辨存儲深度值,然后在Update中交替傳給各種mat。這樣做主要是因為,一張RT存儲當前幀的深度圖,另外一張RT
存儲上一幀的深度圖,這樣就能讓深度圖在CamRecieveMat中保持形成軌跡。
雪面渲染材質
其中主要的參數有:
- Edge Length: Tessellation的程度
- Displacement Textur: 初始時讓雪面適當位移的噪聲貼圖
- Imprint Texture: Camera腳本傳遞進來的最后的深度圖
- Top Material Settings: 基本雪面(無顏色值部分)的雪面渲染
- Bottom Material Settings: 凹陷雪面(r通道部分)的雪面渲染
- Upper Material Settings: 凸起部分(g通道部分)的雪面渲染
- Middle Material Settings: 側邊雪面(b通道部分)的雪面渲染
然后還有一些關于個部分雪面渲染的程度等設定不贅述。
對于凸起部分的雪面貼圖僅采用了不同的diffuse貼圖和法線貼圖,并附加不同的顏色值和法線程度。
Tessellation
根據上文所獲得的最終深度圖,直接使用unity提供的tessellation技術(不贅述),在disp函數里將頂點的y方向進行相對應的位移。不過需要注意的是需要重新計算法線方向,否則陰影會有問題。
另外還有一個trick,可以將只需要頂點位移的地方tessellation的值提高。但是這樣做需要在剩余沒有腳印的雪面部分變化不大,沒有明顯的位移,否則在不同tessellation的接縫處會產生裂痕。所以實際上最后我也沒有用,只是一個參考。
三向貼圖
沒有使用三項貼圖使用了三向貼圖最后的一個處理是在雪面的渲染部分,地形變形導致了貼圖的拉伸,因此采用三向貼圖的算法進行貼圖(具體原理連接https://blog.csdn.net/liu_if_else/article/details/73833656)。左圖是普通uv貼圖,靠近雪面邊沿的地方貼圖會有明顯的拉伸。右圖是三項貼圖處理過后,貼圖拉伸變形效果消除。只需要針對所有的貼圖處理一下即可,代碼如下:
fixed4最后的最后,本文是參考了兩個demo融合更改的雪面效果,如果有錯誤,希望大家指正,謝謝~
總結
以上是生活随笔為你收集整理的unity透明通道加颜色_Unity-雪地效果的实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何将JAR包发布到Maven中央仓库?
- 下一篇: iphone黑屏转圈_iphone7无限