UE4程序化建模工具開發(fā)教程「植被建模」(ue4程序化植物)
Unreal Engine最好的部分之一就是它對(duì)那些偏藝術(shù)的人來說是無障礙的。隨著虛幻引擎4的首次發(fā)布,人們發(fā)現(xiàn)自己可以制作整個(gè)游戲,而不必觸及C 。從那時(shí)起,人們一直在挑戰(zhàn)藍(lán)圖的極限,Epic則通過更新擴(kuò)展工具集來做出回應(yīng)。
Unreal引擎中一個(gè)非常強(qiáng)大的部分是程序化網(wǎng)格(procedural mesh)組件,它接收數(shù)組輸入并輸出靜態(tài)網(wǎng)格。
將程序化網(wǎng)格與渲染到紋理(render to texture)功能相結(jié)合,可以完全在引擎中程序化地創(chuàng)建紋理資源!
這很有用,因?yàn)椋?/span>
- 你可以準(zhǔn)確地看到資產(chǎn)在構(gòu)建時(shí)的外觀。
- 在構(gòu)建資產(chǎn)時(shí)就可以在其環(huán)境中看到該資產(chǎn)。
- 更新都是實(shí)時(shí)的。
這有大量的潛在應(yīng)用,我一直在研究風(fēng)格化的植被(Foliage)生成,對(duì)于傳統(tǒng)建模工具而言這是一個(gè)痛苦的任務(wù),而程序化網(wǎng)格則非常適合用于解決這個(gè)問題,因?yàn)橛螒驑渲饕珊?jiǎn)單的形狀(圓柱體和平面)組成,并且更多地是關(guān)于這些形狀的正確放置和輕微變化,而不是它們各自的復(fù)雜性。
使用程序網(wǎng)格組件構(gòu)建的一些樹:
如果你有興趣試用該工具,可以在此處下載。
使用此工具時(shí),我建議增加項(xiàng)目設(shè)置中的最大循環(huán)計(jì)數(shù)(Max Loop Count)。如果超過項(xiàng)目設(shè)置的最大循環(huán)計(jì)數(shù),我們的幾何圖形將無法正確構(gòu)建!
1、程序化創(chuàng)建三角形
讓我們從簡(jiǎn)單的網(wǎng)格對(duì)象開始,渲染一個(gè)三角形。創(chuàng)建新的Actor藍(lán)圖并添加程序化網(wǎng)格組件。創(chuàng)建DrawTriangle函數(shù),并將其插入到構(gòu)造腳本中:
添加兩個(gè)數(shù)組:
- 向量數(shù)組,用來表示頂點(diǎn)
- 整數(shù)數(shù)組,用來表示頂點(diǎn)數(shù)組的目標(biāo)索引
在這里我們有三角形的三個(gè)頂點(diǎn)和創(chuàng)建該三角形所需的整數(shù)順序。注意我們需要列出頂點(diǎn)的順序,如果存儲(chǔ)0,1,2,則三角形將會(huì)方向錯(cuò)誤。
程序化網(wǎng)格組件輸出到Create Mesh Section(創(chuàng)建網(wǎng)格截面)函數(shù),并將上述數(shù)組鏈接到對(duì)應(yīng)的輸入中。
嘿!我們成功制作了一個(gè)三角形!
2、程序化創(chuàng)建平面
現(xiàn)在讓我們更復(fù)雜一點(diǎn),做一個(gè)平面。首先需要添加更多的數(shù)組。我們需要補(bǔ)充:
- 法線向量數(shù)組
- 切線結(jié)構(gòu)向量數(shù)組
- UV二維矢量數(shù)組
別擔(dān)心,我們將用一些小技巧獲得法線和切線!
請(qǐng)記住,就像以前一樣,我們需要先清理數(shù)組數(shù)據(jù)。
然后創(chuàng)建Draw Quad函數(shù),并添加兩個(gè)嵌套循環(huán),用來處理x 和 y的每個(gè) 值。
然后取當(dāng)前的 x 和 y 值,乘以一個(gè)值(距離),并將其添加到向量數(shù)組中,最后將UV當(dāng)前 x 和 y 值除以其總計(jì)(長(zhǎng)度)以獲得歸一化值。
然后,我們可以使用Create Grid Mesh Triangles(創(chuàng)建網(wǎng)格三角形)功能自動(dòng)生成指定數(shù)量的三角形。雖然以后無法使用它,但就目前而言,這是生成三角形數(shù)據(jù)網(wǎng)格的簡(jiǎn)單方法。
我們還需要法線和切線,這樣我們就可以使用Calculate? Tangents for Mesh(計(jì)算網(wǎng)格的切線)函數(shù)來得到結(jié)果。
下面是最終得到的完整函數(shù),點(diǎn)擊鏈接查看放大的視圖:
下面是構(gòu)造腳本:
結(jié)果:
3、程序化創(chuàng)建圓柱體
一旦有了網(wǎng)格,將形狀從平面更改為圓柱體就是一件簡(jiǎn)單的事情:我們不再將定點(diǎn)與網(wǎng)格對(duì)齊,而是將它們纏繞在軸上。
取我們之前創(chuàng)建的 X 和 XLength 值,將它們相除以得到歸一值,然后乘以 360,從而得出角度。我們希望圍繞 z 軸旋轉(zhuǎn) x 軸,因此獲取這些值并將它們插入,并通過與浮點(diǎn)數(shù)相乘來控制距離。
像這樣將此新計(jì)算與原始的 x*float 交換,點(diǎn)擊鏈接 查看大圖。
現(xiàn)在我們的平面就變成了圓柱體!
如果我們?nèi)w一化的y或z值,并用1-x反轉(zhuǎn),則創(chuàng)建一個(gè)圓錐體!
4、讀取網(wǎng)格數(shù)據(jù)
我們需要的最后一個(gè)元素是讀取網(wǎng)格數(shù)據(jù)。Get? Section from Static Mesh(從靜態(tài)網(wǎng)格體獲取截面)函數(shù)可以從任何網(wǎng)格中獲取數(shù)據(jù)并輸出供我們使用?,F(xiàn)在,我們可以對(duì)任何網(wǎng)格進(jìn)行采樣,對(duì)其進(jìn)行修改,然后將其散布在表面上。
現(xiàn)在,我們已經(jīng)有了構(gòu)建程序化內(nèi)容所需的基礎(chǔ)。在下一部分中,我們將介紹如何利用這些工具制作一個(gè)簡(jiǎn)單的樹生成器。
5、程序化生成植被
在深入研究植被生成工具開發(fā)之前,我強(qiáng)烈建議你下載并嘗試一下,否則我們將討論的一些主題將非常抽象!你可能還會(huì)注意到一些未涵蓋的對(duì)pivot painter的引用。這是我目前正在開發(fā)的額外功能,尚未完成!
樹葉工具分為五個(gè)單獨(dú)的藍(lán)圖:
1、父藍(lán)圖 Tree Parent
- 保存將在所有子項(xiàng)之間共享的數(shù)據(jù)。
- 樹干、樹枝和樹葉藍(lán)圖均繼承自它。
2、樹干 Trunk
- 繼承自Tree Parent
- 樣條控制的網(wǎng)格
- 只制作一個(gè)網(wǎng)格
- 提供大量用戶控制
3、樹枝 Branch
- 繼承自Tree Parent
- 沿表面或隨機(jī)生成多個(gè)樹枝
- 用戶控制僅限于隨機(jī)變量范圍
- 可以相互疊加
4、樹葉 Leaf
- 繼承自Tree Parent
- 讀取網(wǎng)格數(shù)組并沿樹干/樹枝或隨機(jī)放置
- 不能有子節(jié)點(diǎn)
5、合成器 Compositer
- 以TreeParent數(shù)組為輸入,將網(wǎng)格重建為單個(gè)資產(chǎn)
- 檢測(cè)并合并重復(fù)材質(zhì),以減少材質(zhì)數(shù)量
你可能會(huì)想,為什么要這樣做?。亢冒?,分解樹有多種好處:
- 在層次結(jié)構(gòu)上進(jìn)行更改時(shí)不必重繪整個(gè)網(wǎng)格
- 快速分離和隱藏資產(chǎn)的元素
- 刪除部分而不會(huì)破壞整個(gè)樹
- 資源將組件化,因此可以將樹的一部分復(fù)制粘貼到其他樹上
- 拆分隨機(jī)種子生成,以便獲得更多控制
所有這些元素結(jié)合在一起,讓用戶構(gòu)建一個(gè)模塊化的組件堆棧,這些組件"應(yīng)該"允許他們制作任何類型的樹!
6、父藍(lán)圖 – Tree Parent
為了避免重復(fù)工作,我們應(yīng)該首先創(chuàng)建一個(gè)作為基礎(chǔ)的父藍(lán)圖,其他藍(lán)圖需要繼承父藍(lán)圖。這很有用,因?yàn)槲覀兎湃敫杆{(lán)圖中的任何數(shù)據(jù)都將在其后代藍(lán)圖中共享。例如,每個(gè)資產(chǎn)類型都需要一個(gè)材質(zhì)引用和一組網(wǎng)格數(shù)組,以便將信息添加到父級(jí),以便傳播到其子級(jí)。
將程序化網(wǎng)格組件添加到TreeParent藍(lán)圖中。
我們還需要一些變量,每個(gè)子藍(lán)圖都需要這些變量。
Base:
- Material:應(yīng)用于網(wǎng)格的材質(zhì),這意味著我們每個(gè)組件只支持一種材質(zhì)。
- ProcMesh,一個(gè)包含頂點(diǎn)、三角形、UV 和頂點(diǎn)顏色等制作網(wǎng)格所需的數(shù)組的結(jié)構(gòu)。法線在具有函數(shù)后生成。
- RandomSeed,隨機(jī)種子,隨機(jī)化網(wǎng)格的一部分。
References:
- Parrent,樹藍(lán)圖變量,用于引用其所有者。
- Root,表示網(wǎng)格合成工具,用于獲取存儲(chǔ)順序。
- ChildRefs,父藍(lán)圖數(shù)組,用于告訴父級(jí)對(duì)象進(jìn)行更新。
- Ts,轉(zhuǎn)換數(shù)組的數(shù)組,用于存儲(chǔ)樹枝信息??梢园阉胂蟪蓸涞墓羌堋8杆{(lán)圖引用此內(nèi)容來獲取生成位置。
一個(gè)共享函數(shù),它告訴子數(shù)組中的資產(chǎn)進(jìn)行更新。每次更改組件時(shí)都會(huì)調(diào)用它(但請(qǐng)記住,在我們創(chuàng)建之前,這些函數(shù)或強(qiáng)制轉(zhuǎn)換都不存在)。
如果我們不更新子組件,則樹將很快斷開連接。
7、樹干 Trunk
樹干藍(lán)圖應(yīng)繼承自 TreeParent,并且基于可編輯樣條曲線。從添加組件下拉列表中選擇樣條線就可以將其添加到任何藍(lán)圖中,就像我們對(duì)程序化網(wǎng)格組件所做的那樣。
可以看到我們已經(jīng)繼承的組件:
在構(gòu)造腳本中,我們添加了一個(gè)名為 Draw 的新函數(shù)。我們將對(duì)藍(lán)圖自身及其所有子藍(lán)圖進(jìn)行此調(diào)用。
Draw函數(shù)檢查父樹干是否已存在,如果存在,則沿父樣條移動(dòng)組件,否則將直接移動(dòng)以創(chuàng)建網(wǎng)格。最后,通知子項(xiàng)使用"Update Children"進(jìn)行更新。
I在 Create Base Segments中,我們清理歷史幾何數(shù)據(jù),計(jì)算新數(shù)據(jù),然后重新繪制網(wǎng)格,在這個(gè)教程中,這一模式我們將反復(fù)運(yùn)用。
對(duì)于幾何圖形,我們需要兩個(gè)整數(shù),一個(gè)用于長(zhǎng)度段的數(shù)量,另一個(gè)用于徑向段的數(shù)量。
獲取我們想要的樣條長(zhǎng)度和長(zhǎng)度段數(shù),將它們除以得到每個(gè)點(diǎn)之間的距離,并將其設(shè)置為稱為對(duì)于我們的幾何圖形,我們需要兩個(gè)整數(shù),一個(gè)用于長(zhǎng)度段的數(shù)量,另一個(gè)用于徑向段的數(shù)量。
獲取我們想要的樣條長(zhǎng)度和長(zhǎng)度段數(shù),將它們除以得到每個(gè)點(diǎn)之間的距離,并將其設(shè)置為稱為Segment Distance(段距離)的浮點(diǎn)數(shù)。
然后循環(huán)處理每個(gè)長(zhǎng)度段,并得到樣條線上指定距離處的變換。長(zhǎng)度將是當(dāng)前循環(huán)序號(hào) * 段距離??梢允褂?x 或 y 來控制軀干的厚度。將其乘以暴露的值,為網(wǎng)格添加均勻大小。
你可能需要在此處旋轉(zhuǎn),以使其與樹枝的旋轉(zhuǎn)對(duì)齊。
將轉(zhuǎn)換存儲(chǔ)在數(shù)組中,這非常重要,因?yàn)槲覀冃枰环N通用方法來了解樹枝在空間的位置,并且并非每個(gè)藍(lán)圖都有樣條組件。稍后將添加到 Ts 數(shù)組(在 TreeParent 中創(chuàng)建)。
然后,我們?cè)贒raw Radius函數(shù)中圍繞該變換繪制頂點(diǎn)。這類似于我們之前繪制幾何圖形的方式。單擊鏈接以查看完整圖表。
這里唯一的主要區(qū)別是我們制作三角形數(shù)組的方式。這對(duì)于樹干來說是不必要的,但對(duì)于多個(gè)樹枝來說絕對(duì)至關(guān)重要。網(wǎng)格三角形函數(shù)只期望單一網(wǎng)格,但是如果我們想制作多個(gè)單獨(dú)的網(wǎng)格,需要偏移三角形計(jì)數(shù)器。
完成所有這些操作后,我們需要獲取基本轉(zhuǎn)換數(shù)組,并將其設(shè)置為 Ts 數(shù)組。此處的索引表示多個(gè)分支,但由于我們只創(chuàng)建一個(gè)段,因此僅將其設(shè)置為索引 0。
一旦獲得了所有數(shù)據(jù),剩下的就是繪制網(wǎng)格了!
8、樹枝 Branch
希望你現(xiàn)在已經(jīng)識(shí)別出這種模式,清除舊數(shù)據(jù)并生成新數(shù)據(jù)。樹枝藍(lán)圖需要接收一個(gè)父級(jí)(如果存在),并沿其分散多個(gè)樹枝。如果父藍(lán)圖不存在,我們將直接散落在地上。
上面沒有什么新內(nèi)容,因此讓我們繼續(xù)Make Branch Data(制作樹枝數(shù)據(jù)),此函數(shù)的大部分內(nèi)容是為我們正在創(chuàng)建的每個(gè)樹枝查找生成點(diǎn)(點(diǎn)擊鏈接查看大圖)。
首先要確定是否有父藍(lán)圖。如果是這樣,我們得到父級(jí)的 T 數(shù)組,這是一個(gè)轉(zhuǎn)換數(shù)組。每個(gè)樹枝都是一個(gè)新的轉(zhuǎn)換數(shù)組。這意味著,如果父樹枝有 8 個(gè)分支,而我們選擇創(chuàng)建 4 個(gè)分支,則它總共生成 32 個(gè)分支。如果父藍(lán)圖是樹干,則 T 數(shù)組將只有一個(gè)轉(zhuǎn)換條目。
如果它沒有父級(jí),那么繼續(xù)循環(huán)進(jìn)行分支計(jì)數(shù)并計(jì)算出歸一化距離。
下一步是弄清楚每個(gè)分支的起源應(yīng)該是什么。如果沒有父級(jí),只需獲取對(duì)象的原點(diǎn)即可。如果存在父級(jí),則獲取當(dāng)前變換數(shù)組并根據(jù)規(guī)范化距離查找位置。還可以在此處添加鉗位值以縮小范圍。
這里有一個(gè)圖表,如果這聽起來令人困惑,可以更好地解釋它。在下圖中,頂部值是需要轉(zhuǎn)換為轉(zhuǎn)換數(shù)組的規(guī)范化距離。乘以轉(zhuǎn)換索引計(jì)數(shù),得到最接近的索引,余數(shù)是下一個(gè)索引之間的距離。此計(jì)算將給我們一個(gè)沿變換長(zhǎng)度的粗略距離。
生成最小和最大矢量之間的隨機(jī)位置。
合并位置,使用自定義宏修改旋轉(zhuǎn)并修改比例。
整理出原點(diǎn)旋轉(zhuǎn)是一個(gè)非常重要的元素。為了獲得易于控制的結(jié)果,可以使用圍繞索引旋轉(zhuǎn)并使用方向矢量以避免鎖定(鏈接)。
一旦獲得原點(diǎn)后,將其添加到pivot數(shù)組并創(chuàng)建分支。
在樹干示例中,我們使用樣條線進(jìn)行變換,然后圍繞它構(gòu)建幾何圖形。
我們不能在這里這樣做,因?yàn)闃訔l不存在。相反,我們必須生成這些點(diǎn)(鏈接)。
這里我們?nèi)≡c(diǎn)。
抓取當(dāng)前垂直長(zhǎng)度。我們需要這個(gè)來抵消我們的三角形計(jì)數(shù)。三角形數(shù)組只是引用頂點(diǎn)數(shù)組上的索引,因此需要偏移量來保持三角形引用的正確性。生成最小值/最大值之間的隨機(jī)分支長(zhǎng)度。
然后對(duì)于分支上的每個(gè)點(diǎn)。
找出下一個(gè)點(diǎn)的位置。接受最后一個(gè)變換,通過乘以方向矢量來抵消它。通過一些受控的旋轉(zhuǎn)稍微調(diào)整它。
再次創(chuàng)建網(wǎng)格數(shù)據(jù),就像我們之前所做的那樣。
分支藍(lán)圖的重要功能是它是可堆疊的。我們應(yīng)該能夠在樹枝上的樹枝上建立分支,等等。
可能遇到的唯一問題是我們的分支計(jì)數(shù)是指數(shù)級(jí)的。如果第一層有 6 個(gè)分支,第 2 層和第 3 層有 4 個(gè)分支,我們將得到 96 個(gè)分支,而不是 14 個(gè)分支。如果我們添加包含 4 個(gè)分支的第 4 層,則得到 384 個(gè)分支。整個(gè)操作都使用循環(huán),這意味著如果數(shù)字太大,我們將遇到很多麻煩。
9、樹葉 Leaf
樹葉不能有子級(jí),因此它們將始終處于各自層次結(jié)構(gòu)的末尾。藍(lán)圖將對(duì)網(wǎng)格數(shù)組進(jìn)行采樣,并將它們分散到樹干或樹枝資源中。我們?cè)谶@里可以做的一個(gè)有用的技巧是使用渲染實(shí)例而不是繪制幾何圖形,這可以大大提高性能。在這里,我們添加一個(gè)切換開關(guān)來表示是否利用此優(yōu)化。
對(duì)于此組件,創(chuàng)建一個(gè)可由用戶設(shè)置的網(wǎng)格數(shù)組。對(duì)于每個(gè)網(wǎng)格,使用get section from static mesh(從靜態(tài)網(wǎng)格體獲取部分)函數(shù)來獲取每個(gè)對(duì)象的數(shù)據(jù)并將其存儲(chǔ)以供以后使用(鏈接)。
與樹枝藍(lán)圖相同,清除舊數(shù)據(jù),檢查父數(shù)據(jù),然后循環(huán)處理。
找到與以前相同的生成點(diǎn),然后創(chuàng)建網(wǎng)格或添加實(shí)例。
添加網(wǎng)格數(shù)據(jù)非常簡(jiǎn)單(鏈接)。
我們得到三角形偏移量,并選擇一個(gè)要復(fù)制的網(wǎng)格。
按長(zhǎng)度偏移三角形。按生成點(diǎn)轉(zhuǎn)換頂點(diǎn)數(shù)據(jù),將其全部存儲(chǔ)在數(shù)組中。
10、合并
組裝完各個(gè)組件后,需要將它們整理到一個(gè)可以導(dǎo)出的統(tǒng)一網(wǎng)格中。函數(shù)可以作為按鈕向編輯器公開,而不是在構(gòu)造腳本中運(yùn)行它。這允許在運(yùn)行腳本時(shí)進(jìn)行更高級(jí)別的控制。
在此功能中,我們清除舊數(shù)據(jù),構(gòu)建唯一的材質(zhì)數(shù)組(這避免了使用重復(fù)材料創(chuàng)建任何資產(chǎn)),必要時(shí)重建網(wǎng)格數(shù)據(jù)并輸出網(wǎng)格。作為優(yōu)化,我們應(yīng)該重建網(wǎng)格以避免大量重復(fù)的材質(zhì)分配。
將組件整理成一組數(shù)組(鏈接)。
檢查我們構(gòu)建的材質(zhì)數(shù)組在長(zhǎng)度上是否與組件數(shù)組相匹配。如果材質(zhì)比組件少,我們知道是一些共享的材質(zhì)。
此時(shí),我們必須遍歷每個(gè)組件的三角形數(shù)據(jù)并對(duì)其進(jìn)行偏移,以便在組合在一起時(shí)與頂點(diǎn)數(shù)組對(duì)齊。
最后,采用新的數(shù)據(jù)結(jié)構(gòu)并創(chuàng)建一個(gè)靜態(tài)網(wǎng)格。
單擊合成器上的程序網(wǎng)格組件,然后按"創(chuàng)建靜態(tài)網(wǎng)格"按鈕。這將提示選擇一個(gè)位置,選擇一個(gè)名稱就可以了:
11、結(jié)論
這只是你可以使用過程網(wǎng)格組件創(chuàng)建的資產(chǎn)類型的一個(gè)示例。有各種各樣的可能性,也不僅限于編輯器創(chuàng)建,你也可以在游戲中使用此功能!
我們也不能在不提到Houdini的情況下完成一篇關(guān)于程序化工具的文章,這是一個(gè)純粹專注于程序化內(nèi)容生成的出色工具。它有一個(gè)很棒的UE4插件,你可以用它來處理Houdini引擎資源。
原文鏈接:http://www.bimant.com/blog/ue4-procedural-foliage-tool/