<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                # **隨機化石頭的生成** * * * * * ## **零、需求分析** **H子**:**AOI**老師,最近有想法,想要制作一款獨立游戲了,但是美術素材量并不少,特別是一些瑣碎的資源,比如石頭,樹木之類的東西。 **AOI**:嗯。有考慮過到各種資源市場購買資源嗎。 **H子**:有是有過,不過考慮到預算限制,以及資源風格,數量等等的問題,靠購買也并不能解決所有問題。 **AOI**:那么,有考慮過想要制作什么樣的美術風格嗎? **H子**:現在考慮到人力資源方面的壓力,果然還是簡單明快的風格更好吧。所以這次先考慮LowPoly風格了。 **AOI**:這個確實算是一種明智的選擇。在獨立團隊,個人開發者等人力資源不足的情況下,選擇更簡單明快的風格,往往比需要龐大工作量的風格更有優勢。 **AOI**:其次,盡可能實現程序化生成,也是可以提升開發效率的方法。 **H子**:程序化生成? **AOI**:對目標進行分析,并且找出其中的規律和邏輯,以此構建程序并自動化的產出素材。此后,就可以進一步的在自動產出的素材中篩選和修改,就可以更輕松的產出經過主觀處理的素材。 這次就先用隨處可見的石頭舉個例子吧。 想想看,Low Poly的石頭有什么特點呢。 **H子**:我想想......隨便拿粘土和硬卡,把幾個面壓平壓出棱角的感覺? **AOI**:你說的好像也沒什么錯...... 首先,要生成隨機的石頭,可以先分析造型。一般的鵝卵石等的路邊小石,多數因為自然風化等作用下,都是近似球形。先把受到外力破損的造型作為特例剔除。 也就是說,要生成隨機的石頭,需要的是以下幾個基本步驟: 1. 在一定范圍內的隨機頂點 2. 把隨機頂點最外層頂點轉化成模型 生成一塊石頭所需要的,大體上來說就是以上的兩個個基本步驟。 然后按照需求,逐步的完成石頭的生成并且將流程自動化。 **H子**:那么!我們用什么方法來進行這個自動化生成的工作呢? **AOI**:那就是慣例的Blender吧。這次我們會使用一款叫Sverchok的可視化節點建模插件來進行這次的工作。 **H子**:好!我先去裝好插件。 * * * * * ## **壹、生成位置的頂點【Random Vector MK2】節點的運用** **AOI**:先切換到Sverchok編輯界面吧。切換到節點編輯器,你會見到節點類型那里多了一個選項。 ![SV節點編輯器](https://box.kancloud.cn/585d071919f60363bb158a181b9992fc_114x33.png) 點擊即可切換到Sverchok節點編輯界面。 **H子**:好了!我找到了。 **AOI**:首先進行第一步。 生成一定范圍內的隨機頂點,在Sverchok插件的內建節點庫里面,有一個名為**Random Vector MK2**的節點可以使用。 按Crtl+空格鍵彈出的搜索節點窗口內輸入節點名稱即可搜索和創建該節點。 對了,創建節點前記得先創建節點樹,雖然你不記得創建,在空白的節點編輯器界面直接創建節點,軟件也會自動創建節點樹。但是最好還是養成習慣比較好。 如下圖所示: ![通過搜索框創建RandomVectorMK2節點](https://box.kancloud.cn/3b2053705c81450b5b494c0eb542ef65_301x280.png =301x280) 創建后,將會在畫布上得到一個新的節點: ![RandomVectorMK2節點](https://box.kancloud.cn/e014c3d3be1e2c08d810a987820af0d9_179x140.png =179x140) 節點有三個入口: * Count:產生的隨機Vector數量 * Seed:隨機種子 * Scale:縮放 **H子**:也就是說,根據需要,調整Seed和Count值就可以獲得需要的頂點了嗎? **AOI**:根據實際情況輸入Count的值,用于產生石頭所需的頂點,頂點數量越多,越接近球形。因為隨機頂點是在Scale值為半徑的空間內產生隨機頂點。而Scale值可以決定最后產生石頭的大小的最大值,也就是產生頂點的區間的最大半徑。 Seed可以隨意設置,值的變化會產生不同的隨機頂點,因此可以利用Seed進行造型的隨機化,也是程序化石頭批量生成的關鍵。 **H子**:那么?我們應該怎么把這些頂點變成最后的模型呢? **AOI**:先不用著急,我們可以先觀察一下頂點的效果。 先通過搜索創建**Viewer Draw**節點: ![ViewerDraw搜索](https://box.kancloud.cn/28aad7e45a4b7e509ffe77832cbaea18_290x287.png =290x287) 創建之后,即可再畫布見到該節點: ![ViewerDrawNode節點](https://box.kancloud.cn/a7516dee5c73ee8491a914f1e3f5e31a_140x206.png =140x206) 可以見到這個節點,有三個入口: * vertices:頂點 * egd_pol:邊/面 * matrix:矩陣 **H子**:啊,我明白了,也就是說再對應的節點里面傳遞進去對應的數據,就可以在場景上畫出對應的內容了吧。而且看入口的顏色就可以分辨出數據類型了。這么說的話,在**Random Vector MK2**節點的出口的顏色和**Viewer Draw**節點的vertices入口的顏色是一樣的呢。 **AOI**:沒錯,所以可以直接吧這一對出入口鏈接在一起。那么,就連上去看看效果吧。 **H子**:連! ![1-1](https://box.kancloud.cn/76e1c5d5b1bcadb78ed8c80da5e71b14_467x604.png =467x604) 啊!場景上出現頂點了。 這么說,**Viewer Draw**節點上面的三個白色和藍色的應該就是設置顯示顏色了吧,分別對應點線面。 **AOI**:沒錯,從圖標就確實的可以理解到其功能。 **H子**:那么,現在頂點有了,也可以顯示出來了,那么,下一步就是該轉換成模型了吧。 * * * * * ## **貳、將隨機頂點變成模型吧【Convex Hull】節點的運用** **AOI**:好,我們先搜索找到Convex Hull節點吧。 **H子**:**AOI**老師!我搜出來兩個結果了!一個叫**Convex Hull**一個叫**Convex Hull MK2**。他們有什么不同呢? ![ConvexHull搜索結果](https://box.kancloud.cn/e651fa40b09ff57a210b4db8e7ddaa46_279x264.png =279x264) **AOI**:Convex Hull節點顧名思義就是創建一個凸面包裹體的。 先創建兩者的節點看看吧。 ![ConvexHullNode節點。](https://box.kancloud.cn/edd69f5e8aefc24d1dd69c311ed0a58c_311x196.png =311x196) 可以看到,兩者光從外觀上來看,差別還是挺大的,但是仔細觀察接口的話,會發現兩者的入口和出口都是完全一致的。 首先可以見到兩者的入口都只有一個Vertices,從顏色即可看出,這個是接受頂點數據的傳入。而輸出則變成的兩個,一個是Vertices,一個是Polygons。 由此可見,這兩個節點的作用都是通過傳入一組頂點數據,并且基于這一組頂點數據創建一個凸面物體。 而MK2和普通版的特點在于,MK2進一步的提供了包括2D的凸面形狀的創建等的功能,而普通版的節點僅僅針對3D物體的創建。我們要創建的石頭是3D物體,所以只需要使用普通版本即可。 把節點添加到節點樹上試試看把。 **H子**:好!我試試看。 ![2-3](https://box.kancloud.cn/9db454cb034bbb32a44374d6c3e742b1_674x671.png) 我看到了! 出來了!好簡單! 好,**AOI**老師你先不要說!我往下做做看。 點一下BAKE就能得到模型了對吧!對吧!對吧! **AOI**:冷靜!冷靜! **H子**:我點了! ![點擊Bake并把模型拖出](https://box.kancloud.cn/24e08c5516646132d7196176dc30b4d2_465x261.png) 好!然后右鍵選擇模型,拖出來。一模一樣!成功了! **AOI**:對吧,要生成石頭還是很簡單的對不對。只要改變**Random Vector MK2**節點的**Seed**的值,就可以改變造型。當然現在的造型還很粗糙,想要進一步的進行更多的優化,自然要添加更多的節點對產生的數據進行控制。 * * * * * ## **叁、批量產生石頭吧 【Frame Info】節點的運用** **H子**:那么下一步就是開始批量化的產生石頭了吧。首先果然是要不斷的變化**Seed**值呢,但是有什么方法可以不斷的改變呢。手動點果然是不現實的呢,最討厭這種重復的工作了。 **AOI**:仔細想想,在Blender或者一般的3D軟件里面有什么值,是會不斷的變化的呢?或者說,什么值是會自動遞增的呢? **H子**:自動遞增的值嘛?我想想看......啊!是時間!時間軸的值! **AOI**:對了,嚴格來說,就是幀數。當你開始播放的時候,這個是一個會不斷遞增的值。而在Sverchok的節點里面,有一個名為**Frame Info**的節點可以獲得當前幀,并且作為值輸出。 ![Frame Info搜索結果](https://box.kancloud.cn/1a18a80ec2e0eefce3a6a1a99f91fbe4_293x119.png) 搜索Frame Info就可以得到一個唯一結果。創建節點即可。 創建一個**Stethoscope MK2**節點,并且分別吧**Frame Info**節點的每個出口輸出到**Stethoscope MK2**節點的Date入口看看有什么效果吧。 **H子**:好,我試試看! ![current frame](https://box.kancloud.cn/f9fa031eb258d05fe8c8f352d68b2224_400x218.png) ![Start frame](https://box.kancloud.cn/48607ac3af8ad2ee1cb97681a5807515_401x202.png) ![End frame](https://box.kancloud.cn/67c7fba20676b4d957f8f9d99a7338f1_392x205.png) ![Evaluate](https://box.kancloud.cn/8033080dc7b2820214c10ce05c5c3dea_421x213.png) 啊,我懂了,就是當前幀,起始和結束幀,以及當前幀位于起點到終點的百分比吧。 **AOI**:對的,就是這樣。所以實際上會變化的數據只有兩個,也就是CurrentFrame和Evaluate。 因此我們可以選擇吧**CurrentFrame**出口直接連到**Random Vector MK2**節點的**Seed**入口。即可每一幀都改變產生的隨機值了。當然,根據需要,可以使用**Math**節點對**CurrentFrame**輸出的數據進行處理,然后再使用。 **H子**:好的!我連好了!但是總不能每次創建模型都要手動創建吧。 **AOI**:當然不是的,接下來,就給你說說看怎么進行自動化的批量生產吧。 * * * * * ## **肆、自動化產生石頭吧!AnimationNode和腳本的運用**。 **AOI**:已經裝好AnimationNode插件了吧,激活AnimationNode插件之后,就可以在節點編輯器窗口里面切換到AnimationNode界面了。 就是如圖所示的小圖標,點擊切換過去就好了。 ![AnimationNode](https://box.kancloud.cn/7d6fc015824b6dba5a7b7e895d2fff21_123x44.png) 同樣是先創建一個節點樹吧。 **H子**:老師我做好了!但是,為什么要在這里使用另外一個插件呢。 **AOI**:在這里使用AnimationNode的主要原因,自然就是為了使用他的腳本節點了。使用腳本節點,可以根據需要執行腳本。 **H子**:啊,我懂了,也就是說,只要把BAKE按鈕執行的命令,在AnimationNode的腳本節點里面運行就可以了對吧。 **AOI**:沒錯,你理解得很快呢。那么我們就開始操作吧。 首先,創建一個腳本節點。 對了,AnimationNode的搜索快捷鍵是**Ctrl+A**,要好好記住。 ![Script](https://box.kancloud.cn/887deca35c334b8d1eaff79a127290fc_332x292.png) 創建好腳本節點之后如圖所示: ![Script NodeBase](https://box.kancloud.cn/ded8b49febc89867ef0022696da99302_242x185.png) 可以在這里選擇或者新建一份腳本 ![ScriptSelection](https://box.kancloud.cn/e299e6fa5fea937ab66417de4c7616ea_177x32.png) 可以在此處修改腳本節點的名稱,名稱非常重要,因為之后對腳本節點的調用也是以名字為依據。 ![Name](https://box.kancloud.cn/89a8e86f93b9dce5a152fc2386f8aa5c_182x29.png) 在這里,我們就吧他改成AutoBake好了 然后,點擊NewInput按鈕即可創建不同的數據類型輸入接口 ![New Input](https://box.kancloud.cn/1c5f49cdc70176d4b36e9f51dd39e5ca_206x40.png) Script節點的運用,我們就在后面一步一步的細說吧。 為了利用腳本,首先必須有一份腳本。可以通過腳本選擇框旁邊的+按鈕創建,也可以在文本編輯器窗口創建,總之方法很多,無需拘泥。 在這里,就直接點擊旁邊的+按鈕創建吧。 **H子**:我創建好了,程序自動的就根據我的節點名稱創建了同名的腳本了阿 ![](https://box.kancloud.cn/e4086d9a559a485fe9f23c20cf5759a3_236x188.png) **AOI**:然后在界面上劃分出文本編輯器的窗口,并且選擇剛剛創建好的腳本。 **H子**:好的。 ![](https://box.kancloud.cn/9d53c56fbaf73a1240af5db88583ca21_799x516.png) 是一份空白的腳本呢。然后我就可以往里面編寫代碼了嗎。 **AOI**:對的,就是這樣。 接下來,就去獲得BAKE模型的時候使用的命令吧。 切換回到Sverchok界面,并且點擊一下BAKE按鈕,拉出信息欄,即可見到BAKE操作對應的命令了。 ![bake Command](https://box.kancloud.cn/ff2affcffd6ea361a0760cd4becf464d_595x436.png) 右鍵選擇該行命令,同時按Ctrl+C組合鍵復制命令。 然后再把命令粘貼到腳本里面。基本的操作就大功告成了。 ![](https://box.kancloud.cn/3b16216bb23605e0d8b39d2c7985587b_483x156.png) **H子**:那么老師,我有個問題。Script腳本,可以允許沒有輸入和輸出接口,如果這樣的話,不就是只要創建了腳本節點,并擺在畫布上,不管有沒有其他節點流程鏈接進來,都會每一幀都會執行一次了嗎。 **AOI**:你說的很對,所以我們必須進行一些操作,確保不會自動的就執行代碼,并且產生一大堆無用而重復的數據。 首先,切換到AnimationNode節點模式,按T打開工具欄,并切換到AnimationNodes工具欄 ![](https://box.kancloud.cn/cc8430ae2367b0d010618f712938d770_198x354.png) 在Auto Execution面板下面,去掉Always的勾,并勾上Frame Chaneged。這樣的話動畫節點樹就不會總是執行,而只會在當幀有改變的時候才執行一次。 **H子**:等等老師,你這話的意思不就是在說,原本的動畫節點樹,是每一幀都在運行的嗎? **AOI**:你說的并不完全對。 你看到AnimationNode節點編輯器左上角有個毫秒數的數字嗎,那個就是執行完一次動畫節點樹消耗的毫秒數了。之所以一開始是0ms,是因為并沒有任何節點在運行,所以也并沒有任何時間的消耗。但是當你添加任意一個節點進入到畫布的時候,時間就會有變動,也就是說,腳本被執行了。 也由此可見,實際上在AnimationNode中,每個節點的執行本質上是獨立的,他們都會被主動調用,而通過出入口起來,只是為了讓節點流的數據得以按照一個從左到右的方向傳遞和計算。 所以,關閉了Auto Execution的Always的意義,就在于讓腳本不要時刻不停的自動執行下去。 因此,動畫節點樹并非每幀執行一次,而是不斷的執行,與幀無關,只要全部執行完一次,就會自動開始第二次。 **H子**:那么為什么明明添加了Script節點,但是卻沒有執行呢。 **AOI**:這個問題問得好。其原因在于,因為Script節點,其實分成了兩部分。一部分是用于定義,而一部分則是用于執行。創建Script節點的時候,實際上是創建了用于定義部分。只有把用于執行部分的節點創建到畫布上的時候,才會執行。 **H子**:那么,我們該怎么添加執行部分的節點呢。 **AOI**:點擊菜單欄的Subprograms按鈕,再彈出的菜單欄即可見到剛剛創建和和命名為AutoBake的選項了。點擊該選項,即可在畫布上創建一個執行Auto Bake腳本 ![](https://box.kancloud.cn/dfb86f9f777b9f5068a53fd81ef8225a_478x338.png) ![](https://box.kancloud.cn/2c1364b3928db4d063f52a82888f322e_172x96.png) 可以看到,我們現在創建了一個既沒有入口,也沒有出口的名為AutoBake的**Invoke Subprogram**節點,點擊中間的AutoBake按鈕,即可在彈出的菜單選擇并切換成其他的Script節點定義。 那么**H子**,我問你一個問題: 假設,我想讓腳本每隔3幀執行一次,有什么辦法可以做到呢? **H子**:我想想看......首先是要傳遞一個幀數據進來,然后在腳本里面添加判斷,如果當前幀除以3并且余數為0的時候,就執行一次腳本......對吧。 **AOI**:沒錯,基本的思路就是這樣子...... **H子**:欸?!奇怪了老師,為什么沒有FrameInfo節點呢。 **AOI**:因為在AnimationNode里面傳遞幀的節點更簡單,只傳遞當前幀,而且叫做**Time Info** ![](https://box.kancloud.cn/69d32b5f23978747b38a076c922ff918_141x73.png) 好吧,然后接下來為AutoBake的Script節點增加一個float型的數據入口吧。這樣就可以把時間數據傳遞到Script節點內部,并且以變量的形式被代碼調用。 如圖所示,點擊Script 的 New Input按鈕,在彈出的搜索框內輸入Float,即可搜到Float和Float List兩個結果,Float List就是Float數據類型的列表,在此處,我們只需要使用一個數據即可,所以無需使用數組類型。 ![](https://box.kancloud.cn/c324e22489d291cab79616a10fc62b8a_441x195.png) 點擊選擇Float即可完成一個Float入口的創建。 ![](https://box.kancloud.cn/71457fb0bcd85145699b9c44ff79c962_199x281.png) 完成Float型入口的創建之后,默認的入口命名是Float,此處將其改成TimeInfo,入口的名稱同時也是在腳本里面進行調用的變量名。 **H子**:老師我做好了,得到了變量之后,就是說我可以吧**Time Info**節點的輸出值連到這個入口吧。然后只要進一步在代碼里面設置判斷條件就可以了吧? **AOI**:對的,那么,你試試看把代碼完成看看。 **H子**:我已經寫好了,老師看看這個對不對。 ~~~ if(TimeInfo > 0 and TimeInfo % 3 == 0): bpy.ops.node.sverchok_mesh_baker_mk2(idname="Viewer Draw", idtree="NodeTree") ~~~ **AOI**:嗯,不錯,連幀值為0的時候也考慮到了,考慮得挺全面得。 這樣直接執行就可以每隔3幀Bake一次模型了。只要打開時間軸,就可以得到大量得隨機產生的石頭了。 **H子**:我運行了一下,看起來是這樣子的。 ![](https://box.kancloud.cn/9cfff3690221b06d1b866a73516f21f3_360x289.png) 確實達成目的了,每3幀執行一次,并且得到了模型。但是都疊在了一起了。 那不是只能一個個手動拖開了嗎? **AOI**:那就交給你自己思考了。實際上在Sverchok的節點里面,有著很多可以操作各種數據類型的節點。可以考慮運用這些節點,對隨機產生的數據進行操作。并且得到矯正過的數據。最后再轉化成模型。 **H子**:好的!我想想去! * * * * * ## **終、**H子**的努力成果** **H子**最后在邊查文檔邊記錄操作腳本等一系列的努力下,把程序化石頭生成器最終版本完成到了如下的程度: * 把Z軸高度小于0的頂點高度都設置成0,確保的石頭底部扁平 * 烘焙出的模型自動進行對象和數據重命名 * 自動從色表上選取隨機顏色,并添加到石頭的頂點顏色上。 * 把烘焙的模型隨機的分布在場景上,以避免模型的堆疊。 最終版本節點圖: Sverchok節點圖。節點樹名稱為【NodeTree】: ![SV節點圖](https://box.kancloud.cn/b4b2d9729921e0a9dcb41540da2cb634_1752x471.png) Clamp節點圖: ![Clamp節點圖](https://box.kancloud.cn/29d386e6ba34ee05179b7fdb9de59005_698x199.png) AnimationNode節點圖。節點樹名稱為【BakeStone】: ![AN節點圖](https://box.kancloud.cn/d752b21f4b4d3e556bf97f540a6718f1_1320x690.png) AutoBake腳本: ~~~ FinObject = None if(TimeInput > 0 and TimeInput % 10 == 0): #執行Bake命令 bpy.ops.node.sverchok_mesh_baker_mk2(idname="Viewer Draw", idtree="NodeTree") #取消全選 bpy.ops.object.select_all(action='DESELECT') #obj獲取對象名稱為"Sv_0"的模型。因為Bake命令得到的模型默認為Sv_0 obj = bpy.data.objects["Sv_0"] #將模型設置為選中狀態 obj.select = True #按照創建時的幀數為模型重命名,重命名包括對象名和多邊形名 name = "Rock" + str(TimeInput) obj.name = name obj.data.name = name #將模型對象返回給輸出節點,以便用于后續的操作 FinObject = obj ~~~ 最終完成的效果如圖: ![隨機石頭](https://box.kancloud.cn/b4f72f16ed4a58df35d22bd62174ef61_384x235.gif) ![渲染圖](https://box.kancloud.cn/1c34557c74afcfec6c36d5ccdb21d390_461x284.png) * * * * * *附注:因為插件本身并沒有中文支持,如果使用中文Blender界面,插件的文本有部分會因為Blender自身的多語言支持特性而被翻譯成中文,但是會使得插件本身的搜索功能變差,甚至無法通過搜索找到想要的節點。所以建議使用插件的時候盡量使用英文界面。*
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看