這篇文章主要介紹“Unity3D中的水特現(xiàn)模擬雨天”,在日常操作中,相信很多人在Unity3D中的水特現(xiàn)模擬雨天問(wèn)題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”Unity3D中的水特現(xiàn)模擬雨天”的疑惑有所幫助!接下來(lái),請(qǐng)跟著小編一起來(lái)學(xué)習(xí)吧!
站在用戶的角度思考問(wèn)題,與客戶深入溝通,找到松溪網(wǎng)站設(shè)計(jì)與松溪網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗(yàn),讓設(shè)計(jì)與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個(gè)性化、用戶體驗(yàn)好的作品,建站類型包括:網(wǎng)站建設(shè)、成都做網(wǎng)站、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣、主機(jī)域名、虛擬空間、企業(yè)郵箱。業(yè)務(wù)覆蓋松溪地區(qū)。
在寫實(shí)類游戲制作時(shí),常需要下雨場(chǎng)景的制作,由于日常生活中幾乎所有物體都會(huì)被淋濕,所以下雨的制作其實(shí)需要考慮的方面有很多,我們將從粒子,材質(zhì),腳本控制等方面,分析一下應(yīng)該如何渲染一個(gè)下雨的場(chǎng)景。
材質(zhì)高光:
Unity的Standard Lighting中,使用GGX作為BRDF的高光算法,GGX具有拖尾感,可以較好的模擬潮濕物體表面的反光效果,首先我們來(lái)看一下這張故宮下雨時(shí)的照片(圖侵刪):
在普通游客的眼里,地面變得“濕滑”了,然而在渲染工程師的眼里,我們應(yīng)該將這個(gè)“濕滑”的效果在PBR中分成四部分:Smoothness的提高,Specular Color的變亮以及GI Occlusion的降低和法線貼圖比重的降低。首先,提高Smoothness是毫無(wú)疑問(wèn)的,要讓物體表面光滑首先要降低粗糙度,但是僅僅降低粗糙度是不行的,水停留在物體表面,這時(shí)反射光線的是水而不是物體本身,因此物體本身的漫反射會(huì)被降低,因此被淋水的物體看起來(lái)顏色會(huì)變深,根據(jù)物理反射定律,物體本身色彩無(wú)變化,即光線反射比例無(wú)變化的情況下,高光程度應(yīng)提高,所以會(huì)表現(xiàn)出高光率提高的現(xiàn)象。同樣,因?yàn)榉e水在物體表面的停留,物體受環(huán)境光影響會(huì)增大,這時(shí)我們應(yīng)該適當(dāng)降低Occlusion Map的影響,并降低法線貼圖的偏移強(qiáng)度,這些在Unity的Standard Shader中都有提供,不需要手動(dòng)寫Shader,當(dāng)然,如果要處理一個(gè)大場(chǎng)景,希望通過(guò)全局變量控制,還是應(yīng)該手寫shader進(jìn)行精確優(yōu)化的,因此,希望讀者能夠不依賴Shader Forge, Unity Surface Shader等輔助功能,獨(dú)立編寫基于PBR Shader。至于反射圖像的處理,我們一般通過(guò)Reflection Probe, Screen Space Reflection & Planar Reflection等方法實(shí)現(xiàn),這并不在本文討論的范圍內(nèi),我們將會(huì)在本專欄的其他文章中詳細(xì)討論。
接下來(lái)就是雨水的制作了,雨水本身的粒子效果制作雖然屬于比較初級(jí)的粒子制作,甚至Assets Store上也有大量的資源,但是對(duì)美術(shù)制作能力有比較高的要求。如果像我一樣,美術(shù)功底奇差無(wú)比,完全可以直接買一個(gè)效果實(shí)現(xiàn)#手動(dòng)斜眼#,然后在粒子發(fā)射器上綁定一個(gè)腳本,使其始終在攝像機(jī)上方懸停,可以看到在示例中,我們使用粒子碰撞防止穿幫:
在攝像機(jī)第一視角效果如下:
到此,一個(gè)簡(jiǎn)單的雨水渲染就出來(lái)了,然而,整個(gè)畫面看起來(lái)僵硬死板,這是因?yàn)槲覀儧](méi)有表現(xiàn)出雨滴打在地上的效果,因此,我們需要模擬一個(gè)動(dòng)態(tài)的法線貼圖,讓地面的法線“動(dòng)起來(lái)”,解決的方法有許多,最簡(jiǎn)單的方法就是序列幀,在CG軟件(如Houdini,Substance Painter等)中制作序列幀并且渲染,然后在Unity中播放,這當(dāng)然是一種比較簡(jiǎn)單的方法,但是同樣也無(wú)法實(shí)現(xiàn)真正的實(shí)時(shí)與隨機(jī),我們這里則是使用Unity自帶的CommandBuffer進(jìn)行比較底層的圖形繪制,實(shí)現(xiàn)隨機(jī)的雨點(diǎn)特效。
學(xué)習(xí)過(guò)渲染管線基礎(chǔ)的朋友都知道,Unity的攝像機(jī)其實(shí)并不是繪制RenderTexture的唯一方法,它只是封裝的比較上層的方法,其實(shí)攝像機(jī)的工作流程就是(剔除->繪制網(wǎng)格->后處理)這三部分,無(wú)論是Forward path或是Deferred Shading path,亦或是Unity 2018最新提供的HDRP和LWRP,本質(zhì)上都是這三部,區(qū)別僅僅在于,deferred shading會(huì)將光照作為后處理運(yùn)算,而forward path會(huì)直接將燈光信息傳入shader中進(jìn)行光影運(yùn)算并直接輸出色彩,而我們這里并不需要?jiǎng)討B(tài)剔除,只需要使用command buffer在一個(gè)指定的Render Target上進(jìn)行GPU Instance,使用指定的材質(zhì)繪制大量面片即可。有朋友問(wèn)我為何不使用Unity 2017推出的CustomRenderTexture進(jìn)行繪制,我認(rèn)為,CustomRenderTexture只是給不會(huì)渲染底層的程序提供的一個(gè)上層封裝,實(shí)際功能不如使用Graphics類或CommandBuffer直接進(jìn)行繪制,后者雖然門檻較高但是功能更加強(qiáng)大,大概相當(dāng)于美圖秀秀和PhotoShop的關(guān)系(只是個(gè)人看法,別懟別懟)。
首先我們需要手動(dòng)生成一個(gè)正方形Mesh,并將indexBuffer設(shè)置為四邊形繪制,實(shí)現(xiàn)非常簡(jiǎn)單,代碼如下:
由于我們是直接往屏幕上繪制的,所以根本不需要考慮ViewProjectionMatrix的問(wèn)題,直接用NDC坐標(biāo)(-1, 1)進(jìn)行繪制即可,如果直接將這個(gè)mesh繪制到RenderTarget上,就是一個(gè)覆蓋全屏的Mesh。
接下來(lái)我們要讓這個(gè)mesh縮小并且隨機(jī)分布在RenderTarget上,實(shí)現(xiàn)雨滴隨機(jī)散落的效果,這時(shí)候就需要使用矩陣進(jìn)行變換了,然而,雨滴數(shù)量眾多,在本例中我們繪制了1023個(gè)雨點(diǎn),所以很難依靠CPU進(jìn)行迭代繪制,無(wú)論是計(jì)算還是Drawcall,消耗都是難以接受的。所以我們使用Compute Shader與Gpu Instance進(jìn)行繪制,大幅度提高運(yùn)算效率。
首先是Compute Shader,這里不贅述如何使用Compute Shader,只是提供Compute Shader的實(shí)現(xiàn)目標(biāo)與過(guò)程。實(shí)現(xiàn)目標(biāo):生成1023個(gè)隨機(jī)分配位置的矩陣并執(zhí)行1023個(gè)計(jì)時(shí)器。為何要用計(jì)時(shí)器呢,原因很簡(jiǎn)單,當(dāng)一個(gè)雨點(diǎn)散落到地上時(shí),漣漪應(yīng)該是越來(lái)越淺直到消失的,在漣漪消失時(shí)更新位置信息,使面片在另一個(gè)位置繪制。實(shí)現(xiàn)代碼如下:
這里來(lái)解釋一下這段代碼的意義,MatrixBuffer是我們需要使用的1023個(gè)坐標(biāo)矩陣,而timeSliceBuffer則是我們需要使用的計(jì)時(shí)器,其中float2的x值是計(jì)時(shí)器數(shù)值而y值是計(jì)時(shí)器速度。_DeltaFlashSpeed則是由腳本傳入的每幀的更新,即Time.DeltaTime * X; 然后是兩個(gè)LocalRand函數(shù),使用魔數(shù)運(yùn)算輸出一個(gè)偽隨機(jī)數(shù)。其中第一個(gè)函數(shù)會(huì)輸出一個(gè)(-1, 1)區(qū)間的float2隨機(jī)數(shù),用于隨機(jī)生成一個(gè)平面位置,而第二個(gè)函數(shù)則會(huì)輸出一個(gè)(0, 1)區(qū)間的float隨機(jī)數(shù),用于生成一個(gè)隨機(jī)的計(jì)時(shí)器速度。
下面的CSMain函數(shù)就比較簡(jiǎn)單了,當(dāng)計(jì)時(shí)器數(shù)值>1時(shí),歸0并重新生成隨機(jī)的速度與位置。根據(jù)線代基礎(chǔ),矩陣的M03, M13決定了xy軸的位置,M00,M11則決定了xy軸的Scale,而這里為了偷懶,果斷省略了雨滴大小的隨機(jī),直接用同樣大小的面片。
在ComputeShader中運(yùn)算完畢后,就可以在腳本里獲取計(jì)算的結(jié)果,并且使用運(yùn)算結(jié)果進(jìn)行繪制了,當(dāng)然,在此之前我們需要先進(jìn)行初始化:
這里初始化了Compute Shader,Compute Buffer以及需要用到的GPU Instance材質(zhì)與高斯模糊材質(zhì)(之后會(huì)用到)。
接下來(lái)就是調(diào)用Compute Shader并使用CommandBuffer進(jìn)行繪制:
首先,指定renderTarget并初始化為(0.5,0.5,1)也就是標(biāo)準(zhǔn)的法線貼圖格式,然后使用Compute Shader輸出的矩陣進(jìn)行Gpu Instance,最后經(jīng)過(guò)高斯高斯模糊,使畫面順滑一些。
有了輸入的計(jì)時(shí)器與輸入的矩陣,就可以開始繪制波紋了,波紋繪制實(shí)際非常簡(jiǎn)單,直接用Alpha Blend實(shí)現(xiàn)減弱效果,用三角函數(shù)實(shí)現(xiàn)波動(dòng)即可,直接上代碼:
Shader "Unlit/Wave"
{
SubShader
{
Tags { "RenderType"="Opaque" }
ZWrite Off
ZTest Always
Cull Off
Blend oneMinusSrcAlpha srcAlpha
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_instancing
#include "UnityCG.cginc"
#pragma target 5.0
#define MAXCOUNT 1023
StructuredBuffer<float2> timeSliceBuffer;
struct appdata
{
float4 vertex : POSITION;
float4 uv : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f
{
float4 vertex : SV_POSITION;
float timeSlice : TEXCOORD0;
float2 uv : TEXCOORD1;
};
v2f vert(appdata v, uint instanceID : SV_InstanceID)
{
v2f o;
UNITY_SETUP_INSTANCE_ID(v);
o.vertex = mul(unity_ObjectToWorld, v.vertex);
o.timeSlice = timeSliceBuffer[instanceID].x;
o.uv = v.uv;
return o;
}
#define PI 18.84955592153876
float4 frag(v2f i) : SV_Target
{
float4 c = 1;
float2 dir = i.uv - 0.5;
float len = length(dir);
bool ignore = len > 0.5;
dir /= max(len, 1e-5);
c.xy = (dir * sin(-i.timeSlice * PI + len * 20)) * 0.5 + 0.5;
c.a = ignore ? 1 : i.timeSlice;
return c;
}
ENDCG
}
}
}
shader非常簡(jiǎn)單,只是繪制了一個(gè)大致效果,最后生成的法線貼圖效果如下:
可以看到,這張對(duì)密集恐患者非常友好的圖片,已經(jīng)有了深淺不一的漣漪花紋(雖然比較難看),我們將這張renderTarget放到地面上,效果如下:
可以看到,地面已經(jīng)有了法線的漣漪,最近放假回國(guó)探親,只能用家里的古董筆記本寫文章,不過(guò)從粒子到動(dòng)圖繪制,在這臺(tái)古董上也只需要4ms左右的運(yùn)算時(shí)間,drawcall也因?yàn)間pu instance的原因并沒(méi)有額外增加,可以說(shuō)性能表現(xiàn)比較令人滿意。
到此,關(guān)于“Unity3D中的水特現(xiàn)模擬雨天”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)?lái)更多實(shí)用的文章!
新聞名稱:Unity3D中的水特現(xiàn)模擬雨天
標(biāo)題來(lái)源:http://chinadenli.net/article28/ihoijp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供App設(shè)計(jì)、企業(yè)建站、品牌網(wǎng)站制作、移動(dòng)網(wǎng)站建設(shè)、網(wǎng)站維護(hù)、外貿(mào)建站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)