所以我正在創造一個無盡的地形。
我可以創建地形,但我的塊之間有間隙并且它們沒有正確對齊。
我認為問題可能是由我的噪聲生成腳本引起的,但我不確定。
這是我的噪音生成腳本
public static class Noise_GENERATOR
{
public static float[,] GenerateNoise(int chunkSize, int octaves, int seed, float noiseScale, float persistence, float lacunarity, Vector2 offset)
{
float[,] noiseMap = new float[chunkSize, chunkSize];
System.Random prng = new System.Random(seed);
Vector2[] octaveOffsets = new Vector2[octaves];
float maxPossibleHeight = 0;
float amplitude = 1;
float frequency = 1;
for (int i = 0; i < octaves; i )
{
float offsetX = prng.Next(-100000, 100000) offset.x;
float offsetY = prng.Next(-100000, 100000) offset.y;
octaveOffsets[i] = new Vector2(offsetX, offsetY);
maxPossibleHeight = amplitude;
amplitude *= persistence;
}
if (noiseScale <= 0)
{
noiseScale = 0.0001f;
}
float maxLocalNoiseHeight = float.MinValue;
float minLocalNoiseHeight = float.MaxValue;
float halfWidth = chunkSize / 2f;
float halfHeight = chunkSize / 2f;
for (int y = 0; y < chunkSize; y )
{
for (int x = 0; x < chunkSize; x )
{
amplitude = 1;
frequency = 1;
float noiseHeight = 0;
for (int i = 0; i < octaves; i )
{
float sampleX = (x-halfWidth octaveOffsets[i].x) / noiseScale * frequency;
float sampleY = (y-halfHeight octaveOffsets[i].y) / noiseScale * frequency;
float perlinValue = Mathf.PerlinNoise(sampleX, sampleY) * 2 - 1;
noiseHeight = perlinValue * amplitude;
amplitude *= persistence;
frequency *= lacunarity;
}
if (noiseHeight > maxLocalNoiseHeight)
{
maxLocalNoiseHeight = noiseHeight;
}
else if (noiseHeight < minLocalNoiseHeight)
{
minLocalNoiseHeight = noiseHeight;
}
noiseMap[x, y] = noiseHeight;
float normalizedHeight = (noiseMap[x, y] 1) / (maxPossibleHeight / 0.9f);
noiseMap[x, y] = Mathf.Clamp(normalizedHeight, 0, int.MaxValue);
}
}
return noiseMap;
}
}
為了生成網格的高度,我使用影片曲線并將其乘以elevationScale 變數。
float height = heightCurve.Evaluate(noiseMap[x, y]) * elevationScale;

我想過訪問每個地形塊并獲取邊緣的高度并將它們匹配在一起,但這看起來真的很奇怪,我不知道如何正確地做到這一點。
編輯:這里以防萬一我的網格生成器腳本以及我如何創建地形塊
public static class Mesh_GENERATOR
{
public static MeshData GenerateChunkMesh(int chunkSize,float[,] noiseMapData,float elevationScale,AnimationCurve terrainCurve,int LODlevel )
{
float[,] noiseMap = noiseMapData;
AnimationCurve heightCurve = new AnimationCurve(terrainCurve.keys);
//Setup variables
Vector3[] vertices = new Vector3[chunkSize * chunkSize];
int[] triangles = new int[(chunkSize - 1) * (chunkSize - 1) * 6];
Vector2[] uvs = new Vector2[chunkSize * chunkSize];
int triangle = 0;
int levelOfDetailIncrement = (LODlevel == 0) ? 1 : LODlevel * 2;
int numberOfVerticesPerRow = (chunkSize) / levelOfDetailIncrement 1;
for (int y = 0; y < chunkSize; y )
{
for (int x = 0; x < chunkSize; x )
{
int i = y * chunkSize x;
//Create vertices at position and center mesh
float height = heightCurve.Evaluate(noiseMap[x, y]) * elevationScale;
Vector2 percentPosition = new Vector2(x / (chunkSize - 1f), y / (chunkSize -1f ));
Vector3 vertPosition = new Vector3(percentPosition.x * 2 - 1, 0, percentPosition.y * 2 - 1) * chunkSize/2;
vertPosition.y = height;
vertices[i] = vertPosition;
uvs[i] = new Vector2((float)x / chunkSize, (float)y / chunkSize);
//Construct triangles
if (x != chunkSize - 1 && y != chunkSize - 1)
{
triangles[triangle 0] = i chunkSize;
triangles[triangle 1] = i chunkSize 1;
triangles[triangle 2] = i;
triangles[triangle 3] = i chunkSize 1;
triangles[triangle 4] = i 1;
triangles[triangle 5] = i;
triangle = 6;
}
}
}
MeshData meshData = new MeshData(chunkSize, vertices, triangles, uvs);
return meshData;
}
}
public class MeshData
{
public int chunkSize;
public Vector3[] vertices;
public int[] triangles;
public Vector2[] uvs;
public Mesh mesh;
public MeshData(int chunkSize,Vector3[] vertices,int[] triangles, Vector2[] uvs)
{
this.chunkSize = chunkSize;
this.vertices = vertices;
this.triangles = triangles;
this.uvs = uvs;
}
public Mesh CreateMesh()
{
if(mesh == null) { mesh = new Mesh(); } else { mesh.Clear(); }
mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
mesh.vertices = vertices;
mesh.triangles = triangles;
mesh.uv = uvs;
mesh.RecalculateNormals();
return mesh;
}
}
這是我的 TerrainChunk
public class TerrainChunk
{
GameObject meshObject;
Vector2 position;
Bounds bounds;
MeshRenderer meshRenderer;
MeshFilter meshFilter;
public TerrainChunk(Vector2 coord, int chunkSize, Transform parent,Material terrainMaterial)
{
position = coord * chunkSize;
bounds = new Bounds(position, Vector2.one * chunkSize);
Vector3 positionV3 = new Vector3(position.x , 0, position.y );
Debug.Log("CHUNK: COORD" coord "POSITION" position "POSITION3V" positionV3);
meshObject = new GameObject("Terrain Chunk");
meshFilter = meshObject.AddComponent<MeshFilter>();
meshRenderer = meshObject.AddComponent<MeshRenderer>();
meshRenderer.material = terrainMaterial;
meshObject.transform.position = positionV3;
meshObject.transform.parent = parent;
SetVisible(false);
worldGenerator.RequestMapData(position,OnNoiseDataReceived);
}
void OnNoiseDataReceived(MapData mapData)
{
worldGenerator.RequestMeshData(mapData, OnMeshDataReceived);
}
void OnMeshDataReceived(MeshData meshData)
{
meshFilter.mesh = meshData.CreateMesh();
}
public void UpdateTerrainChunk(Vector2 viewerPosition, int maxRenderDistance)
{
float viewerDstFromNearestEdge = Mathf.Sqrt(bounds.SqrDistance(viewerPosition));
bool visible = viewerDstFromNearestEdge <= maxRenderDistance;
SetVisible(visible);
}
public void SetVisible(bool visible)
{
meshObject.SetActive(visible);
}
public bool IsVisible()
{
return meshObject.activeSelf;
}
}
}
uj5u.com熱心網友回復:
如果我正確理解您的所有值和變數。
問題可能出在噪聲發生器上。
您需要將 chunkSize 創建為大 1,因此如果您要傳遞 250,則需要傳遞 251,因為噪聲生成器中的 for 回圈在 249 而不是 250 處停止。(我可能錯了),如果您這樣做網格生成器現在將具有正確的計算值。
所以你的 chunksize 變數應該是這樣的
chunkSize = chunkSize 1;
現在仍然會有更小的間隙,并且網格會相互夾住,所以要解決這個問題,你需要定位塊,然后這樣做 ->
(如果您的坐標用作從 World 生成器物件創建塊的方向 -> 例如,指向北的塊的值將是 x:0 y:1,指向西的塊將是 x:-1 y:0 , NorthWest 塊 x:-1 y:-1 等等),您可能需要將 0.5f 更改為您的值,以便塊正確對齊。
Vector3 positionV3 = new Vector3(position.x (coord.x 0.5f), 0, position.y (coord.y 0.5f) );
地形中仍然可能有一些較小的間隙可見,但這可以通過使用這些值來解決,或者您可以嘗試訪問每個塊并獲取邊緣頂點及其高度,然后以這種方式將塊連接在一起。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/392533.html
