日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

随机世界的生成

發布時間:2023/12/29 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 随机世界的生成 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

內容來源:http://accidentalnoise.sourceforge.net/minecraftworlds.html

?更多搜索? unity?Perlin

其他文字 為Unity3D游戲生成2D和3D多邊形隨機地圖:?http://www.manew.com/thread-40880-1-1.html

3D立方體世界級別生成

部分由于游戲的受歡迎程度的Minecraft出現在世界游戲設置做出立方體,3D地形充滿了有趣的東西,如洞穴,出挑,等等所構成的想法引起大家的興趣死灰復燃最近。這樣的世界是ANL風格產生的噪聲的理想應用。這個例子是基于我之前討論這種技術的努力的討論。(這篇鏈接文章后來被收錄在2011年4月的“?游戲開發者雜志”雜志中。)自編寫以來,圖書館的結構發生了一些變化。

在(鏈接到我的世界帖子)中,我討論了使用3D噪聲函數來實現Minecraft風格的地形。從那時起,圖書館已經發展了一點,所以我將重新審視這些帖子并再次討論它。由于我不得不回答很多關于這個系統的問題,所以我將嘗試更清楚地了解所涉及的概念。為了澄清這些基本概念,我將開始創建一個2D地形的想法,就像你在Terraria和King Arthur's Gold等游戲中看到的那樣,然后將其擴展到像Minecraft這樣的3D案例中。這將允許我更有效地使用圖像來演示這些概念。

該系統具有以下抽象目標:能夠使用特定點或單元的坐標來饋送系統,并且能夠確定該位置應該是什么類型的塊。我們希望它是一個黑盒子;?我們給它一點,我們得到一個塊類型。當然,請注意,這僅適用于世界的初始生成。這些類型的游戲中的塊可以通過玩家動作來改變,并且此時嘗試使用相同類型的系統來描述這些改變是不合適的。需要以其他方式跟蹤這些更改。這個系統產生了初始的世界,原始的,沒有人類或非人類的手。

這種技術也可能不適合某些系統(如草或其他生物實體)的建模,因為這些系統本身就是復雜的實體,不容易以隱式方式建模。與降雪,結冰等系統相同......這里介紹的技術代表了一種隱含的方法,即可以在某一點評估的一個,并且在給定點的值不依賴于周圍的值。生物和其他類型的系統通常需要了解周圍環境以便執行精確的模擬。一個街區接收多少陽光?附近有水嗎?必須回答這些問題和其他問題,以模擬生物系統的增長和傳播,并在較小程度上模擬其他類型的氣候相關系統。它也不適合用于水模擬。該系統沒有流動概念,不了解流體力學或重力。水是一個復雜的主題,需要大量復雜的處理。

這并不是說隱含方法在這些方面完全沒用;?事實并非如此。但是,在這些系統中,隱式方法只是眾多工具中的一種。它們可用于模擬區域,擾動區域等,但系統的核心將是執行環境分析和模擬的顯式方法,這超出了本文和此庫的范圍。

所以,我們只是模擬污垢和巖石。我們想要一個功能,告訴我們一個給定的位置應該是污垢,沙子,空氣,金,鐵,煤等......但是,首先,我們將保持簡單。我們想要一個能告訴我們給定塊是Solid還是Air的函數。這個功能應該模擬我們周圍的地球。也就是說,天空在上方,堅固在下面。因此,讓我們承擔將天空與地球分開的圣經任務。為此,讓我們探索漸變功能。梯度函數在N維空間中被給予線段(即,在我們正在工作的任何坐標空間中,無論是2D,3D還是更高),并計算沿著該段對齊的梯度場。輸入坐標投影在此線上,并根據它們相對于定義線段的端點所在線的位置計算其梯度值。投影到段之間某處的點被賦予范圍為(-1,1)的值。所以這給了我們一個很好的起點。我們可以設置沿Y軸對齊的漸變函數。在范圍的頂部,我們將漸變場映射到-1(打開),在底部我們將它映射到1(實心)。

terraintree = {{name =“ground_gradient”,type =“gradient”,x1 = 0,x2 = 0,y1 = 0,y2 = 1} }

(關于符號的快速說明。示例代碼以Lua聲明表的形式編寫。有關格式的更多信息,請參閱Lua集成部分。基本上,格式旨在由特殊類解析,讀取聲明并將它們轉換為噪聲模塊實例的實際樹。我更喜歡這種格式而不是更加冗長的逐步C ++格式,因為它更簡潔,更清晰。我認為,源代碼更具人性化并且比C ++代碼更簡潔。在大多數情況下,聲明應該易于閱讀和理解。模塊被命名,源在適當的時候通過名稱或值指定。用于解析表聲明的Lua代碼包括在內在源代碼分發中,如果要直接使用這些聲明。)

對于2D情況,梯度函數接受(x1,x2,y1,y2)形式的線段,擴展到3D情況的(x1,x2,y1,y2,z1,z2)。由(x1,y1)形成的點描繪了線段的起點,其被映射到0.由(x2,y2)形成的點是映射到1的線段的末端。所以這里我們映射線段(0,1) - >(0,0)到梯度。這將梯度設置在函數的Y = 1和Y = 0區域之間。所以這個樂隊形成了世界的Y范圍。我們映射的任何一個世界都將在這個范圍內。我們可以映射X中的任何區域(實際上是無窮大,但受到雙精度的限制),但有趣的東西,即地面,將位于波段內。現在,這種行為可以調整,但就目前而言,我們有足夠的靈活性。請記住,任何高于或低于此范圍的值都可能是無趣的,因為上面的那些可能全部都是開放的,而下面的那些可能都是可靠的。(正如你將在短時間內看到的那樣,這個陳述實際上可能證明是錯誤的。盡管如此,更多關于此。)對于本系列中的大多數圖像,我將映射由框(0,1)定義的方形區域。 - >(1,0)在2D空間中。那時,我們的世界看起來像這樣:1) - >(1,0)在2D空間中。那時,我們的世界看起來像這樣:1) - >(1,0)在2D空間中。那時,我們的世界看起來像這樣:

?

看起來不是很多,而且它肯定不回答“給定點是固定還是開放?”的問題。為了回答這個問題,我們必須應用所謂的步驟函數。我們希望在一側的所有位置都是開放的,而另一側的所有位置都是實心的,而不是平滑的梯度。在ANL中,我們可以使用Select函數完成此操作。Select函數接受兩個輸入函數或值(在這種情況下它們等同于Solid和Open),并根據控制函數的值(在本例中為Gradient函數)在它們之間進行選擇。Select模塊有兩個附加參數,即閾值衰減,它們會影響此過程。對于這一步,不需要衰減,因此我們將其設置為0.?然而,閾值參數決定了Solid和Ground之間的分界線的繪制位置。漸變函數中大于此值的任何位置都將為“實心”,并且任何小于閾值的位置都將打開。由于漸變映射我們在0和1之間的范圍,因此放置閾值的邏輯位置為0.5。這將空間分成兩半。我們將表示1的值為solid,而將0的值表示為open。所以我們將設置地平面功能如下:

terraintree = {{name =“ground_gradient”,type =“gradient”,x1 = 0,x2 = 0,y1 = 0,y2 = 1},{name =“ground_select”,type =“select”,low = 0,high = 1,threshold = 0.5,control =“ground_gradient”} }

像以前一樣映射函數的相同區域,我們得到這樣的結果:

?

它確實回答了“給定點是固定還是開放?”的問題。您可以在2D空間中使用任何可能的坐標調用該函數,結果將為1或0,具體取決于該點相對于地面的位置。然而,這不是一個非常有趣的功能。只是一條扁平線,延伸到無限遠。為了使它活躍起來,我們將談論一種通常被稱為“湍流”的技術。

對于將值添加到函數的輸入坐標的概念,湍流是一個奇特的詞。想象一下,你用坐標(0,1)調用地面函數。它位于地平面之上,因為在Y = 1時,梯度值為0,小于閾值0.5。所以這一點將被計算為Open。但是,如果在調用地面函數之前,該點已經以某種方式被轉換了呢?如果我們從該點的Y坐標中減去一個隨機值,該怎么辦?說,3?我們減去3,得到坐標(0,-2)。現在,如果我們用這個點調用地面函數,那么該點被評估為實體,因為Y = -2位于梯度段的末尾之外,該梯度段映射到1.所以突然之間,而不是打開,點(0,1)會突然變得堅固。你會在空中漂浮一塊堅固的巖石。通過在調用ground_select函數之前在輸入點的Y坐標中添加或減去隨機數,可以對函數中的任何點執行相同操作。這是ground_select函數的圖像,展示了這一點。在調用ground_select函數之前,每個坐標位置都有一個在(-0.25,0.25)范圍內添加到Y坐標的值。

?

這比扁平線更有趣,但它看起來并不像地面。這是因為每個點都被一個完全隨機的值擾亂,導致混亂的混亂模式。但是,如果我們使用連續隨機函數,例如ANL的?分形函數,而不是混亂的混亂模式,我們將獲得更多控制的東西。所以,讓我們繼續前進,將分形線連接到地面,看看我們得到了什么。

terraintree = {{name =“ground_gradient”,type =“gradient”,x1 = 0,x2 = 0,y1 = 0,y2 = 1},{name =“ground_shape_fractal”,type =“fractal”,fractaltype = anl.FBM,basistype = anl.GRADIENT,interptype = anl.QUINTIC,octaves = 6,frequency = 2},{name =“ground_scale”,type =“scaleoffset”,scale = 0.5,offset = 0,source =“ground_shape_fractal”},{name =“ground_perturb”,type =“translatedomain”,source =“ground_gradient”,ty =“ground_scale”},{name =“ground_select”,type =“select”,low = 0,high = 1,threshold = 0.5,control =“ground_perturb”} }

這里有幾點需要注意。首先,我們設置一個Fractal模塊,并使用ScaleOffset模塊對其進行鏈接。ScaleOffset模塊將分形的輸出縮放到更易管理的級別。一些地形可能是多山的,需要更大的規模,而其他地形更平坦,規模更小。我們稍后會詳細討論不同的地形類型,但現在這將用于演示目的。如果我們現在輸出函數,我們會得到這樣的結果:

?

現在這比純隨機噪音更有趣,不是嗎?至少,即使某些景觀有點奇怪,它也像地面一樣,那些浮島絕對是奇怪的。這是因為輸出圖中的每個點隨機偏移了一個不同的值,由分形確定。為了便于說明,這里是分形的輸出實際上是失真的:

?

上面圖像為黑色的任何地方代表-0.25,白色的任何地方代表0.25。因此,無論分形是最暗的黑色,地面函數中的對應點都會向下“扭曲”0.25。(0.25表示屏幕的1/4。)由于一點可能會稍微扭曲,而空間上方的另一點可能會更加扭曲,這會導致懸垂和浮島的可能性。自然界中的懸垂自然發生。浮島當然不會。(除了阿凡達,就是。科學!)如果你的游戲想擁有這樣奇特的幻想景觀,那么這很棒,但如果你想要一個更逼真的模型,那么我們需要馴服提供失真的分形函數一點點。幸運的是,ScaleDomain?功能提供了這樣的手段。

我們想要做的是強制該函數更像高度圖函數。想象一下2D高度圖,其中地圖中的每個點表示網格點的網格點中的上升或下降的高度或低度。地圖中的白色值表示高山,黑色值表示低山谷。我們想要一個類似的行為,但為了做到這一點,我們必須基本上消除其中一個維度。在高度圖的情況下,我們正在從2D高度圖創建3D地形。同樣,在我們的2D地形的情況下,我們需要有一維高度圖。通過強制分形中具有相同Y坐標的所有點來評估相同的值,然后我們將使用相同的X偏移具有相同量的所有點,從而確保不會出現浮島。我們可以使用ScaleDomain來設置的scaleY因子為0。因此,被稱為ground_shape_fractal功能之前,我們稱之為ground_scale_y按比例繪制在y 0.坐標這確保了Y的值具有分形的輸出沒有影響,從而有效地將其變成一維噪聲函數。為此,我們進行以下更改:

terraintree = {{name =“ground_gradient”,type =“gradient”,x1 = 0,x2 = 0,y1 = 0,y2 = 1},{name =“ground_shape_fractal”,type =“fractal”,fractaltype = anl.FBM,basistype = anl.GRADIENT,interptype = anl.QUINTIC,octaves = 6,frequency = 2},{name =“ground_scale”,type =“scaleoffset”,scale = 0.5,offset = 0,source =“ground_shape_fractal”},{name =“ground_scale_y”,type =“scaledomain”,source =“ground_scale”,scaley = 0},{name =“ground_perturb”,type =“translatedomain”,source =“ground_gradient”,ty =“ground_scale_y”},{name =“ground_select”,type =“select”,low = 0,high = 1,threshold = 0.5,control =“ground_perturb”} }

我們將ScaleDomain函數鏈接到ground_scale,然后將ground_perturb的源更正為ScaleDomain函數。這將改變從上面的圖像擾亂地面的分形,而不是:

現在,如果我們查看輸出,我們可以看到結果:

?

好多了。浮島完全被消除,地形更像是連綿起伏的山脈和丘陵。然而,這種不幸的副作用是懸崖和懸崖的丟失。現在所有的地面都是連續的,滾動的。如果我們愿意,我們可以通過多種方式糾正這種情況。

第一種方法是使用另一個TranslateDomain函數和另一個Fractal。如果我們在X方向上施加少量的分形湍流,我們可以稍微擾亂山脈的邊緣和表面,足以形成一些懸崖和懸垂。讓我們看看它在行動中。

terraintree = {{name =“ground_gradient”,type =“gradient”,x1 = 0,x2 = 0,y1 = 0,y2 = 1},{name =“ground_shape_fractal”,type =“fractal”,fractaltype = anl.FBM,basistype = anl.GRADIENT,interptype = anl.QUINTIC,octaves = 6,frequency = 2},{name =“ground_scale”,type =“scaleoffset”,scale = 0.5,offset = 0,source =“ground_shape_fractal”},{name =“ground_scale_y”,type =“scaledomain”,source =“ground_scale”,scaley = 0},{name =“ground_perturb”,type =“translatedomain”,source =“ground_gradient”,ty =“ground_scale_y”},{name =“ground_overhang_fractal”,type =“fractal”,fractaltype = anl.FBM,basistype = anl.GRADIENT,interptype = anl.QUINTIC,octaves = 6,frequency = 2},{name =“ground_overhang_scale”,type =“scaleoffset”,source =“ground_overhang_fractal”,scale = 0.2,offset = 0},{name =“ground_overhang_perturb”,type =“translatedomain”,source =“ground_perturb”,tx =“ground_overhang_scale”},{name =“ground_select”,type =“select”,low = 0,high = 1,threshold = 0.5,control =“ground_overhang_perturb”} }

結果是:

?

第二種方式就是設定的scaleY的參數ground_scale_y到的東西比0離開Y標尺的功能有點讓一些變化大,雖然較高的設置規模,更多的地形會來類似于早期的,未擴展的版本。

這些結果肯定比滾山更有趣。然而,盡管它很有趣,它仍然會變得非常無聊,探索一個無盡的英里和相同的一般模式的地形。更重要的是,這樣的地形將是非常不現實的。自然界有很多變化來保持事物的趣味性。因此,讓我們看看我們可以做些什么來讓世界變得更加多樣化。

查看前面的示例代碼,我們可以看到那里的模式。我們有漸變功能,在應用步進功能和地面給定堅固之前,由功能操縱以給出地面形狀。因此,為了增加不同的地形而開始使事物變得復雜的自然地方是給出地形的部分。我們可以像我們喜歡的那樣復雜(而且我們可以負擔得起;每個分形都會增加處理開銷,所以你應該只使用盡可能多的分數,而不是使用一個分形來擾亂Y和另一個擾亂X.需要,并盡量保守。)我們可以設置代表山脈,山麓,低地平原,荒地等的地形......并使用各種選擇的輸出函數,鏈接到低頻分形,描繪每種類型的區域。那么,讓我們來看看我們如何實現各種類型的地形。

為了便于說明,我們將設置三種類型的地形:高地(平緩起伏的山丘),山脈和低地(大多是平坦的)。我們將使用基于選擇的系統在它們之間切換,并將它們全部拼接成復雜的掛毯。我們走了......

低地:

這個很容易。我們可以使用上面的設置,稍微降低山丘的振幅,甚至可以使它們比加法更具減法性,以降低平均海拔。我們可能會降低八度計數以使它們更平滑。

{name =“lowland_shape_fractal”,type =“fractal”,fractaltype = anl.FBM,basistype = anl.GRADIENT,interptype = anl.QUINTIC,octaves = 2,frequency = 1}, {name =“lowland_autocorrect”,type =“autocorrect”,source =“lowland_shape_fractal”,low = 0,high = 1}, {name =“lowland_scale”,type =“scaleoffset”,source =“lowland_autocorrect”,scale = 0.2,offset = -0.25}, {name =“lowland_y_scale”,type =“scaledomain”,source =“lowland_scale”,scaley = 0}, {name =“lowland_terrain”,type =“translatedomain”,source =“ground_gradient”,ty =“lowland_y_scale”},

高原:

再次,簡單。(實際上,這些都不是真的那么難。)但是,我們將使用不同的基礎,使山丘像沙丘一樣。

{name =“highland_shape_fractal”,type =“fractal”,fractaltype = anl.RIDGEDMULTI,basistype = anl.GRADIENT,interptype = anl.QUINTIC,octaves = 2,frequency = 2}, {name =“highland_autocorrect”,type =“autocorrect”,source =“highland_shape_fractal”,low = 0,high = 1}, {name =“highland_scale”,type =“scaleoffset”,source =“highland_autocorrect”,scale = 0.45,offset = 0}, {name =“highland_y_scale”,type =“scaledomain”,source =“highland_scale”,scaley = 0}, {name =“highland_terrain”,type =“translatedomain”,source =“ground_gradient”,ty =“highland_y_scale”},

山:

{name =“mountain_shape_fractal”,type =“fractal”,fractaltype = anl.BILLOW,basistype = anl.GRADIENT,interptype = anl.QUINTIC,octaves = 4,frequency = 1}, {name =“mountain_autocorrect”,type =“autocorrect”,source =“mountain_shape_fractal”,low = 0,high = 1}, {name =“mountain_scale”,type =“scaleoffset”,source =“mountain_autocorrect”,scale = 0.75,offset = 0.25}, {name =“mountain_y_scale”,type =“scaledomain”,source =“mountain_scale”,scaley = 0.1}, {name =“mountain_terrain”,type =“translatedomain”,source =“ground_gradient”,ty =“mountain_y_scale”},

當然,你可以獲得更多的創意,但這確立了一般模式。您可以考慮地形的特征,并構建適合您的噪聲功能。所有這些都遵循相同的原則;?差異主要在于規模。現在,為了將它們組合在一起,我們將設置一些額外的分形來充當Select的控件。然后我們將Select模塊鏈接在一起以生成整體。

{name =“terrain_type_fractal”,type =“fractal”,fractaltype = anl.FBM,basistype = anl.GRADIENT,interptype = anl.QUINTIC,octaves = 3,frequency = 0.5}, {name =“terrain_autocorrect”,type =“autocorrect”,source =“terrain_type_fractal”,low = 0,high = 1}, {name =“terrain_type_cache”,type =“cache”,source =“terrain_autocorrect”}, {name =“highland_mountain_select”,type =“select”,low =“highland_terrain”,high =“mountain_terrain”,control =“terrain_type_cache”,threshold = 0.55,falloff = 0.15}, {name =“highland_lowland_select”,type =“select”,low =“lowland_terrain”,high =“highland_mountain_select”,control =“terrain_type_cache”,threshold = 0.25,falloff = 0.15},

所以我們在這里為低地,高地和山脈建立了三種主要類型。我們使用一個分形來在所有三個之間進行選擇,以便從低地 - >高地 - >山脈中自然發展。然后我們使用另一個分形隨機將荒地插入地圖。最終的模塊鏈是:

terraintree = {{name =“lowland_shape_fractal”,type =“fractal”,fractaltype = anl.FBM,basistype = anl.GRADIENT,interptype = anl.QUINTIC,octaves = 2,frequency = 1},{name =“lowland_autocorrect”,type =“autocorrect”,source =“lowland_shape_fractal”,low = 0,high = 1},{name =“lowland_scale”,type =“scaleoffset”,source =“lowland_autocorrect”,scale = 0.2,offset = -0.25},{name =“lowland_y_scale”,type =“scaledomain”,source =“lowland_scale”,scaley = 0},{name =“lowland_terrain”,type =“translatedomain”,source =“ground_gradient”,ty =“lowland_y_scale”},{name =“ground_gradient”,type =“gradient”,x1 = 0,x2 = 0,y1 = 0,y2 = 1},{name =“highland_shape_fractal”,type =“fractal”,fractaltype = anl.RIDGEDMULTI,basistype = anl.GRADIENT,interptype = anl.QUINTIC,octaves = 2,frequency = 2},{name =“highland_autocorrect”,type =“autocorrect”,source =“highland_shape_fractal”,low = 0,high = 1},{name =“highland_scale”,type =“scaleoffset”,source =“highland_autocorrect”,scale = 0.45,offset = 0},{name =“highland_y_scale”,type =“scaledomain”,source =“highland_scale”,scaley = 0},{name =“highland_terrain”,type =“translatedomain”,source =“ground_gradient”,ty =“highland_y_scale”},{name =“mountain_shape_fractal”,type =“fractal”,fractaltype = anl.BILLOW,basistype = anl.GRADIENT,interptype = anl.QUINTIC,octaves = 4,frequency = 1},{name =“mountain_autocorrect”,type =“autocorrect”,source =“mountain_shape_fractal”,low = 0,high = 1},{name =“mountain_scale”,type =“scaleoffset”,source =“mountain_autocorrect”,scale = 0.75,offset = 0.25},{name =“mountain_y_scale”,type =“scaledomain”,source =“mountain_scale”,scaley = 0.1},{name =“mountain_terrain”,type =“translatedomain”,source =“ground_gradient”,ty =“mountain_y_scale”},{name =“terrain_type_fractal”,type =“fractal”,fractaltype = anl.FBM,basistype = anl.GRADIENT,interptype = anl.QUINTIC,octaves = 3,frequency = 0.5},{name =“terrain_autocorrect”,type =“autocorrect”,source =“terrain_type_fractal”,low = 0,high = 1},{name =“terrain_type_cache”,type =“cache”,source =“terrain_autocorrect”},{name =“highland_mountain_select”,type =“select”,low =“highland_terrain”,high =“mountain_terrain”,control =“terrain_type_cache”,threshold = 0.55,falloff = 0.15},{name =“highland_lowland_select”,type =“select”,low =“lowland_terrain”,high =“highland_mountain_select”,control =“terrain_type_cache”,threshold = 0.25,falloff = 0.15},{name =“ground_select”,type =“select”,low = 0,high = 1,threshold = 0.5,control =“highland_lowland_select”} }

以下是這將產生的各種地形的隨機全景照片:

你可以看到那里有一個非常好的變化。有些地方有高聳的鋸齒狀山脈,而其他地方有平緩的公寓。現在,我們想要添加洞穴,以探索地下的奇跡。

對于洞穴,我使用了一個針對ground_select的乘法系統。也就是說,我想出了一個輸出1或0的函數,并將它與ground_select的輸出相乘。這具有設置為在洞穴函數中打開函數中0的任何位置的效果。所以我想要一個洞穴出現的地方必須在洞穴功能中返回0,我希望它不是我設置為1的洞穴。至于洞穴的形狀,我喜歡將洞穴系統基于1個八度音程山脊多重分形。

{name =“cave_shape”,type =“fractal”,fractaltype = anl.RIDGEDMULTI,basistype = anl.GRADIENT,interptype = anl.QUINTIC,octaves = 1,frequency = 2},

這導致類似于:

如果將Select函數應用為階梯函數,就像我們對地面漸變一樣,使閾值的低邊選擇為1(無洞穴),高邊選擇為0(洞穴),然后結果看起來像這樣:

{name =“cave_shape”,type =“fractal”,fractaltype = anl.RIDGEDMULTI,basistype = anl.GRADIENT,interptype = anl.QUINTIC,octaves = 1,frequency = 2}, {name =“cave_select”,type =“select”,low = 1,high = 0,control =“cave_shape”,threshold = 0.8,falloff = 0},

結果:

當然,這看起來相當平滑,所以讓我們添加一些分形噪聲來擾亂域。

{name =“cave_shape”,type =“fractal”,fractaltype = anl.RIDGEDMULTI,basistype = anl.GRADIENT,interptype = anl.QUINTIC,octaves = 1,frequency = 2}, {name =“cave_select”,type =“select”,low = 1,high = 0,control =“cave_shape”,threshold = 0.8,falloff = 0}, {name =“cave_perturb_fractal”,type =“fractal”,fractaltype = anl.FBM,basistype = anl.GRADIENT,interptype = anl.QUINTIC,octaves = 6,frequency = 3}, {name =“cave_perturb_scale”,type =“scaleoffset”,source =“cave_perturb_fractal”,scale = 0.25,offset = 0}, {name =“cave_perturb”,type =“translatedomain”,source =“cave_select”,tx =“cave_perturb_scale”},

結果:

這樣可以使洞穴稍微變暗,并使它們不那么平滑。讓我們看看如果我們現在將洞穴應用于地形可能會是什么樣子:

通過與該值打門限cave_select,我們可以使洞穴薄或厚。但我們真正應該做的一件事就是盡量做到這一點,以便洞穴不會從地表地形挖出如此巨大的,不敬虔的塊狀物。要做到這一點,我們可以回到highland_lowland_select函數,你會記得,這是用于擾亂地面漸變的最終地形函數。這里有用的功能是它仍然是一個梯度,隨著函數深入地球而增加。我們可以使用這個梯度來減弱洞穴功能,以便在您深入地球時洞穴變得更大。幸運的是,這種衰減可以簡單地通過乘以輸出來實現highland_lowland_select函數使用cave_shape的輸出,然后將結果傳遞給cave函數鏈的其余部分。現在,我們要做的一個重要改變是增加了一個Cache功能。緩存函數將存儲給定輸入坐標的函數結果,如果使用相同的坐標再次調用該函數,它將返回緩存的副本,而不是重新計算結果。這對于這樣的情況很有用,其中一個復雜函數(highland_lowland_select)將在模塊鏈中被多次調用。如果沒有緩存,每次調用復雜函數的整個鏈時都會重新計算。要引入緩存,我們首先進行以??下更改:

{name =“highland_lowland_select”,type =“select”,low =“lowland_terrain”,high =“highland_mountain_select”,control =“terrain_type_cache”,threshold = 0.25,falloff = 0.15}, {name =“highland_lowland_select_cache”,type =“cache”,source =“highland_lowland_select”}, {name =“ground_select”,type =“select”,low = 0,high = 1,threshold = 0.5,control =“highland_lowland_select_cache”},

這會附加Cache,然后重定向ground_select的輸入來自緩存,而不是直接來自函數。然后我們可以修改洞穴代碼來添加衰減:

{name =“cave_shape”,type =“fractal”,fractaltype = anl.RIDGEDMULTI,basistype = anl.GRADIENT,interptype = anl.QUINTIC,octaves = 1,frequency = 4}, {name =“cave_attenuate_bias”,type =“bias”,source =“highland_lowland_select_cache”,bias = 0.45}, {name =“cave_shape_attenuate”,type =“combiner”,operation = anl.MULT,source_0 =“cave_shape”,source_1 =“cave_attenuate_bias”}, {name =“cave_perturb_fractal”,type =“fractal”,fractaltype = anl.FBM,basistype = anl.GRADIENT,interptype = anl.QUINTIC,octaves = 6,frequency = 3}, {name =“cave_perturb_scale”,type =“scaleoffset”,source =“cave_perturb_fractal”,scale = 0.5,offset = 0}, {name =“cave_perturb”,type =“translatedomain”,source =“cave_shape_attenuate”,tx =“cave_perturb_scale”}, {name =“cave_select”,type =“select”,low = 1,high = 0,control =“cave_perturb”,threshold = 0.48,falloff = 0},

我們首先添加了Bias功能。這是為了方便起見,允許我們調整梯度衰減函數的范圍。然后我們添加了cave_shape_attenuate函數,它是anl :: MULT類型的Combiner。這會將漸變乘以cave_shape。然后將結果傳遞給cave_perturb函數。結果看起來像這樣:

你可以看到洞穴在朝向地面的區域變得更薄。(忽略頂部的東西,它只是漸變的一個神器,對最終的洞穴沒有影響。如果它成為一個問題 - 比方說,如果你把這個函數用于別的東西,那么漸變可以在被使用之前被鉗制到(0,1)。)有點難以看出它是如何與地形相關的,所以讓我們繼續把所有東西合成在一起,看看我們得到了什么。到目前為止,這是我們的整個功能鏈。

terraintree = {{name =“ground_gradient”,type =“gradient”,x1 = 0,x2 = 0,y1 = 0,y2 = 1},{name =“lowland_shape_fractal”,type =“fractal”,fractaltype = anl.BILLOW,basistype = anl.GRADIENT,interptype = anl.QUINTIC,octaves = 2,frequency = 0.25},{name =“lowland_autocorrect”,type =“autocorrect”,source =“lowland_shape_fractal”,low = 0,high = 1},{name =“lowland_scale”,type =“scaleoffset”,source =“lowland_autocorrect”,scale = 0.125,offset = -0.45},{name =“lowland_y_scale”,type =“scaledomain”,source =“lowland_scale”,scaley = 0},{name =“lowland_terrain”,type =“translatedomain”,source =“ground_gradient”,ty =“lowland_y_scale”},{name =“highland_shape_fractal”,type =“fractal”,fractaltype = anl.FBM,basistype = anl.GRADIENT,interptype = anl.QUINTIC,octaves = 4,frequency = 2},{name =“highland_autocorrect”,type =“autocorrect”,source =“highland_shape_fractal”,low = -1,high = 1},{name =“highland_scale”,type =“scaleoffset”,source =“highland_autocorrect”,scale = 0.25,offset = 0},{name =“highland_y_scale”,type =“scaledomain”,source =“highland_scale”,scaley = 0},{name =“highland_terrain”,type =“translatedomain”,source =“ground_gradient”,ty =“highland_y_scale”},{name =“mountain_shape_fractal”,type =“fractal”,fractaltype = anl.RIDGEDMULTI,basistype = anl.GRADIENT,interptype = anl.QUINTIC,octaves = 8,frequency = 1},{name =“mountain_autocorrect”,type =“autocorrect”,source =“mountain_shape_fractal”,low = -1,high = 1},{name =“mountain_scale”,type =“scaleoffset”,source =“mountain_autocorrect”,scale = 0.45,offset = 0.15},{name =“mountain_y_scale”,type =“scaledomain”,source =“mountain_scale”,scaley = 0.25},{name =“mountain_terrain”,type =“translatedomain”,source =“ground_gradient”,ty =“mountain_y_scale”},{name =“terrain_type_fractal”,type =“fractal”,fractaltype = anl.FBM,basistype = anl.GRADIENT,interptype = anl.QUINTIC,octaves = 3,frequency = 0.125},{name =“terrain_autocorrect”,type =“autocorrect”,source =“terrain_type_fractal”,low = 0,high = 1},{name =“terrain_type_y_scale”,type =“scaledomain”,source =“terrain_autocorrect”,scaley = 0},{name =“terrain_type_cache”,type =“cache”,source =“terrain_type_y_scale”},{name =“highland_mountain_select”,type =“select”,low =“highland_terrain”,high =“mountain_terrain”,control =“terrain_type_cache”,threshold = 0.55,falloff = 0.2},{name =“highland_lowland_select”,type =“select”,low =“lowland_terrain”,high =“highland_mountain_select”,control =“terrain_type_cache”,threshold = 0.25,falloff = 0.15},{name =“highland_lowland_select_cache”,type =“cache”,source =“highland_lowland_select”},{name =“ground_select”,type =“select”,low = 0,high = 1,threshold = 0.5,control =“highland_lowland_select_cache”},{name =“cave_shape”,type =“fractal”,fractaltype = anl.RIDGEDMULTI,basistype = anl.GRADIENT,interptype = anl.QUINTIC,octaves = 1,frequency = 4},{name =“cave_attenuate_bias”,type =“bias”,source =“highland_lowland_select_cache”,bias = 0.45},{name =“cave_shape_attenuate”,type =“combiner”,operation = anl.MULT,source_0 =“cave_shape”,source_1 =“cave_attenuate_bias”},{name =“cave_perturb_fractal”,type =“fractal”,fractaltype = anl.FBM,basistype = anl.GRADIENT,interptype = anl.QUINTIC,octaves = 6,frequency = 3},{name =“cave_perturb_scale”,type =“scaleoffset”,source =“cave_perturb_fractal”,scale = 0.5,offset = 0},{name =“cave_perturb”,type =“translatedomain”,source =“cave_shape_attenuate”,tx =“cave_perturb_scale”},{name =“cave_select”,type =“select”,low = 1,high = 0,control =“cave_perturb”,threshold = 0.48,falloff = 0},{name =“ground_cave_multiply”,type =“combiner”,operation = anl.MULT,source_0 =“cave_select”,source_1 =“ground_select”} }

以下是此功能的隨機位置選擇:

現在看起來很不錯。洞穴都是地下深處相當大的洞穴,但在地表,它們往往會衰減到小隧道。這有助于營造神秘氣息。當您外出探索這片土地時,您會遇到一個小洞穴入口。它去哪兒了?它有多深?沒有辦法說,但隨著你的探索,它開始擴大到廣闊的洞穴,充滿了黑暗和危險。當然還有戰利品。永遠是戰利品。

您可以通過多種方式調整此方法以獲得不同的結果。您可以修改閾值設置cave_select和設置cave_attenuate_bias,或更改cave_attenuate_bias到不同的功能來重映射漸變的范圍,以更好地滿足您的需求。您可以添加另一個在Y軸上擾亂洞穴系統的分形,以消除X方向上偶然出現的非自然光滑隧道(僅在X中擾亂洞穴形狀)。您可以添加另一個分形作為另一個衰減源,設置為cave_shape_attenuate的第三個源在區域基礎上縮放衰減,使得洞穴在某些區域(例如,可能是山脈)更密集地出現,而在其他區域則更不密集或根本不出現。該區域選擇器將從terrain_type_fractal函數派生,以了解山區的位置。這一切只是考慮你想要什么,了解各種功能對輸出的影響,并嘗試各種參數,直到你得到你喜歡的東西。這不是一門完美的科學,通常有很多方法可以達到任何特定的效果。

缺點

這種地形生成方法存在缺陷。產生噪音可能相當慢。重要的是減少分形的數量,你使用的分形的八度計數,以及盡可能減少其他慢速操作。盡可能嘗試重新使用分形,并緩存每個被調用多次的函數。在這個例子中,我非常自由地使用分形,為三種地形類型中的每一種提供單獨的分形。通過使用ScaleOffset重新映射范圍并將它們全部基于單個分形,我本可以節省大量處理時間。在2D中它并不是那么糟糕,但是當你開始進入3D并嘗試映射大量數據時,時間真的會增加。

擴展到3D

現在,如果你制作像Terraria或King Arthur's Gold這樣的游戲,這一切都很棒,但如果你想制作像Minecraft或Infiniminer這樣的游戲呢?代替?我們要對功能鏈做出哪些改變?答案是“不多”。上面的功能鏈幾乎可以直接用于3D地形。您所要做的就是使用生成器的3D變體映射3D體積,并將Y軸映射到體積的垂直軸,而不是2D區域。但是,需要進行一項更改,即洞穴的工作方式。你看,Ridged Multifractal適用于2D洞穴系統,但在3D中它雕刻了一系列彎曲的殼而不是隧道,效果不對。所以在3D中,有必要設置2個洞穴形狀分形,包括1個八度嶺脊多重分形噪聲但具有不同的種子,將它們選擇為1或0,并將它們相乘。這樣,無論分形交叉哪里變成洞穴,

terraintree3d = {{name =“ground_gradient”,type =“gradient”,x1 = 0,x2 = 0,y1 = 0,y2 = 1},{name =“lowland_shape_fractal”,type =“fractal”,fractaltype = anl.BILLOW,basistype = anl.GRADIENT,interptype = anl.QUINTIC,octaves = 2,frequency = 0.25},{name =“lowland_autocorrect”,type =“autocorrect”,source =“lowland_shape_fractal”,low = 0,high = 1},{name =“lowland_scale”,type =“scaleoffset”,source =“lowland_autocorrect”,scale = 0.125,offset = -0.45},{name =“lowland_y_scale”,type =“scaledomain”,source =“lowland_scale”,scaley = 0},{name =“lowland_terrain”,type =“translatedomain”,source =“ground_gradient”,ty =“lowland_y_scale”},{name =“highland_shape_fractal”,type =“fractal”,fractaltype = anl.FBM,basistype = anl.GRADIENT,interptype = anl.QUINTIC,octaves = 4,frequency = 2},{name =“highland_autocorrect”,type =“autocorrect”,source =“highland_shape_fractal”,low = -1,high = 1},{name =“highland_scale”,type =“scaleoffset”,source =“highland_autocorrect”,scale = 0.25,offset = 0},{name =“highland_y_scale”,type =“scaledomain”,source =“highland_scale”,scaley = 0},{name =“highland_terrain”,type =“translatedomain”,source =“ground_gradient”,ty =“highland_y_scale”},{name =“mountain_shape_fractal”,type =“fractal”,fractaltype = anl.RIDGEDMULTI,basistype = anl.GRADIENT,interptype = anl.QUINTIC,octaves = 8,frequency = 1},{name =“mountain_autocorrect”,type =“autocorrect”,source =“mountain_shape_fractal”,low = -1,high = 1},{name =“mountain_scale”,type =“scaleoffset”,source =“mountain_autocorrect”,scale = 0.45,offset = 0.15},{name =“mountain_y_scale”,type =“scaledomain”,source =“mountain_scale”,scaley = 0.25},{name =“mountain_terrain”,type =“translatedomain”,source =“ground_gradient”,ty =“mountain_y_scale”},{name =“terrain_type_fractal”,type =“fractal”,fractaltype = anl.FBM,basistype = anl.GRADIENT,interptype = anl.QUINTIC,octaves = 3,frequency = 0.125},{name =“terrain_autocorrect”,type =“autocorrect”,source =“terrain_type_fractal”,low = 0,high = 1},{name =“terrain_type_y_scale”,type =“scaledomain”,source =“terrain_autocorrect”,scaley = 0},{name =“terrain_type_cache”,type =“cache”,source =“terrain_type_y_scale”},{name =“highland_mountain_select”,type =“select”,low =“highland_terrain”,high =“mountain_terrain”,control =“terrain_type_cache”,threshold = 0.55,falloff = 0.2},{name =“highland_lowland_select”,type =“select”,low =“lowland_terrain”,high =“highland_mountain_select”,control =“terrain_type_cache”,threshold = 0.25,falloff = 0.15},{name =“highland_lowland_select_cache”,type =“cache”,source =“highland_lowland_select”},{name =“ground_select”,type =“select”,low = 0,high = 1,threshold = 0.5,control =“highland_lowland_select_cache”},{name =“cave_attenuate_bias”,type =“bias”,source =“highland_lowland_select_cache”,bias = 0.45},{name =“cave_shape1”,type =“fractal”,fractaltype = anl.RIDGEDMULTI,basistype = anl.GRADIENT,interptype = anl.QUINTIC,octaves = 1,frequency = 4},{name =“cave_shape2”,type =“fractal”,fractaltype = anl.RIDGEDMULTI,basistype = anl.GRADIENT,interptype = anl.QUINTIC,octaves = 1,frequency = 4},{name =“cave_shape_attenuate”,type =“combiner”,operation = anl.MULT,source_0 =“cave_shape1”,source_1 =“cave_attenuate_bias”,source_2 =“cave_shape2”}, {name =“cave_perturb_fractal”,type =“fractal”,fractaltype = anl.FBM,basistype = anl.GRADIENT,interptype = anl.QUINTIC,octaves = 6,frequency = 3},{name =“cave_perturb_scale”,type =“scaleoffset”,source =“cave_perturb_fractal”,scale = 0.5,offset = 0},{name =“cave_perturb”,type =“translatedomain”,source =“cave_shape_attenuate”,tx =“cave_perturb_scale”},{name =“cave_select”,type =“select”,low = 1,high = 0,control =“cave_perturb”,threshold = 0.48,falloff = 0},{name =“ground_cave_multiply”,type =“combiner”,operation = anl.MULT,source_0 =“cave_select”,source_1 =“ground_select”} }

一些結果:

現在,它看起來像一些參數需要一些調整。也許減少衰減,或加厚洞穴,減少地形分形中的八度音階數,使地形更平滑等等......再次,這完全取決于你想要達到的目的。

轉載于:https://www.cnblogs.com/sanyejun/p/9300799.html

總結

以上是生活随笔為你收集整理的随机世界的生成的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。