Noise module that outputs 3-dimensional MultiFractal noise. The multifractal algorithm differs from the Fractal brownian motion in that perturbations are combined multiplicatively and introduces an offset parameter. The perturbation at each frequency is computed as in the fBM algorithm, but offset is finally added to the value. The role of offset is to emphasize the final perturbation value. Multiplicative combination of perturbation, in turn, emphasizes the "mountain-like-aspect" of the landscape, so that between mountains a sort of slopes are generated (From http://meshlab.sourceforge.net/wiki/index.php/Fractal_Creation )
Inheritance: FilterModule, IModule3D, IModule2D
Exemplo n.º 1
0
        public NoiseProvider(WorldGeneratorPreset generatorPreset, int seed)
        {
            GeneratorPreset = generatorPreset;

            Seed       = seed;
            FastRandom = new FastRandom(seed);


            var mainLimitNoise = new SimplexPerlin(seed + FastRandom.Next(), NoiseQuality.Fast);

            var mainLimitFractal = new LibNoise.Filter.MultiFractal()
            {
                Primitive3D      = mainLimitNoise,
                Primitive2D      = mainLimitNoise,
                Frequency        = MainNoiseFrequency,
                OctaveCount      = 4,
                Lacunarity       = MainNoiseLacunarity,
                Gain             = MainNoiseGain,
                SpectralExponent = MainNoiseSpectralExponent
            };

            TerrainNoise = new ScaleableNoise()
            {
                XScale      = 1f / GeneratorPreset.CoordinateScale,
                YScale      = 1f / GeneratorPreset.HeightScale,
                ZScale      = 1f / GeneratorPreset.CoordinateScale,
                Primitive3D = mainLimitFractal,
                Primitive2D = mainLimitFractal
            }; //turbulence;


            var baseHeightNoise = new SimplexPerlin(seed + FastRandom.Next(), NoiseQuality.Fast);

            var fractal = new Voronoi()
            {
                Primitive2D = new ScaleableNoise()
                {
                    Primitive2D = baseHeightNoise,
                    XScale      = 1f / GeneratorPreset.CoordinateScale,
                    ZScale      = 1f / GeneratorPreset.CoordinateScale
                },
                OctaveCount      = 1,
                Frequency        = 1.295f,
                SpectralExponent = 0.25f
                                   //Distance = true
                                   //   Distance = false
            };

            BaseHeightNoise = new ScaleableNoise()
            {
                Primitive2D = fractal,
                XScale      = 1f / 8f,
                ZScale      = 1f / 8f
            };

            var depthNoise        = new SimplexPerlin(seed + FastRandom.Next(), NoiseQuality.Fast);
            var depthNoiseFractal = new RidgedMultiFractal()
            {
                Primitive2D      = depthNoise,
                Primitive3D      = depthNoise,
                Frequency        = DepthFrequency,
                Lacunarity       = DepthLacunarity,
                Gain             = DepthNoiseGain,
                OctaveCount      = 2,
                SpectralExponent = (float)GeneratorPreset.DepthNoiseScaleExponent
            };

            DepthNoise = new ScaleableNoise
            {
                Primitive2D = depthNoiseFractal,
                Primitive3D = depthNoiseFractal,
                XScale      = 1f / GeneratorPreset.MainNoiseScaleX,
                YScale      = 1f / GeneratorPreset.MainNoiseScaleY,
                ZScale      = 1f / GeneratorPreset.MainNoiseScaleZ
            };

            var rainSimplex = new SimplexPerlin(seed + FastRandom.Next(), NoiseQuality.Fast);
            var rainVoronoi = new WorldGenerator.Utils.Noise.Voronoi
            {
                Primitive3D = rainSimplex,
                Primitive2D = rainSimplex,
                Distance    = false,
                Frequency   = RainFallFrequency,
                OctaveCount = 2
            };

            var biomeScaling = (32.3345885f) * GeneratorPreset.BiomeSize;

            var rainNoise = new WorldGenerator.Utils.Noise.ScaleableNoise()
            {
                Primitive2D = rainVoronoi,
                Primitive3D = rainVoronoi,
                XScale      = 1f / biomeScaling,
                YScale      = 1f / biomeScaling,
                ZScale      = 1f / biomeScaling
            };

            // GeneratorPreset.bi

            IModule2D tempSimplex = new SimplexPerlin(seed + FastRandom.Next(), NoiseQuality.Fast);
            var       tempVoronoi = new WorldGenerator.Utils.Noise.Voronoi
            {
                Primitive2D      = tempSimplex,
                Distance         = false,
                Frequency        = TemperatureFrequency,
                OctaveCount      = 2,
                SpectralExponent = 0.25f
            };

            /*var tempNoise =  new ScaleableNoise()
             * {
             *  Primitive2D = tempVoronoi,
             *  Primitive3D = tempVoronoi,
             *  XScale = 1f / biomeScaling,
             *  YScale = 1f / biomeScaling,
             *  ZScale = 1f / biomeScaling
             * };
             */
            TempNoise = new ScaleableNoise()
            {
                Primitive2D = tempVoronoi,
                //   Primitive3D = tempSimplex,
                XScale = 1f / biomeScaling,
                YScale = 1f / biomeScaling,
                ZScale = 1f / biomeScaling
            };
            RainNoise = rainNoise;
        }
Exemplo n.º 2
0
        double[,,] GenerateDensityMap(Chunk chunk)
        {
            var primitive = new SimplexPerlin
            {
                Quality = NoiseQuality.Best,
                Seed = 1
            };

            var terrainFilter = new MultiFractal
            {
                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 / 60000f) + 2;
                        //var density = noise - (y / 10f) + 3;
                        densityMap[x, y, z] = density;
                    }
                }
            }

            TriLerp(densityMap);

            return densityMap;
        }
Exemplo n.º 3
0
        /// <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;
        }