Search Unity

  1. We've closed the job boards. If you're looking for work, or looking to hire check out Unity Connect. You can see more information here.
    Dismiss Notice
  2. Unity 2017.2 is now released.
    Dismiss Notice
  3. The Unity Gear Store is here to help you look great at your next meetup, user group or conference. With all new Unity apparel, stickers and more!
    Dismiss Notice
  4. If you're a macOS 10.13 High Sierra user take be sure to read this before updating Unity.
    Dismiss Notice
  5. Introducing the Unity Essentials Packs! Find out more.
    Dismiss Notice
  6. Want to see the most recent patch releases? Take a peek at the patch release page.
    Dismiss Notice
  7. Unity 2017.3 beta is now available for download.
    Dismiss Notice

CoherentNoise procedural generation library - RELEASED

Discussion in 'Assets and Asset Store' started by Nevermind, Jun 3, 2011.

  1. keenanwoodall

    keenanwoodall

    Joined:
    May 30, 2014
    Posts:
    489
  2. ExtremePowers

    ExtremePowers

    Joined:
    Sep 27, 2013
    Posts:
    28
    How does VoronoiCells work? I have tried this, but I can't get it to work:
    Code (CSharp):
    1. void Start() {
    2.     Debug.Log ("Ran at start");
    3.     map = new Texture2D (2048, 2048);
    4.  
    5.     VoronoiCells2D VC = new VoronoiCells2D (Seed, Func<int,int,int,float> /*This need to have some elements, but what elements?*/);
    6.  
    7.     for (int x = 0; x < map.width; x++) {
    8.         for (int y = 0; y < map.height; y++) {
    9.             VC.GetValue(x,y,0);
    10.         }
    11.     }
    12. }
     
    Last edited: Mar 9, 2015
  3. Nevermind

    Nevermind

    Joined:
    Jun 10, 2010
    Posts:
    66
    Your code is not doing anything because you're just creating a noise value, but not using it anywhere. You should actually call SetColor or whatever.
    Or is your problem in that you don't know what to put in the VoronoiCells2D constructor?
     
  4. ExtremePowers

    ExtremePowers

    Joined:
    Sep 27, 2013
    Posts:
    28
    It is okay now, I never figured it out, but I figured out how easy Voronoi is generated, so I created my own. It was that I didn't know what to put in the constructor.
     
  5. Breyer

    Breyer

    Joined:
    Nov 10, 2012
    Posts:
    412
    hi @Nevermind i would like to contribute to your work. I found tons of articles explanation different noises (e.g. accidental noise), image filters or - using ur wording - displacement

    I write because would like to avoid redoing wheel - i implemented fBm as first attempt to ur source code (fractional Brownian Motion, here is explanation: https://code.google.com/p/fractalterraingeneration/wiki/Fractional_Brownian_Motion) but i wondering if you already implemented this but under different name? (Pink, Ridge, Billow fractal?)

    this is how look:

    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. namespace CoherentNoise.Generation.Fractal
    6. {
    7. public class fBmNoise : FractalNoiseBase
    8. {
    9.  
    10.    public float Persistence
    11.    {
    12.      get;
    13.      set;
    14.    }
    15.  
    16.    public float Amplitude
    17.    {
    18.      get;
    19.      set;
    20.    }
    21.    public float StartFrequency;
    22.    private float m_CurAmplitude;
    23.    ///<summary>
    24.    /// Create new fBm noise generator using seed. Seed is used to create a <see cref="GradientNoise"/> source.
    25.    ///</summary>
    26.    ///<param name="seed">seed value</param>
    27.    public fBmNoise(int seed) : base(seed)
    28.    {
    29.      Persistence = 0.5f;
    30.      Amplitude=Persistence;
    31.    }
    32.    ///<summary>
    33.    /// Create new fBm noise generator with user-supplied source. Usually one would use this with <see cref="ValueNoise"/> or gradient noise with less dimensions, but
    34.    /// some weird effects may be achieved with other generators.
    35.    ///</summary>
    36.    ///<param name="source">noise source</param>
    37.    public fBmNoise(Generator source) : base(source)
    38.    {
    39.      Persistence = 0.5f;
    40.      Amplitude=Persistence;
    41.    }
    42.  
    43.    #region Overrides of FractalNoiseBase
    44.  
    45.    /// <summary>
    46.    /// Fractional Brownian Motion is the summation of successive octaves of noise, each with higher frequency and lower amplitude.
    47.    /// It doesn't especially matter what kind of noise, most will do.
    48.    /// </summary>
    49.    /// <param name="curOctave">Octave at which source is sampled (this always starts with 0)</param>
    50.    /// <param name="signal">Sampled value</param>
    51.    /// <param name="value">Resulting value from previous step</param>
    52.    /// <returns>Resulting value adjusted for this sample</returns>
    53.    protected override float CombineOctave(int curOctave, float signal, float value)
    54.    {
    55.      if (curOctave == 0)
    56.      {
    57.        m_CurAmplitude = Persistence;
    58.        Frequency=StartFrequency;
    59.      }
    60.      m_CurAmplitude*=Persistence;
    61.      Frequency*=Lacunarity;
    62.      return value+signal*m_CurAmplitude;
    63.    }
    64.  
    65.    #endregion
    66. }
    67.  
    68. }
    69.  
    however compared to previous link my implementation is a bit different due to your implementation of GetValue in FractalNoiseBase where you rotate input coord by 30 angle (as i understand) and im wondering if my implementation is still fBm or not technically^^

    Code (CSharp):
    1. // Prepare the next octave.
    2.                 // scale coords to increase frequency, then rotate to break up lattice pattern
    3.                 var rotated = s_Rotation*(new Vector3(x, y, z) * Lacunarity);
    4.                 x = rotated.x;
    5.                 y = rotated.y;
    6.                 z = rotated.z;
    this is the code i talked about in GetValue function

    PS:

    there is screenshot for fBm based on GradientNoise, 10 octaves, persistence (gain) 0.5, 100 seed, 256 tex resolution

    random_fBM.png

    effect will be different if you pass custom generator/noise (fBm works on most noises) ofc
     
    Last edited: Apr 11, 2015
  6. Nevermind

    Nevermind

    Joined:
    Jun 10, 2010
    Posts:
    66
    Yeah, PinkNoise is basically the same as fBm, as far as I understand it. The different noise names are a bit vague actually (-8
     
  7. Breyer

    Breyer

    Joined:
    Nov 10, 2012
    Posts:
    412
    http://www.scratchapixel.com/old/lessons/3d-advanced-lessons/noise-part-1/pattern-examples/
    According to this link fbm is special case of pink noise so you are right . ;)

    However since this is special case i think i will add comment to my code with mentioning this instead of deleting fbm

    i found another interesting article: http://www.redblobgames.com/articles/noise/introduction.html there is more unified implementation of pink, fbm and other fractal noises. color noises (pink, fbm as red, blue, violet) can be controlled via exponent so i decide to remove fbm and rewrote PinkNoise to ColorNoise with Exponent parameter which should lie in [-2,2] range. in my implementation exponent is reversed and -2 mean violet noise while 2 mean red noise

    here impl:

    Code (CSharp):
    1. using System;
    2.  
    3. namespace CoherentNoise.Generation.Fractal
    4. {
    5. /// <summary>
    6. /// Pink noise is a fractal noise that adds together weighted signals sampled at different frequencies, with weight inversely proportional to frequency. .
    7. /// When source noise is <see cref="GradientNoise"/>, this becomes Perlin noise.
    8. /// </summary>
    9. public class ColorNoise:FractalNoiseBase
    10. {
    11.     private float m_CurPersistence;
    12.  
    13.     ///<summary>
    14.     /// Create new pink noise generator using seed. Seed is used to create a <see cref="GradientNoise"/> source.
    15.     ///</summary>
    16.     ///<param name="seed">seed value</param>
    17.     public ColorNoise(int seed) : base(seed)
    18.     {
    19.         Persistence = 0.5f;
    20.         Exponent = 0;
    21.     }
    22.  
    23.     ///<summary>
    24.     /// Create new pink noise generator with user-supplied source. Usually one would use this with <see cref="ValueNoise"/> or gradient noise with less dimensions, but
    25.     /// some weird effects may be achieved with other generators.
    26.     ///</summary>
    27.     ///<param name="source">noise source</param>
    28.     public ColorNoise(Generator source) : base(source)
    29.     {
    30.         Persistence = 0.5f;
    31.         Exponent = 0;
    32.     }
    33.  
    34.     #region Overrides of FractalNoiseBase
    35.  
    36.     /// <summary>
    37.     /// Returns new resulting noise value after source noise is sampled. Perlin generator adds signal, multiplied by current persistence value. Persistence value
    38.     /// is then decreased, so that higher frequencies will have less impact on resulting value.
    39.     /// </summary>
    40.     /// <param name="curOctave">Octave at which source is sampled (this always starts with 0)</param>
    41.     /// <param name="signal">Sampled value</param>
    42.     /// <param name="value">Resulting value from previous step</param>
    43.     /// <returns>Resulting value adjusted for this sample</returns>
    44.     protected override float CombineOctave(int curOctave, float signal, float value)
    45.     {
    46.         if (curOctave == 0)
    47.             m_CurPersistence = 1;
    48.         value = value + signal*m_CurPersistence;
    49.         m_CurPersistence *=(float)Math.Pow(Persistence,Exponent);
    50.         return value;
    51.     }
    52.  
    53.     #endregion
    54.  
    55.     /// <summary>
    56.     /// Persistence value determines how fast signal diminishes with frequency. i-th octave sugnal will be multiplied by presistence to the i-th power.
    57.     /// Note that persistence values >1 are possible, but will not produce interesting noise (lower frequencies will just drown out)
    58.     ///
    59.     /// Default value is 0.5
    60.     /// </summary>
    61.     public float Persistence
    62.     {
    63.         get;
    64.         set;
    65.     }
    66.     public float Exponent
    67.     {
    68.         get;
    69.         set;
    70.     }
    71. }
    72. }
    and here is screenshot produced by ColorNoise alone with differenet exponent:

    colornoise.png

    from left to right: white noise, blue noise, red (fBm) noise, pink noise, violet noise. As you see blue and violet are very similar but in fact they are a bit different, difference is very subtle though. All parameters are identical except Exponent (octaves=10, amplitude 0.5)
     
    Last edited: Apr 11, 2015
  8. NoxCaos

    NoxCaos

    Joined:
    Jan 14, 2014
    Posts:
    5
    Ok, I have to generate texture 512x512, but it takes over a minute for the library to make this. Are there some performance improvements?
     
  9. Breyer

    Breyer

    Joined:
    Nov 10, 2012
    Posts:
    412
    hi again now question about Voronoi: you use Euclidean distance metric? (Vector3.SqrtMagnitude)

    I found another source about procedural, distance metrics now ex. http://numerics.mathdotnet.com/Distance.html

    and managed to implement minkowski distance metrics which is generalized algorithm for euclidean (p=2), Chebyshev (p=infinity), and manhattan (p=1) distance metric and allow mix them using floating point ex 1.5f

    here impl:

    Code (CSharp):
    1. public float MinkowskiExponent=2;
    2.  
    3. public float Minkowski(Vector3 vec)
    4.     {
    5.         return Minkowski(vec.x,vec.y,vec.z);
    6.     }
    7.     public float Minkowski(Vector2 vec)
    8.     {
    9.         return Minkowski(vec.x,vec.y);
    10.     }
    11.     /// <summary>
    12.     /// Minkowski Distance, i.e. the generalized p-norm of the difference.
    13.     /// </summary>
    14.     public float Minkowski(float x, float y, float z)
    15.     {
    16.         //if (p < 0) throw new ArgumentOutOfRangeException("p");
    17.         //if (p == 1) return Manhattan(a, b);
    18.         //if (p == 2) return Euclidean(a, b);
    19.         //if (float.IsPositiveInfinity(p)) return Chebyshev(a, b);
    20.         x=Math.Abs(x);
    21.         y=Math.Abs(y);
    22.         z=Math.Abs(z);
    23.  
    24.         var norm=Math.Pow(Math.Pow(x,MinkowskiExponent)+Math.Pow(y,MinkowskiExponent) ,1/ MinkowskiExponent);
    25.  
    26.         return (float)Math.Pow(Math.Pow(norm, MinkowskiExponent)+Math.Pow(z,MinkowskiExponent), 1 / MinkowskiExponent);
    27.     }
    28.     public float Minkowski(float x, float y)
    29.     {
    30.         //if (p < 0d) throw new ArgumentOutOfRangeException("p");
    31.         //if (p == 1d) return Manhattan(a, b);
    32.         //if (p == 2d) return Euclidean(a, b);
    33.         //if (double.IsPositiveInfinity(p)) return Chebyshev(a, b);
    34.         x=Math.Abs(x);
    35.         y=Math.Abs(y);
    36.  
    37.         var norm=Math.Pow(Math.Pow(x,MinkowskiExponent)+Math.Pow(y,MinkowskiExponent) ,2/MinkowskiExponent);
    38. //add luminosity parameter instead of 3
    39.         return (float)Math.Pow(Math.Pow(norm, MinkowskiExponent),2/MinkowskiExponent);
    40.     }
    Replace any VectorX.SqrtMagnitude() by Minkowski() and voila!

    i dont include whole package because im on complete rewrite way (33% at least code was changed and still not finished) + plans adding new noises/features (i replaced pseudo random generator everywhere by lookup table which sometime should profit in performance, tradeoff is increased memory usage, i replaced built-in FloorToInt by faster version, and have plan on removing ALL unity dependency - except TextureMaker - which ease implementing multi-threading in future)
     
  10. Captian-Brink

    Captian-Brink

    Joined:
    Aug 23, 2013
    Posts:
    44
    Last edited: Feb 2, 2017