創作內容

42 GP

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

作者:樂小呈│2021-08-22 00:18:58│巴幣:2,088│人氣:813
圖多注意歐

之前就一直好奇 <超閾限空間 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
參考資料,直接幫我完成上面解說的所有步驟ㄌ

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

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



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

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


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

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


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



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


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


終於寫好ㄌ
晚安
引用網址:https://home.gamer.com.tw/TrackBack.php?sn=5244818
All rights reserved. 版權所有,保留一切權利

相關創作

同標籤作品搜尋:Unity|遊戲開發|Shader|程式

留言共 4 篇留言

矮鵝
哇塞這真的開腦洞了,shader進階技巧~~~

08-22 10:01

樂小呈
玩家把物件放下來後就貼進背景裡了ㄏㄏ08-22 10:07
FunS
哇 深度判斷那個真的想不到辦法欸..[e20]

08-22 17:22

樂小呈
頭痛ㄌ,最後一個問題[e21]08-22 17:57
KK
超棒!當初看這個遊戲的時候沒去細想實作原理,像這樣的研究解析跟實作,腦中就會跟著延伸出很多有趣的想法,第一步去追根究柢的這個念頭,以及去執行的行動力,我想這就是我現在最欠缺的東西。收穫良多~讚讚[e19][e19]

08-24 18:23

樂小呈
洗澡洗一洗解答就出來了[e16]08-24 19:29
樂小呈
加油 !08-24 19:30
PPPPPP
安安路過 查資料時看你的別篇文章 覺得你真的蠻厲害的 加油!
關於最後一個問題應該可以用深度圖解決 放置的時候也拍一張去除目標物件的深度圖
之後繪製時多判斷該像素的相機空間的深度是否小於等於該深度圖的值 大於的就剔除這樣

12-09 14:31

樂小呈
還好啦 >///<12-09 22:12
樂小呈
深讀圖感覺不錯,但不知道會不會遇到精度問題 :thinking:12-09 22:13
我要留言提醒:您尚未登入,請先登入再留言

42喜歡★angus945 可決定是否刪除您的留言,請勿發表違反站規文字。

前一篇:【閒聊】改變一下發日誌的... 後一篇:【專案日誌】山鴉行動 U...

追蹤私訊切換新版閱覽

作品資料夾

SALOL~~
望德勒斯圖書館更新中~看更多我要大聲說7小時前


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

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