小屋創作

日誌2021-08-22 00:18

【學習日誌】把物體投影到背景上 8/21

作者:樂小呈

圖多注意歐

之前就一直好奇 <超閾限空間 Superliminal> 中神奇的透視操作是怎搞的,但不是放大縮小那個,那個不難理解,我指的是可以用透視把物體投影進背景的神奇效果,像這樣


原本以為是用頂點操作的方式,Raycast 把所有頂點貼到背景上,但多想一下之後就會發現問題了,交界處怎麼裁切? 所以這個做法就被否定了。

直到前天晚上洗澡的時候,我在腦中模擬各種方法嘗試計算,等洗完的那一刻思路剛好通ㄌ,答案浮現在大腦理,阿斯。



先上成果


簡單來說,就是用像素的世界座標,反推原本透視視角的 UV,在把原本視角中的圖像用後處理疊上當前畫面。


至於怎麼只投影特定物件,可以透過攝影機的渲染 Layer 達成,我用兩個攝影機來做效果。
主攝影機,負責遊戲畫面渲染的 mainCamera,不渲染要被投影的物件(投影時)


投影攝影機,在放下物體時會把當下畫面輸出成 Texture2D,只畫出被投影的物件,用 Layer


最後把 Texture 傳給 mainCamera 的後處理 Shader 進行計算,透過這種方法就能畫出被投影進背景的物體了。



如何取得像素世界的座標就參考大佬趴趴鼠的文章整個程式碼,我這裡就只解說後面的步驟,基本上就是手動作一次渲染流程的各種 transform 而已

首先是 worldSpace 轉換成投影攝影機的 cameraSpace,用攝影機的 transform 反矩陣乘



接著投影矩陣投影進 projectionCamera 的 viewSpace,但把深度壓掉變成 -1 ~ 1 的 float2




只要 * 0.5 + 0.5 就反推出原本視角的 UV 了


最後把反推出的 UV 當作 Texture 採樣,就能畫出被投影進背景的物體。



用一連串帥氣的矩陣操作完成投影!
我也希望我做得到...但實際開始才發現窩的圖學觀念不夠扎實,搞不出來
這也是為什麼上面的解說沒什麼數學解釋

殘念阿,明明邏輯都對,結果卡在 rendering pipline 的基本知識不充足
所以最後還是到處翻資料,找了一個現成的方法取得 viewProjection Matrix,直接完成所有工作。
_projectionMat = camera.nonJitteredProjectionMatrix * transform.worldToLocalMatrix

float4 projected = mul(_projectionMat, worldPos)
float2 projUV = (projected.xy / projected.w) * 0.5 + 0.5;
(fake code
參考資料,直接幫我完成上面解說的所有步驟ㄌ
https://gamedev.stackexchange.com/questions/166757/how-can-i-transform-a-world-space-point-to-a-cameras-screen-coordinate

老實說我覺得這不算難拉,理解之後應該會 Shader 的人都搞得出來,難就難在一開始憑空猜測原理的時候

然後實際做還有幾個問題在,第一就是陰影的問題,因為投影之後要把原本的物件隱藏,所以會讓原本渲染的物體陰影也消失。至於修正方法,我是直接弄一個只會讓 mesh 投影出陰影的透明材質,讓陰影保持渲染。



Texture Repeat
UV 像素採樣的時候,如果超出 0 ~ 1 的範圍,會根據 wrapMode 讓 texture 重複之類的

直接用 saturate 把 uv 限制在 0 ~ 1 之間就好了,但這樣還是會變成邊緣拉伸啦,如果投影時物體被畫面截斷...懶得修了w


反向的投影
如圖,懶ㄉ解釋了

就加個方向的判斷而已,檢查像素和原點的相對方向是不是和原本視角相同,用 dot product < 0 檢查就行。


最後還有一個沒修的問題,找不出方法修
就是用投影反推的 UV 沒辦法做深度判斷,所以障礙物的前後都會被畫上投影物體,有大佬知道怎麼解決嗎



就醬,想通以後花了些時間實現,回復了不少能量


原始檔在這,有興趣自己載來玩玩
https://github.com/angus945/Superliminal_perspectiveProjection

請不要介意那個超級糟糕的控制手感,我沒有花很多時間在 playerControler 上 www
WSAD 移動
左鍵長按拖動物件,按 R 旋轉物件,滾輪移動距離,放開就把物體投影到背景上了
投影之後只有視角正確才能把它拿回來,可以長按 E 回到正確的位置


終於寫好ㄌ
晚安

42

4

LINE 分享

相關創作

【程式筆記】0320 C++物件導向程式設計

【學習】插件、多人和反向工程

遊戲進度:小規模封測進行中

留言

開啟 APP

face基於日前微軟官方表示 Internet Explorer 不再支援新的網路標準,可能無法使用新的應用程式來呈現網站內容,在瀏覽器支援度及網站安全性的雙重考量下,為了讓巴友們有更好的使用體驗,巴哈姆特即將於 2019年9月2日 停止支援 Internet Explorer 瀏覽器的頁面呈現和功能。
屆時建議您使用下述瀏覽器來瀏覽巴哈姆特:
。Google Chrome(推薦)
。Mozilla Firefox
。Microsoft Edge(Windows10以上的作業系統版本才可使用)

face我們了解您不想看到廣告的心情⋯ 若您願意支持巴哈姆特永續經營,請將 gamer.com.tw 加入廣告阻擋工具的白名單中,謝謝 !【教學】