日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

unity透明通道加颜色_Unity-雪地效果的实现

發布時間:2023/12/19 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 unity透明通道加颜色_Unity-雪地效果的实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

最終效果https://www.zhihu.com/video/1217959676639330304

本文使用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-雪地效果的实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。