2017-04-04 1 views
5

프로 시저 생성을 위해 노력하고 있는데, 분명히 프로가 아니지만이 가이드를 따라갔습니다 : click 그리고 몇 가지 결과가 있습니다. 현재로서는 2 가지 문제가 있습니다. 문제를 해결하는 기본적인 아이디어가 있지만 다른 의견을 듣고 싶습니다.유니티 3D의 절차 지형 프로그래밍

(단 하나의 답변에 이미이 질문을 게시했지만 일부 정보가 없거나 몇 마디로 설명하기가 불가능한 경우 전혀 응답이 없습니다.

enter image description here

내가 확대한다면 그들이 좀 사라는 그러나 텍스처가 부적당 남아 그것은 놀라운 : 덩어리 사이의 간격을 :

주요 문제는)이 정보를 찾을 수 있습니다.

두 번째로 볼 수 있듯이 빨간색으로 문제가 있습니다 (실제로 전화하는 법을 모르겠 음). 가이드의 자료를 사용하려고했지만 동일한 효과가 있습니다.

게다가 Perlin Noise (나는 다이아몬드 스퀘어 또는 심플 렉스를 사용할 수 있음)는 의사 무작위 알고리즘이므로 동일한 입력 매개 변수에 대해 동일한 값을 반환하므로 내 청크가 항상 같은?

내 코드 (나는 가이드에서 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. 펄린 노이즈 값). 일반적으로 스택 오버플로에 대한 질문에서 단 한 가지만 묻는 것이 좋습니다. 그러나 질문이 매우 밀접하게 관련된 경우 예외가 발생할 수 있습니다. 또한 물음표로 끝내면 문제가되는 것이 무엇인지 명확하게 알 수 있습니다. – PJvG

+1

Perlin 노이즈에 대해서는 [Seed] 속성이있는 [GitHub의 LibNoise 라이브러리] (https://github.com/ricardojmendez/LibNoise.Unity/blob/master/Generator/Perlin.cs)에서 확인할 수 있습니다. . 다른 결과를 원하면'Perlin' 객체에 대해 다른 시드를 사용해야합니다. 만약 당신이 여전히 혼란 스럽다면 의사 랜덤 생성기와 씨드에 대해 좀 더 연구를 해보십시오. – PJvG

+1

@PjvG 나는 게시물 당 약 1 질문 (포럼에 대한 공통 규칙)을 알고 있지만, 나는 그것들을 분리해야한다고 생각하지 않는다. 그래서, 내 자신을 명확히하려고 할 것입니다, 주요 질문은 간격에 관한 것입니다, 몇 가지 일반적인 (이 방법을해야합니다) 솔루션이 무엇입니까? 누군가가 똑같은 문제를 안고있는 경우를 대비해 마크에 대해 물었습니다. 나는 음영 옵션에서 뭔가 잘못했다고 확신했습니다. – user7803907

답변

2

1) : 당신은 함께 지형을 꿰매 수

덩어리 사이의 간격이 그들이 documentation:

에서 SetNeighbors(Terrain left, Terrain top, Terrain right, Terrain bottom);

와 같은 LOD를 얻을 수 있도록하는 것은 당신에게 설치를 수 있습니다 인접한 지형 간의 연결

이렇게하면 인접한 지형에서 LOD가 일치합니다. 하나의 지형에서이 함수를 호출하기에 충분하지 않은 것은 입니다. 각 지형의 이웃을 개 설정해야합니다.

2) 두 번째 :

이 문제는 당신이 당신의 지형 객체에서 사용하는 텍스처에서 와야 지상에 빨간색 마크.

+0

아이디어가 있습니까? 텍스처에 어떤 종류의 문제가있을 수 있습니까? (나를 위해 그것은 물질의 "금속"효과처럼 보입니다.) – user7803907

2

. 지형을 사용하는 주된 요점은 적절하게 최적화 할 수있는 절차 적 메쉬 조각을 갖는 것입니다.

엔진은 지형을 멀리 떨어 뜨려 지형을 최적화합니다. 즉, 인접한 두 개의 청크가 서로 다른 두 개의 LOD를 가져올 수 있습니다. 즉, 두 개의 LOD가 서로의 꼭지점 해상도의 절반을 차지한다는 것을 의미합니다. 세심한주의를 기울이면 다른 모든 정점에서 어떻게 발생하는지 알 수 있습니다. LOD가 닫히지 않아 가까이에서 사라지는 것 같습니다.

엔진이 해결하는 방법은 여분의 정점을 지형의 더 낮은 해상도 부분에 스티칭하는 것입니다. 그러나 별도의 지형 개체가 있고 서로의 존재를 인식하지 못하기 때문에이 작업을 수행 할 수 없습니다. 문제를 해결하기 위해 할 일은 작은 지형 오브젝트를 모두 하나의 큰 지형으로 병합하는 것입니다. 주요 문제는

+1

원래 프로젝트 (가이드의)가 이에 대해 뭔가를 가지고있었습니다. 가이드 프로젝트 청크에는 4 개의 가장 가까운 청크 (위쪽, 아래쪽, 왼쪽 및 오른쪽)에 대한 참조가 포함되어 있습니다 (기억하는 한). 나는 오늘 저녁에 조금 더 자세히 보려고 노력할 것입니다. 그러나 제 질문에 대한 답이 있다고 생각합니다. Btw, 그 빨간 흔적을 고치는 방법에 대해 아이디어가 있습니까? (그들은 정말로 성가시다)? – user7803907