public HeightmapGenerator(int size) { this.size = size; seed = 0; octaves = 2; frequency = 0.01f; lacunarity = 2.0f; quality = NoiseQuality.Standard; primitive = new ImprovedPerlin(); primitive.Quality = quality; primitive.Seed = seed; filter = new RidgedMultiFractal(); filter.Frequency = frequency; filter.Lacunarity = lacunarity; filter.OctaveCount = octaves; filter.Primitive3D = (IModule3D)primitive; scale = new ScaleBias(filter, 1f, 0); }
double[,,] GenerateDensityMap(Chunk chunk) { var primitive = new SimplexPerlin { Quality = NoiseQuality.Best, Seed = 1 }; var terrainFilter = new RidgedMultiFractal { Primitive3D = primitive, Frequency = 1, Gain = 3f, Lacunarity = 2, OctaveCount = 4, Offset = 1, SpectralExponent = 0.25f }; // MultiFractal output seems to vary from 0 to 3ish var outputScaler = new ScaleBias { SourceModule = terrainFilter, Scale = 2 / 3f, Bias = -1f }; // The terrace seems to be useful for smoothing the lower parts while still allowing // for dramatic mountains var terrace = new Terrace() { SourceModule = outputScaler, }; terrace.AddControlPoint(-1f); //terrace.AddControlPoint(-0.5f); //terrace.AddControlPoint(0f); //terrace.AddControlPoint(0.5f); terrace.AddControlPoint(2f); //terrace.AddControlPoint(0.7f, 0.8f); var inputScaler = new ScalePoint { SourceModule = terrace, XScale = 0.01f, YScale = 0.01f, ZScale = 0.01f }; var densityMap = new double[Chunk.XDimension + 1,Chunk.YDimension + 1,Chunk.ZDimension + 1]; for (int x = 0; x <= Chunk.XDimension; x += horizontalSampleRate) { for (int y = 0; y <= Chunk.YDimension; y += verticalSampleRate) { for (int z = 0; z <= Chunk.ZDimension; z += horizontalSampleRate) { float worldX = chunk.OriginInWorld.X + x; float worldY = chunk.OriginInWorld.Y + y; float worldZ = chunk.OriginInWorld.Z + z; var noise = inputScaler.GetValue(worldX, worldY, worldZ); // This applies a gradient to the noise based on height. // The smaller the gradient value, the longer it takes to drive // the entire fractal below zero and the more overhang/hole stuff // we get. var density = noise - (y * y * y / 600000f) + 2; //var density = noise - (y / 10f) + 3; densityMap[x, y, z] = density; } } } TriLerp(densityMap); return densityMap; }
/// <summary> /// /// </summary> protected void GenerateNoise() { EnabledInterface(false); // Parse input ------------------------------------------------------------------------------------ int seed = ParseInt(_tbxSeed.Text, PrimitiveModule.DEFAULT_SEED); float frequency = ParseFloat(_tbxFrequency.Text, FilterModule.DEFAULT_FREQUENCY); float lacunarity = ParseFloat(_tbxLacunarity.Text, FilterModule.DEFAULT_LACUNARITY); float gain = ParseFloat(_tbxGain.Text, FilterModule.DEFAULT_GAIN); float offset = ParseFloat(_tbxOffset.Text, FilterModule.DEFAULT_OFFSET); float exponent = ParseFloat(_tbxExponent.Text, FilterModule.DEFAULT_SPECTRAL_EXPONENT); var octaveCount = (int) _nstpOctave.Value; bool seamless = _chkbx.Checked; GradientColor gradient = GradientColor.GRAYSCALE; NoiseQuality quality = PrimitiveModule.DEFAULT_QUALITY; var primitive = NoisePrimitive.ImprovedPerlin; var filter = NoiseFilter.SumFractal; try { quality = (NoiseQuality) Enum.Parse(typeof (NoiseQuality), _cbxQuality.Text); } catch { MessageBox.Show( String.Format("Unknown quality '{0}'", _cbxQuality.Text), "Libnoise Error", MessageBoxButtons.OK, MessageBoxIcon.Error ); EnabledInterface(true); return; } try { primitive = (NoisePrimitive) Enum.Parse(typeof (NoisePrimitive), _cbxPrimitive.Text); } catch { MessageBox.Show( String.Format("Unknown primitive '{0}'", _cbxPrimitive.Text), "Libnoise Error", MessageBoxButtons.OK, MessageBoxIcon.Error ); EnabledInterface(true); return; } try { filter = (NoiseFilter) Enum.Parse(typeof (NoiseFilter), _cbxFilter.Text); } catch { MessageBox.Show( String.Format("Unknown filter '{0}'", _cbxFilter.Text), "Libnoise Error", MessageBoxButtons.OK, MessageBoxIcon.Error ); EnabledInterface(true); return; } switch (_cbxGradient.Text) { case "Grayscale": gradient = GradientColor.GRAYSCALE; break; case "Terrain": gradient = GradientColor.TERRAIN; break; } // Create module tree ------------------------------------------------------------------------------------ PrimitiveModule pModule = null; switch (primitive) { case NoisePrimitive.Constant: pModule = new Constant(offset); break; case NoisePrimitive.Cylinders: pModule = new Cylinders(offset); seamless = false; break; case NoisePrimitive.Spheres: pModule = new Spheres(offset); seamless = false; break; case NoisePrimitive.BevinsGradient: pModule = new BevinsGradient(); break; case NoisePrimitive.BevinsValue: pModule = new BevinsValue(); break; case NoisePrimitive.ImprovedPerlin: pModule = new ImprovedPerlin(); break; case NoisePrimitive.SimplexPerlin: pModule = new SimplexPerlin(); break; } pModule.Quality = quality; pModule.Seed = seed; FilterModule fModule = null; ScaleBias scale = null; switch (filter) { case NoiseFilter.Pipe: fModule = new Pipe(); break; case NoiseFilter.SumFractal: fModule = new SumFractal(); break; case NoiseFilter.SinFractal: fModule = new SinFractal(); break; case NoiseFilter.MultiFractal: fModule = new MultiFractal(); // Used to show the difference with our gradient color (-1 + 1) scale = new ScaleBias(fModule, 1f, -0.8f); break; case NoiseFilter.Billow: fModule = new Billow(); ((Billow) fModule).Bias = -0.2f; ((Billow) fModule).Scale = 2f; break; case NoiseFilter.HeterogeneousMultiFractal: fModule = new HeterogeneousMultiFractal(); // Used to show the difference with our gradient color (-1 + 1) scale = new ScaleBias(fModule, -1f, 2f); break; case NoiseFilter.HybridMultiFractal: fModule = new HybridMultiFractal(); // Used to show the difference with our gradient color (-1 + 1) scale = new ScaleBias(fModule, 0.7f, -2f); break; case NoiseFilter.RidgedMultiFractal: fModule = new RidgedMultiFractal(); // Used to show the difference with our gradient color (-1 + 1) scale = new ScaleBias(fModule, 0.9f, -1.25f); break; case NoiseFilter.Voronoi: fModule = new Voronoi(); break; } fModule.Frequency = frequency; fModule.Lacunarity = lacunarity; fModule.OctaveCount = octaveCount; fModule.Offset = offset; fModule.Offset = offset; fModule.Gain = gain; fModule.Primitive3D = (IModule3D) pModule; IModule3D finalModule; if (scale == null) finalModule = (IModule3D) fModule; else finalModule = scale; NoiseMapBuilder projection; switch (_cbxProjection.Text) { case "Spherical": projection = new NoiseMapBuilderSphere(); ((NoiseMapBuilderSphere) projection).SetBounds(-90f, 90f, -180f, 180f); // degrees break; case "Cylindrical": projection = new NoiseMapBuilderCylinder(); ((NoiseMapBuilderCylinder) projection).SetBounds(-180f, 180f, -10f, 10f); break; case "Planar": default: float bound = 2f; projection = new NoiseMapBuilderPlane(bound, bound*2, bound, bound*2, seamless); //projection = new NoiseMapBuilderPlane(-bound, bound, -bound, bound, seamless); //projection = new NoiseMapBuilderPlane(0, bound, 0, bound, seamless); break; } int width = 0; int height = 0; switch (_cbxSize.Text) { case "256 x 256": width = 256; height = 256; break; case "512 x 512": width = 512; height = 512; break; case "1024 x 1024": width = 1024; height = 1024; break; case "256 x 128": width = 256; height = 128; break; case "512 x 256": width = 512; height = 256; break; case "1024 x 512": width = 1024; height = 512; break; case "2048 x 1024": width = 2048; height = 1024; break; default: case "128 x 128": width = 128; height = 128; break; } // ------------------------------------------------------------------------------------------------ // 0 - Initializing _prbarRenderProgression.Visible = true; _lblProgressPercent.Visible = true; _prbarRenderProgression.Value = 0; ; _lblProgressPercent.Text = ""; _lblLog.Text = String.Format("Create a {0} image with a {1} projection\n", _cbxSize.Text, _cbxProjection.Text); var watchDog = new Stopwatch(); TimeSpan ts; double elaspedTime = 0; // // ------------------------------------------------------------------------------------------------ // 1 - Build the noise map watchDog.Reset(); _prbarRenderProgression.Value = 0; _lblLog.Text += "Building noise map ... "; var noiseMap = new NoiseMap(); /* // ShapeFilter test Bitmap bmpShape = new Bitmap("smileyShape.bmp"); BitmapAdaptater bmShapeAdaptater = new BitmapAdaptater(bmpShape); ShapeFilter shapeFilter = new ShapeFilter(); shapeFilter.Shape = bmShapeAdaptater; projection.Filter = shapeFilter; */ projection.SetSize(width, height); projection.SourceModule = finalModule; projection.NoiseMap = noiseMap; projection.CallBack = delegate(int line) { line++; watchDog.Stop(); //Process message Application.DoEvents(); _prbarRenderProgression.Value = (line*100/height); _lblProgressPercent.Text = String.Format("{0} % - {1} line(s)", _prbarRenderProgression.Value, line); watchDog.Start(); }; watchDog.Start(); projection.Build(); watchDog.Stop(); ts = watchDog.Elapsed; elaspedTime += ts.TotalMilliseconds; _lblLog.Text += String.Format("{0:00}:{1:00} {2:00},{3:0000}\n", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds*10 ); // ------------------------------------------------------------------------------------------------ // 2 - Render image // Create a renderer, BitmapAdaptater create a System.Drawing.Bitmap on the fly watchDog.Reset(); _prbarRenderProgression.Value = 0; _lblLog.Text += "Rendering image ... "; var renderer = new ImageRenderer(); renderer.NoiseMap = noiseMap; renderer.Gradient = gradient; renderer.LightBrightness = 2; renderer.LightContrast = 8; //renderer.LightEnabled = true; // Libnoise image struct strategy //Graphics.Tools.Noise.Renderer.Image image = new Graphics.Tools.Noise.Renderer.Image(); //renderer.Image = image; // Dotnet Bitmap Strategy var bmpAdaptater = new BitmapAdaptater(width, height); renderer.Image = bmpAdaptater; renderer.CallBack = delegate(int line) { line++; watchDog.Stop(); //Process message Application.DoEvents(); _prbarRenderProgression.Value = (line*100/height); _lblProgressPercent.Text = String.Format("{0} % - {1} line(s)", _prbarRenderProgression.Value, line); watchDog.Start(); }; // Render the texture. watchDog.Start(); renderer.Render(); watchDog.Stop(); ts = watchDog.Elapsed; elaspedTime += ts.TotalMilliseconds; _lblLog.Text += String.Format("{0:00}:{1:00} {2:00},{3:0000}\n", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds*10 ); //---------------------------------------- // Normalmap rendering test // /* BitmapAdaptater nmapAdaptater = new BitmapAdaptater(width, height); NormalMapRenderer nmap = new NormalMapRenderer(); nmap.Image = nmapAdaptater; nmap.BumpHeight = 30.0f; nmap.NoiseMap = noiseMap; nmap.Render(); nmapAdaptater.Bitmap.Save("normalMap.png", ImageFormat.Png); */ //---------------------------------------- /* Heightmap8 heightmap8 = new Heightmap8(); Heightmap8Renderer heightmapRenderer = new Heightmap8Renderer(); heightmapRenderer.Heightmap = heightmap8; */ /* Heightmap16 heightmap16 = new Heightmap16(); Heightmap16Renderer heightmapRenderer = new Heightmap16Renderer(); heightmapRenderer.Heightmap = heightmap16; */ /* Heightmap32 heightmap32 = new Heightmap32(); Heightmap32Renderer heightmapRenderer = new Heightmap32Renderer(); heightmapRenderer.Heightmap = heightmap32; */ /* heightmapRenderer.NoiseMap = noiseMap; heightmapRenderer.ExactFit(); heightmapRenderer.Render(); */ /* Heightmap16RawWriter rawWriter = new Heightmap16RawWriter(); rawWriter.Heightmap = heightmap16; rawWriter.Filename = "heightmap16.raw"; rawWriter.WriteFile(); */ // ------------------------------------------------------------------------------------------------ // 3 - Painting // Save the file //bmpAdaptater.Bitmap.Save("rendered.png",ImageFormat.Png); _imageRendered.Width = width; _imageRendered.Height = height; //_imageRendered.Image = _bitmap; _imageRendered.Image = bmpAdaptater.Bitmap; if (_imageRendered.Width > _panImageViewport.Width) _imageRendered.Left = 0; else _imageRendered.Left = (_panImageViewport.Width - _imageRendered.Width)/2; if (_imageRendered.Height > _panImageViewport.Height) _imageRendered.Top = 0; else _imageRendered.Top = (_panImageViewport.Height - _imageRendered.Height)/2; if (_imageRendered.Width > _panImageViewport.Width || _imageRendered.Height > _panImageViewport.Height) { _imageRendered.Anchor = (AnchorStyles.Left | AnchorStyles.Top); _panImageViewport.AutoScroll = true; } else _panImageViewport.AutoScroll = false; // ---------------------------------------------------------------- ts = TimeSpan.FromMilliseconds(elaspedTime); // Format and display the TimeSpan value. _lblLog.Text += String.Format("Duration : {0:00}:{1:00} {2:00},{3:0000}\n", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds*10 ); EnabledInterface(true); _prbarRenderProgression.Value = 0; _lblProgressPercent.Text = ""; _prbarRenderProgression.Visible = false; _lblProgressPercent.Visible = false; }