2017-04-04 107 views
5

我想與程序生成相處,我絕對不是在統一的親,但我遵循本指南:click並得到了一些結果。現在我有兩個問題,我有一些基本的想法如何解決他們,但我想聽聽其他意見。在Unity 3D中的程序地形編程

(我已經發布了關於Unity答案的這個問題,但是我沒有得到任何答覆,如果有一些缺失的信息或者無法用幾句話來解釋,請讓我知道或給一些建議要找到這些信息)

的主要問題是:缺口塊之間:

enter image description here

他們還挺消失,如果我將縮小,但質地仍不適宜,這是顯着的。

第二,你可以看到我有一個紅色的問題(我真的不知道怎麼稱呼它)在地面上標記。我嘗試過從指南中使用材料,但效果相同。另外,Perlin Noise(我知道我可以使用Diamond square或simplex)是僞隨機算法,所以它會爲相同的輸入參數返回相同的值,所以這是否意味着我的塊總是相同?

我的代碼(我用LibNoise庫與引導):

void Awake() 
    { 
     var settings = new TerrainChunkSettings(129, 129, 100, 40, FlatTexture, SteepTexture, TerrainMaterial); 
     var noiseProvider = new NoiseProvider(); 
     for (var i = 0; i < 4; i++) 
      for (var j = 0; j < 4; j++) 
       new TerrainChunk(settings, noiseProvider, i, j).CreateTerrain(); 
    } 
public class TerrainChunkSettings 
{ 
    public int HeightmapResolution { get; private set; } 

    public int AlphamapResolution { get; private set; } 

    public int Length { get; private set; } 

    public int Height { get; private set; } 

    public Texture2D FlatTexture { get; private set; } 

    public Texture2D SteepTexture { get; private set; } 

    public Material TerrainMaterial { get; private set; } 

    public TerrainChunkSettings(int heightmapResolution, int alphamapResolution, int length, int height, Texture2D flatTexture, Texture2D steepTexture, Material terrainMaterial) 
    { 
     HeightmapResolution = heightmapResolution; 
     AlphamapResolution = alphamapResolution; 
     Length = length; 
     Height = height; 
     FlatTexture = flatTexture; 
     SteepTexture = steepTexture; 
     TerrainMaterial = terrainMaterial; 
    } 
} 

public class TerrainChunk 
{ 
    private Terrain Terrain { get; set; } 

    private TerrainChunkSettings Settings { get; set; } 

    private NoiseProvider NoiseProvider { get; set; } 

    public int X { get; private set; } 

    public int Z { get; private set; } 

    private TerrainData Data { get; set; } 

    private float[,] Heightmap { get; set; } 
    public TerrainChunk(TerrainChunkSettings settings, NoiseProvider noiseProvider, int x, int z) 
    { 
     X = x; 
     Z = z; 
     Settings = settings; 
     NoiseProvider = noiseProvider; 
    } 

    public void CreateTerrain() 
    { 
     var terrainData = new TerrainData(); 
     terrainData.heightmapResolution = Settings.HeightmapResolution; 
     terrainData.alphamapResolution = Settings.AlphamapResolution; 

     var heightmap = GetHeightmap(); 
     terrainData.SetHeights(0, 0, heightmap); 
     ApplyTextures(terrainData); 
     terrainData.size = new Vector3(Settings.Length, Settings.Height, Settings.Length); 

     var newTerrainGameObject = Terrain.CreateTerrainGameObject(terrainData); 
     newTerrainGameObject.transform.position = new Vector3(X * Settings.Length, 0, Z * Settings.Length); 
     Terrain = newTerrainGameObject.GetComponent<Terrain>(); 
     Terrain.Flush(); 
    } 

    private float[,] GetHeightmap() 
    { 
     var heightmap = new float[Settings.HeightmapResolution, Settings.HeightmapResolution]; 

     for (var zRes = 0; zRes < Settings.HeightmapResolution; zRes++) 
     { 
      for (var xRes = 0; xRes < Settings.HeightmapResolution; xRes++) 
      { 
       var xCoordinate = X + (float)xRes/(Settings.HeightmapResolution - 1); 
       var zCoordinate = Z + (float)zRes/(Settings.HeightmapResolution - 1); 

       heightmap[zRes, xRes] = NoiseProvider.GetValue(xCoordinate, zCoordinate); 
      } 
     } 

     return heightmap; 
    } 

    private void ApplyTextures(TerrainData terrainData) 
    { 
     var flatSplat = new SplatPrototype(); 
     var steepSplat = new SplatPrototype(); 

     flatSplat.texture = Settings.FlatTexture; 
     steepSplat.texture = Settings.SteepTexture; 

     terrainData.splatPrototypes = new SplatPrototype[] 
     { 
      flatSplat, 
      steepSplat 
     }; 

     terrainData.RefreshPrototypes(); 

     var splatMap = new float[terrainData.alphamapResolution, terrainData.alphamapResolution, 2]; 

     for (var zRes = 0; zRes < terrainData.alphamapHeight; zRes++) 
     { 
      for (var xRes = 0; xRes < terrainData.alphamapWidth; xRes++) 
      { 
       var normalizedX = (float)xRes/(terrainData.alphamapWidth - 1); 
       var normalizedZ = (float)zRes/(terrainData.alphamapHeight - 1); 

       var steepness = terrainData.GetSteepness(normalizedX, normalizedZ); 
       var steepnessNormalized = Mathf.Clamp(steepness/1.5f, 0, 1f); 

       splatMap[zRes, xRes, 0] = 1f - steepnessNormalized; 
       splatMap[zRes, xRes, 1] = steepnessNormalized; 
      } 
     } 

     terrainData.SetAlphamaps(0, 0, splatMap); 
    } 
} 

public interface INoiseProvider 
{ 
    float GetValue(float x, float z); 
} 
public class NoiseProvider : INoiseProvider 
{ 
    private Perlin PerlinNoiseGenerator; 

    public NoiseProvider() 
    { 
     PerlinNoiseGenerator = new Perlin(); 
    } 

    public float GetValue(float x, float z) 
    { 
     return (float)(PerlinNoiseGenerator.GetValue(x, 0, z)/2f) + 0.5f; 
    } 
} 
+1

你能更清楚你的問題是什麼嗎?我在您的帖子中看到三個可能的問題(1.差距,2.紅色標記和3.佩林噪聲值)。通常,您應該嘗試在Stack Overflow的問題中只提出一件事,但如果問題密切相關,則可能會出現異常。此外,如果以問號結尾,則可以更清楚地表明某件事是一個問題。 – PJvG

+1

關於Perlin噪聲,你可以在[GitHub上的LibNoise庫](https://github.com/ricardojmendez/LibNoise.Unity/blob/master/Generator/Perlin.cs)中看到它有一個'Seed'屬性。如果你想得到不同的結果,你應該爲'Perlin'對象使用不同的種子。如果您仍然感到困惑,那麼可以對僞隨機生成器和種子做更多的研究。 – PJvG

+1

@PjvG我知道每個帖子有1個問題(論壇上的常見規則),但我真的不認爲我應該將它們分開。所以,我會盡力澄清我的自我,主要問題是關於差距,有一些共同的(必須這樣做)解決方案?我曾經問過關於商標的問題,如果有人遇到同樣的問題,我很肯定我在底紋選項中做了一些錯誤。 – user7803907

回答

2

1)的主要問題是:大塊

可以拼接地形在一起之間的差距,以確保他們得到同樣的LOD與SetNeighbors(Terrain left, Terrain top, Terrain right, Terrain bottom);

documentation:

讓你安裝相鄰地形之間的連接。

這可確保LOD在相鄰的地形上相匹配。請注意,這是 不足以在一個地形上調用此函數,您需要設置每個地形的 鄰居。

2)第二:在地面上

這個問題應該來自你正在使用您的地形對象的紋理紅印。

+0

你有什麼想法,紋理可以是什麼樣的問題? (對我來說,它看起來真的很像來自材質的「金屬」效果。) – user7803907

2

的間隙發生,因爲你要創建不同的地形對象。使用地形的主要觀點是要有一個程序化的網格,您可以根據自己的需要進行優化。

發動機通過降低它們的LOD來優化地形,使得它們距離它們越遠。這意味着兩個相鄰的塊可能會得到兩個不同的LOD,實際上意味着其中一個具有另一個的頂點分辨率的一半,這導致了間隙。如果你密切關注,你會注意到它們似乎是與其他頂點發生的。它也似乎消失了,因爲你沒有得到任何LODs。

引擎解決這個問題的方法是將額外的頂點拼接到地形的較低分辨率部分。然而,它不能在你的情況下做到這一點,因爲有單獨的地形對象,他們不知道對方的存在。你可能想要解決的問題是將所有較小的地形對象合併成一個大的地形。

+1

原來的項目(從指南)有這方面的東西。在指南項目塊中包含(據我記得)4個最接近的塊(上,下,左,右)的引用。今晚我會試着再看一下,但是我認爲我的問題得到了回答。順便說一句,你有什麼想法如何解決這些紅色標記(他們真的很討厭)? – user7803907