Unity實用案例之 噴漆效果

2021-08-16 04:38:32 字數 2307 閱讀 9444

**應用場景:**如牆上的標語貼花,汽車上的噴漆等。

選擇方案:

當然實現方法各式各異,最最最簡單,也是最「不堪入目」的方法是直接給乙個麵片,然後獲取噴漆位置,加上乙個要噴漆表面法線方向的偏移,作為最終麵片放置位置,當然,不要忘了設定麵片的方向。這種方法雖然說簡單,但是效果並不理想,會出經常現與其他物體穿插的情況,如果遊戲中曲面太多,那麼這個方案基本沒法看。

對於個別特殊的需求來講,比如說人物身上的紋身,完全可以用乙個shader裡實現,此方法僅限於乙個貼花對應乙個物體,如果是一對多的情況,請看後邊這兩種。

有一種簡易的方法是用projector,這種方法實現較為簡單,不多說。

接下來說一種動態生成網格方案,也較為常用,接下來就詳細說說這種方案。

實現思路:

噴漆的網格是根據場景中所噴位置的物體的網格動態生成的,噴漆的時候,獲取規定範圍內的物體,再用乙個立方體(也可以用球體)去擷取這些物體的mesh,從而構造新的網格,將噴漆渲染在這個mesh就ok了。

**實現:

首先,我們需要乙個獲取規定範圍內meshrenderer的函式:

public gameobject getaffectedobjects(bounds bounds, layermask affectedlayers)

} return objects.toarray();

}

然後拿到這些gameobject去做裁剪,裁剪函式:

public void builddecal(gameobject affectedobject, bool islast)

if (islast)

});}

decalpolygon構建了新的三角形(這裡注意頂點的空間變換),然後分別用立方體的每乙個面去做裁剪,轉換成數學演算法,其實是判面與面的關係,具體實現:

/// /// 兩面相交裁剪

///

public static decalpolygon clippolygon(decalpolygon polygon, plane plane)

if (positivecount == 0)

return null; //全都在裁剪面正面面,不相交

if (positivecount == polygon.vertices.count) return polygon; //全都在裁剪面反面,完全相交

decalpolygon temppolygon = new decalpolygon();

for (int i = 0; i < polygon.vertices.count; i++)

if (positive[i] != positive[next])

}return temppolygon;

}

ok,到這裡已經為新的mesh準備好了所有的資料,接下來將計算好的資料移步到主線程做渲染:

public void renderdecal()

//生成uv資訊

generatetexcoords(0, sprite);

//距離偏移

push(pushdistance);

mesh mesh = createmesh();

if (mesh != null)

});}

這樣,乙個噴漆功能就做好了,有幾點需要注意是的是:

1.gc的控制

示例:vector3 vertices = mesh.vertices;

注意這裡不是簡單的記憶體引用,而是會申請新的記憶體,所以這樣的臨時變數會造成gc,當物體的頂點上十幾k,甚至幾十k的時候,這樣的gc是吃不消的!為了盡量避免這樣的情況,可以做一次預存處理,對沒有檢測過物體的頂點和三角形資料進行儲存,下次用的時候直接取,從而取代mesh.vertices;

2.計算量的問題

還是出於效能的考慮,當與之裁剪的mesh頂點數太多,在主線程for迴圈幾十k次,不出意外pc端也會卡頓,所以非同步是乙個較好的選擇。複雜的裁剪計算交給其他執行緒,計算好主線程直接拿資料做渲染;

3.效果問題

由於新生成的噴漆mesh是由原有物體的mesh裁剪所得的,而這兩個mesh位置是重疊在一起的,兩個完全重疊的面,如果其他因變數也相同的情況下,讓計算機渲染,計算機也不知道該先渲染哪個,這樣就出現z-fighting的問題。所以加乙個push()方法,將新mesh的頂點沿當前頂點的法線方向擠出一點距離,這樣就實現了乙個噴漆功能。

Unity之布料效果

上面的效果是blinn phong 加detail 做出來的,blinnphong 是常用的一種帶有反射的光照演算法。而為了達到布料的效果,還需要加兩張貼圖,一張是面料的detail貼圖,另一張是布料的法線貼圖。shader game 3d dress up specular specular co...

Unity實用Shader之遮罩層

在unity中很多時候會用到遮罩層,如minnmap 鈕等 這裡貼上相關的shader 和注釋 shader shaderdemo masklayer 目標,即需要被遮罩的 masklayer culling mask 2d white 混合的,設定為白色的,任何顏色與白色混合,其顏色不變 cuto...

python實用案例之花式名稱

今天給大家帶來乙個有趣的turtle模組案例,廢話不多說,請看下面 詳解 import turtle 匯入 t turtle.pen 畫筆 turtle.bgcolor black 背景設為黑色 colors red yellow blue green 字型顏色分別為紅色 黃色 藍色 綠色 numb...