2017-04-04 11 views
5

私は手続き型の世代に慣れようとしていますが、私は確かにプロではありませんが、このガイドに従っています:clickといくつかの結果があります。今は2つの問題がありますが、解決方法はいくつか基本的な考え方がありますが、私はいくつかの意見を聞きたいと思います。Unity 3Dの手続き型地形プログラミング

(私はすでにこの質問をUnityの回答に掲載していますが、何か不足している情報がある場合や何らかの言葉で説明することが不可能な場合は、私は何のアドバイスもしていません。

enter image description here

私はズームします場合、彼らはちょっと消えるが、しかし、テクスチャは適さないまま、それが顕著である:チャンクの間のギャップを:

主な問題はある)、この情報を見つけることができます。

2番目に、私は赤で問題が発生していることがわかります(私は本当にそれを呼び出す方法はわかりません)。私はガイドの資料を使用しようとしましたが、同じ効果があります。

さらに、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

あなたの質問はもっと明確になりますか?あなたのポストに3つの可能な質問があります(1.ギャップ、2.赤いマーク、3.パーリンノイズ値)。一般に、Stack Overflowに関する質問では1つだけ質問するようにしてください。ただし、質問が非常に密接に関連している場合は例外があります。また、疑問符で終了すると何かが疑問であることをより明確にすることができます。 – PJvG

+1

Perlinノイズについては、[GitHubのLibNoiseライブラリ](https://github.com/ricardojmendez/LibNoise.Unity/blob/master/Generator/Perlin.cs)に 'Seed'プロパティがあることがわかります。異なる結果が必要な場合は、 'Perlin'オブジェクトに別のシードを使うべきです。おそらく混乱している場合は、疑似乱数ジェネレータとシードについてさらに調査してください。 – PJvG

+1

@PjvG私は1ポスト(フォーラムの共通ルール)あたり約1つの質問を知っていますが、私はそれらを分けなければならないとは本当に思いません。だから、私は自分自身を明確にしようとします、主な問題はギャップについてです、いくつかの共通(この方法を行う必要があります)のソリューションがありますか?私は誰かが同じ問題を抱えていた場合に備えてマークについて尋ねました。私はちょうどシェーディングオプションに何か間違ったことをしていました。 – user7803907

答えて

2

1)主な問題は次のとおりです。チャンク

間のギャップは、あなたはdocumentation:

から、彼らはSetNeighbors(Terrain left, Terrain top, Terrain right, Terrain bottom);

と同じLODを得る確実にするために一緒に地形を縫うことができます設定します隣接する地形間の接続。

これにより、隣接する地形にLODが一致するようになります。 1つの地形でこの関数を呼び出すのに十分でないのは であることに注意してください。各地形の隣に を設定する必要があります。

2)第二:

この問題は、あなたの地形オブジェクトで使用しているテクスチャから来るべきで地面に赤いマーク。

+0

あなたは何か考えがありますか?テクスチャのどのような問題がありますか? (私にとって、それは実際には材料からの「メタリック」な効果のように見えます。) – user7803907

2

あなたは異なる地形オブジェクトを作成しているので、ギャップが起こります。地形を使用する主なポイントは、適切に見えるように最適化できるメッシュの手順的な部分を持つことです。

エンジンは、遠方からLODを減らして地形を最適化します。これは、2つの隣接チャンクが2つの異なるLODを得ることができることを意味します。つまり、ギャップの原因となる、もう一方の頂点解像度の半分を意味します。あなたが細心の注意を払うと、どのようにそれらが他のすべての頂点で起こるように見えるでしょう。 LODをクローズアップしていないため、クローズアップしていないようです。

エンジンがこれを解決する方法は、余分な頂点を地形の低解像度部分に縫い合わせることです。しかし、別の地形オブジェクトがあり、互いの存在を認識していないので、あなたの場合はこれを行うことはできません。問題を解決するためにおそらくしたいことは、すべての小さな地形オブジェクトを1つの大きな地形にマージすることです。

+1

オリジナルのプロジェクト(ガイドから)には何かがありました。ガイドプロジェクトのチャンクには、(私が覚えている限り)4つの最も近いチャンク(上、下、左、右)のリファレンスが含まれています。今晩もう少し見直そうとしますが、私の質問には答えがあると思います。 Btw、あなたはこれらの赤いマークを修正する方法を知っていますか(彼らは本当に迷惑です)? – user7803907

関連する問題