void GenHeightMap() { for (int x = 0; x < 16; x++) { for (int y = 0; y < 16; y++) { for (int z = 0; z < 16; z++) { heightMap[x, y, z] = noise.Noise(x, y, z); } } } }
private void ReplaceBiomeBlocks(GeneratorSettings settings, int x, int z, ChunkColumnStorage chunk, Biome[,] biomesIn) { _surfaceNoise.Noise( _surfaceMap, new Vector3(x * 16 + 0.1F, 0, z * 16 + 0.1F), new Vector3(0.0625F, 1.0F, 0.0625F)); for (int x1 = 0; x1 < 16; ++x1) { for (int z1 = 0; z1 < 16; ++z1) { Biome biome = biomesIn[z1, x1]; biome.GenerateBiomeTerrain(settings.SeaLevel, _random, chunk, x, z, x1, z1, (_surfaceMap[x1, 0, z1] - 0.5) * 2); } } }
public void TestOctavedPerlinNoise3D() { const int xExtent = 100; const int yExtent = 100; using (var file = File.OpenWrite(Path.Combine(RootDir, "OctavedPerlinNoise3D.bmp"))) using (var image = new Image <ImageSharp.PixelFormats.Rgb24>(xExtent, yExtent)) { var noise = new OctavedNoise <PerlinNoise>(new PerlinNoise(100), 8, 0.25f); var noiseValue = new float[xExtent, yExtent, 1]; noise.Noise(noiseValue, new Vector3(-10, 10, -10), new Vector3(0.1f, 0.1f, 0)); for (int x = 0; x < xExtent; x++) { for (int y = 0; y < yExtent; y++) { var color = (byte)(noiseValue[x, y, 0] * 255); image[x, y] = new ImageSharp.PixelFormats.Rgb24(color, color, color); } } image.SaveAsBmp(file); } }
private void GenerateDensityMap(float[,,] densityMap, int xOffset, int yOffset, int zOffset, GeneratorSettings settings) { _depthNoise.Noise( _depthMap, new Vector3(xOffset + 0.1f, 0.0f, zOffset + 0.1f), new Vector3(settings.DepthNoiseScaleX, 1.0f, settings.DepthNoiseScaleZ)); float coordinateScale = settings.CoordinateScale; float heightScale = settings.HeightScale; // 生成3个5*5*33的噪声 _mainNoise.Noise( _mainNoiseMap, new Vector3(xOffset, yOffset, zOffset), new Vector3( coordinateScale / settings.MainNoiseScaleX, heightScale / settings.MainNoiseScaleY, coordinateScale / settings.MainNoiseScaleZ)); _minNoise.Noise( _minLimitMap, new Vector3(xOffset, yOffset, zOffset), new Vector3( coordinateScale, heightScale, coordinateScale)); _maxNoise.Noise( _maxLimitMap, new Vector3(xOffset, yOffset, zOffset), new Vector3( coordinateScale, heightScale, coordinateScale)); // chunk遍历 for (int x1 = 0; x1 < 5; ++x1) { for (int z1 = 0; z1 < 5; ++z1) { float scale = 0.0F; float groundYOffset = 0.0F; float totalWeight = 0.0F; // 中心点生物群系 Biome centerBiome = _biomesForGeneration[z1 + 2, x1 + 2]; // 求scale和groundYOffset的加权平均值 for (int x2 = 0; x2 < 5; ++x2) { for (int z2 = 0; z2 < 5; ++z2) { Biome biome = _biomesForGeneration[z1 + z2, x1 + x2]; float curGroundYOffset = settings.BiomeDepthOffSet + biome.GetBaseHeight() * settings.BiomeDepthWeight; // biomeDepthOffSet=0 float curScale = settings.BiomeScaleOffset + biome.GetHeightVariation() * settings.BiomeScaleWeight; // biomeScaleOffset=0 // parabolicField为 10 / √(该点到中心点的距离^2 + 0.2) float weight = _biomeWeights[z2, x2] / (curGroundYOffset + 2.0F); if (biome.GetBaseHeight() > centerBiome.GetBaseHeight()) { weight /= 2.0F; } scale += curScale * weight; groundYOffset += curGroundYOffset * weight; totalWeight += weight; } } scale = scale / totalWeight; groundYOffset = groundYOffset / totalWeight; scale = scale * 0.9F + 0.1F; groundYOffset = (groundYOffset * 4.0F - 1.0F) / 8.0F; // 取一个-0.36~0.125的随机数,这个随机数决定了起伏的地表 float random = (_depthMap[x1, 0, z1] - 0.5F) * 2 / 8000.0F; if (random < 0.0F) { random = -random * 0.3F; } random = random * 3.0F - 2.0F; if (random < 0.0) { random = random / 2.0F; if (random < -1.0) { random = -1.0F; } random = random / 1.4F; random = random / 2.0F; } else { if (random > 1.0F) { random = 1.0F; } random = random / 8.0F; } float groundYOffset1 = groundYOffset; float scale1 = scale; // groundYOffset有-0.072~0.025的变动量 groundYOffset1 = groundYOffset1 + random * 0.2F; groundYOffset1 = groundYOffset1 * settings.BaseSize / 8.0F; // 这个是大概的地面y坐标 float groundY = settings.BaseSize + groundYOffset1 * 4.0F; // baseSize=8.5,应该代表了平均地表高度68 // 注意这个y*8才是最终的y坐标 for (int y = 0; y < 33; ++y) { // result偏移量,这个是负数则趋向固体,是正数则趋向液体和空气 float offset = (y - groundY) * settings.StretchY * 128.0F / 256.0F / scale1; // scale大概在0.1~0.2这样... if (offset < 0.0F) { offset *= 4.0F; } // 并不保证lowerLimit < upperLimit,不过没有影响 float lowerLimit = (_minLimitMap[x1, y, z1] - 0.5F) * 160000 / settings.LowerLimitScale; // lowerLimitScale=512 float upperLimit = (_maxLimitMap[x1, y, z1] - 0.5F) * 160000 / settings.UpperLimitScale; // upperLimitScale=512 float t = ((_mainNoiseMap[x1, y, z1] - 0.5F) * 160000 / 10.0F + 1.0F) / 2.0F; // 这个函数t < 0则取lowerLimit,t > 1则取upperLimit,否则以t为参数在上下限间线性插值 float result = MathHelper.DenormalizeClamp(lowerLimit, upperLimit, t) - offset; // y = 30~32 if (y > 29) { // 在原result和-10之间线性插值,这样y > 240的方块就会越来越少,最后全变成空气 float t2 = (float)(y - 29) / 3.0F; result = result * (1.0F - t2) + -10.0F * t2; } _densityMap[x1, y, z1] = (float)result; } } } densityMap = _densityMap; }