我想與程序生成相處,我絕對不是在統一的親,但我遵循本指南:click並得到了一些結果。現在我有兩個問題,我有一些基本的想法如何解決他們,但我想聽聽其他意見。在Unity 3D中的程序地形編程
(我已經發布了關於Unity答案的這個問題,但是我沒有得到任何答覆,如果有一些缺失的信息或者無法用幾句話來解釋,請讓我知道或給一些建議要找到這些信息)
的主要問題是:缺口塊之間:
他們還挺消失,如果我將縮小,但質地仍不適宜,這是顯着的。
第二,你可以看到我有一個紅色的問題(我真的不知道怎麼稱呼它)在地面上標記。我嘗試過從指南中使用材料,但效果相同。另外,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.差距,2.紅色標記和3.佩林噪聲值)。通常,您應該嘗試在Stack Overflow的問題中只提出一件事,但如果問題密切相關,則可能會出現異常。此外,如果以問號結尾,則可以更清楚地表明某件事是一個問題。 – PJvG
關於Perlin噪聲,你可以在[GitHub上的LibNoise庫](https://github.com/ricardojmendez/LibNoise.Unity/blob/master/Generator/Perlin.cs)中看到它有一個'Seed'屬性。如果你想得到不同的結果,你應該爲'Perlin'對象使用不同的種子。如果您仍然感到困惑,那麼可以對僞隨機生成器和種子做更多的研究。 – PJvG
@PjvG我知道每個帖子有1個問題(論壇上的常見規則),但我真的不認爲我應該將它們分開。所以,我會盡力澄清我的自我,主要問題是關於差距,有一些共同的(必須這樣做)解決方案?我曾經問過關於商標的問題,如果有人遇到同樣的問題,我很肯定我在底紋選項中做了一些錯誤。 – user7803907