光圈科技傳送門特效UE4實(shí)現(xiàn)(超詳細(xì)攻略)

效果:
原理可以看這個(gè)視頻:
50Cal是用opengl和開源物理引擎手?jǐn)]的,這工作倆量想想都覺(jué)得頭皮發(fā)麻。俺這里是用ue4實(shí)現(xiàn)的,不支持傳送門遞歸,也沒(méi)有用模板遮罩進(jìn)行性能優(yōu)化。
50Cal把原理講的很清楚了,這篇文章俺著重講一下在ue4中實(shí)現(xiàn)的細(xì)節(jié),和一些坑點(diǎn)。
平面反射詳解
傳送門透射本質(zhì)上是在平面反射的基礎(chǔ)上整的花活兒,要整平面反射,就得在和主視角攝像機(jī)鏡像的位置創(chuàng)建一個(gè)場(chǎng)景捕獲actor(那玩意全名叫做場(chǎng)景捕獲2D)。

那么,怎么才能獲得主視角的鏡像位置呢,我們需要一些簡(jiǎn)單的幾何學(xué)。

已知鏡面上一點(diǎn)P和鏡面的法向量n,求A關(guān)于鏡面的對(duì)稱點(diǎn)B,也就是要算出向量AB,由反射的性質(zhì)可得,AB垂直于鏡面,且AC=BC=點(diǎn)A到平面的距離,點(diǎn)A到平面的距離=dot(PA,n)。
所以完整的式子:OB=OA+AB=OA-2dot(PA,n)*n。加粗的代表向量。dot表示點(diǎn)乘。
好了,算出了位置之后我們還得算出朝向。

a是主視角朝向,b是鏡像之后的朝向,b的方向其實(shí)相當(dāng)于a向量被鏡面反射后的方向,
b =?a-2dot(a,n)*n,這個(gè)公式的推導(dǎo)和上面差不多,讀者可自行畫圖推導(dǎo)。
好了,我們可以將主攝像機(jī)的x和z軸進(jìn)行鏡像,然后通過(guò)鏡像之后的x軸和z軸構(gòu)建旋轉(zhuǎn)。在這個(gè)過(guò)程中,你可能需要用到這些藍(lán)圖函數(shù):

好了,到了這一步,你已經(jīng)將場(chǎng)景捕獲放到了正確的位置,接下來(lái),你需要裁剪視錐體。注意圖1視錐的虛線部分,如果虛線部分有幾何體的話,它會(huì)出現(xiàn)在場(chǎng)景捕獲的結(jié)果中,這是我們不希望看到的。要裁剪掉這個(gè),我們需要使用屏幕捕獲的裁剪平面功能,這個(gè)功能很不好找。你需要點(diǎn)開場(chǎng)景捕獲展卷欄下面的三角形。

你可能會(huì)看到啟用剪切平面的按鈕是灰色的,它需要在項(xiàng)目設(shè)置中打開全局剪切平面才能使用。
剪切平面基礎(chǔ):剪切面上任意一點(diǎn)(世界空間),對(duì)于我們來(lái)說(shuō),就是鏡面的位置。
剪切平面法線:剪切平面的法線,對(duì)于我們來(lái)說(shuō)就是鏡面的朝向。

你可能需要用到這些藍(lán)圖函數(shù):

現(xiàn)在,你只需要設(shè)置一個(gè)render target就可以從場(chǎng)景捕獲中得到反射畫面了。你可以在內(nèi)容瀏覽器中點(diǎn)擊右鍵創(chuàng)建渲染目標(biāo),它在材質(zhì)和紋理子菜單下。

注意,視場(chǎng)的設(shè)置應(yīng)該和主相機(jī)保持一致,紋理目標(biāo)的長(zhǎng)寬比要和玩家視口的長(zhǎng)寬比保持一致(出于性能考慮,尺寸可以小一點(diǎn),比如你的主視口是1080p的,那你的紋理目標(biāo)可以用一個(gè)800x450的,保持比例即可)。
將場(chǎng)景捕獲渲染到貼花
傳送門可以是墻上的一個(gè)平面,也可以是一個(gè)貼花,但顯然貼花更加便利,用平面的話你需要讓平面在墻的前面一點(diǎn)點(diǎn),不能在墻壁里,這樣就看不見了,也不能離墻壁太遠(yuǎn),這會(huì)被看出破綻,你需要非常小心的為墻壁設(shè)置碰撞體積,來(lái)保證碰撞發(fā)生的位置正正好。用貼花就沒(méi)有那么多麻煩。
第一步,我們的貼花要完全消去物體本身的光照。打開材質(zhì)編輯器,然后這樣設(shè)置。


將這個(gè)材質(zhì)應(yīng)用于貼花,貼上的物體將會(huì)變成100%的黑色,接著,我們將場(chǎng)景捕獲的渲染目標(biāo)連接到自發(fā)光,那么最終顏色將完全由自發(fā)光分量構(gòu)成。
采樣渲染目標(biāo)時(shí),uv應(yīng)使用屏幕空間坐標(biāo),并將u反向。如圖所示


現(xiàn)在,你做出了一面完美反射的鏡子!如果你不知道為什么uv要用屏幕空間坐標(biāo),那么請(qǐng)返回圖1仔細(xì)琢磨。
關(guān)于HDR,sRGB,色調(diào)曲線
確保場(chǎng)景捕獲的這項(xiàng)設(shè)置,設(shè)置為RGB場(chǎng)景顏色(HDR)

RGB(HDR)反應(yīng)的是物理上,紅綠藍(lán)三個(gè)分量的輻射強(qiáng)度,它的值可以大于1,上不封頂。這和應(yīng)該在材質(zhì)中輸出的內(nèi)容是匹配的。ue計(jì)算完畫面的HDR顏色之后,會(huì)經(jīng)過(guò)Color correction,變換到線性sRGB色彩空間(線性sRGB空間指沒(méi)有進(jìn)行g(shù)amma矯正的sRGB空間),最后經(jīng)過(guò)色調(diào)映射(Tone Mapping)變換到0~1之間的值。
總結(jié):如果要把場(chǎng)景捕獲的結(jié)果畫到材質(zhì)上,那么始終應(yīng)該使用RGB(HDR),如果要在UI上或者后期處理中使用場(chǎng)景捕獲的結(jié)果,那么應(yīng)該使用sRGB(帶色調(diào)映射)。
現(xiàn)在你對(duì)場(chǎng)景捕獲已經(jīng)有了深入的了解!再回頭看看UE的文檔你會(huì)發(fā)現(xiàn)他真是寫了個(gè)寂寞。
https://docs.unrealengine.com/4.27/zh-CN/Resources/ContentExamples/Reflections/1_7/
從平面反射到傳送門透射
前文說(shuō)了,傳送門透射只是在平面反射的基礎(chǔ)上整了個(gè)花活兒。

玩家主視角相機(jī)在A,為了正確渲染傳送門P1,我們需要在A''處放置場(chǎng)景捕獲。A'是A的鏡像位置。聰明的你已經(jīng)注意到,A'相對(duì)與P1的位置就是A''相對(duì)于P2的位置。
所以,完整的做法是,鏡像A,得到A',取得A'相對(duì)于P1的變換T1,取得P2的變換T2,然后疊加T1,T2。
這個(gè)變化的過(guò)程用藍(lán)圖表示是這樣的:

在本例中,transform對(duì)應(yīng)A',from對(duì)應(yīng)P1,to對(duì)應(yīng)A2,乘號(hào)對(duì)應(yīng)的函數(shù)叫做“compose transform”。
接下來(lái)你還需要做個(gè)傳送門的外框,和一個(gè)未開啟的傳送門材質(zhì),不過(guò)這個(gè)不是這次討論的重點(diǎn)了,我寫累了,如果有需要的我以后會(huì)再寫一篇講講這個(gè)材質(zhì)。
不知道怎么做的也可以去看看ue官方的材質(zhì)系列教程?;蛟S學(xué)完了可以比我做得還好看
https://www.unrealengine.com/zh-CN/onlinelearning-courses/materials-master-learning?lang=zh-CN
