您好,登錄后才能下訂單哦!
本篇文章為大家展示了如何通過Mesh投影來實現貼花系統,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。
在做FPS之類的游戲中,如果槍打到了墻角,并不能簡單放置一來彈孔面片了事。而是要像一張貼紙一樣,完全與墻角貼合。這時就需要去實現一個貼花系統來達到這種效果。
貼花系統有幾種不同的實現方式,但這里僅考慮通過Mesh投影來實現貼花系統的實現原理。
這種方式的本質是,找到視野中貼花資源會影響的Mesh, 并創建一個同樣大小以貼花資源為紋理的Mesh覆蓋上去,從而達到貼花的目的。主要分下面兩步來實現。
1. 先找到會受影響的物體,比如將彈孔貼在兩面墻的夾角,那么受影響的物體就是兩面墻。
怎么找到這兩面墻不同的需求可能實現方式也不一樣, 在場景編輯器中通過貼花來實現靜態點綴效果,可以通過創建貼花資源的AABB盒來實現。如果是運行時動態創建彈孔也可以通過四次射線檢測來達到,總之方式有很多。
2. 先創建一個半徑為0.5單位的裁切立方體,在裁切坐標系中,貼花資源就被放在y=0平面中,貼花資源的中心就是裁切坐標系的(0, 0, 0)點。
需要說明的時這一步實際上并沒有代碼操作,只是一個數學抽象。我們的目的是要將所有受影響的三角形投影到y=0平面上,以便可以正確的采樣貼花紋理。
3. 將受影響物體Mesh的所有三角形均轉換到裁切立方體的坐標系之下對立方體的8個平面進行裁切。
在進行裁切之前,有一種情況需要處理,因為三角形是有朝向的,這個朝向是通過面法線來確定的(Unity中三角形的法線為Cross(v2-v1, v3-v1)),在正常的渲染流程中法線不能射入眼睛時,是不會被渲染的。在Unity中視錐體坐標系中,Vector3(0, 0, -1)是前向,因此眼睛的位置在Vector3(0, 0, 1)處。
在這個裁切立方體同樣如此,不可能將紋理投影到一個三角形平面的背面,所以需要先先判斷三角形的法線與Vector3(0, 0, 1)的夾角是否小于90度,只有小于90度才可能會被投影,才需要被裁切。
裁切時會出現,三角形完全在立方體外, 三角形完全在立方體內,三角形一部分在立方體外一部分在立方體內。前兩種情況很好處理,但是第三種情況有可能會將一個三解形切成2個,因此需要格外注意。具體的裁切算法視錐體裁切算法一致,這里就不贅述。
4. 紋理采樣,在創建三角形時,我們需要為每個一頂點指定一個uv坐標。前面已經說過了,我們的實現方式是將裁切后合法的三角形投影到裁切坐標系的y=0平面上, 投影之后的坐標為(x, 0, z). 因此uv可直接執行u = Lerp(0.0f, 1.0f, x + 0.5f), v = Lerp(0.0f, 1.0f, z + 0.5f).這里之所以加0.5f修正是因為立方體中心坐標為(0, 0, 0),這也意味著x,y,z的最小值均為-0.5f.
說了這么多附上源碼一篇。需要說明的是,這個源碼并不是我實現的,是我從網上找來之后修改的,畢竟我對Unity3d沒有那么熟悉。
ps.單位相同的裁切立方體如何適應不同尺寸的貼花資源?在Unity中可以通過設置Scale拉伸坐標軸來實現,所以說3D數學真奇妙。
pps.在實現過程中發現,新創建的Mesh不能緊貼被覆蓋的Mesh, 因為在相同的深度情況下,新創建的Mesh并不能保證一定在被覆蓋的Mesh之后渲染,這會概率性出現新創建的Mesh與被覆蓋的Mesh相互覆蓋的情況。因為在創建完Mesh之后,需要根據平面法線上浮一點,以保證Z-Buffer正常工作。
上述內容就是如何通過Mesh投影來實現貼花系統,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。