Generating Perlin Noise in C#


Noise textures are often very important in lots of algorithms used in computer graphics.

This post will show a simple implementation of the classic Perlin Noise technique.

The code below shows a class responsible for generating each point of the noise texture. The implementation is simple, we used the perlin formula to generate the point, and after we make a bilinear interpolation to smooth a little the sample:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PloobsEngine.Utils
{
    /// Perlin Noise
    public class PerlinNoise
    {
        /// Perlin Noise Constructot
        public PerlinNoise(int width, int height)
        {
            this.MAX_WIDTH = width;
            this.MAX_HEIGHT = height;                
        }

        public int MAX_WIDTH = 256;
        public int MAX_HEIGHT = 256;
                
        /// Gets the value for a specific X and Y coordinate
        /// results in range [-1, 1] * maxHeight
        public float GetRandomHeight(float X, float Y, float MaxHeight,
            float Frequency, float Amplitude, float Persistance,
            int Octaves)
        {
            GenerateNoise();
            float FinalValue = 0.0f;
            for (int i = 0; i < Octaves; ++i)
            {
                FinalValue += GetSmoothNoise(X * Frequency, Y * Frequency) * Amplitude;
                Frequency *= 2.0f;
                Amplitude *= Persistance;
            }
            if (FinalValue < -1.0f)
            {
                FinalValue = -1.0f;
            }
            else if (FinalValue > 1.0f)
            {
                FinalValue = 1.0f;
            }
            return FinalValue * MaxHeight;
        }

        //This function is a simple bilinear filtering function which is good (and easy) enough.        
        private float GetSmoothNoise(float X, float Y)
        {
            float FractionX = X - (int)X;
            float FractionY = Y - (int)Y;
            int X1 = ((int)X + MAX_WIDTH) % MAX_WIDTH;
            int Y1 = ((int)Y + MAX_HEIGHT) % MAX_HEIGHT;
            //for cool art deco looking images, do +1 for X2 and Y2 instead of -1...
            int X2 = ((int)X + MAX_WIDTH - 1) % MAX_WIDTH;
            int Y2 = ((int)Y + MAX_HEIGHT - 1) % MAX_HEIGHT;
            float FinalValue = 0.0f;
            FinalValue += FractionX * FractionY * Noise[X1, Y1];
            FinalValue += FractionX * (1 - FractionY) * Noise[X1, Y2];
            FinalValue += (1 - FractionX) * FractionY * Noise[X2, Y1];
            FinalValue += (1 - FractionX) * (1 - FractionY) * Noise[X2, Y2];
            return FinalValue;
        }

        float[,] Noise;
        bool NoiseInitialized = false;
        /// create a array of randoms
        private void GenerateNoise()
        {
            if (NoiseInitialized)                //A boolean variable in the class to make sure we only do this once
                return;
            Noise = new float[MAX_WIDTH, MAX_HEIGHT];    //Create the noise table where MAX_WIDTH and MAX_HEIGHT are set to some value>0            
            for (int x = 0; x < MAX_WIDTH; ++x)
            {
                for (int y = 0; y < MAX_HEIGHT; ++y)
                {
                    Noise[x, y] = ((float)(StaticRandom.Random()) - 0.5f) * 2.0f;  //Generate noise between -1 and 1
                }
            }
            NoiseInitialized = true;
        }

    }
}

To transform the sampled points in a texture you could use the following code:

public Texture2D CreatePerlinNoiseTexture(int sizex, int sizey,float frequencia, float amplitude, float persistence, int octave,bool mipmap = false)
        {
            PerlinNoise pn = new PerlinNoise(sizex, sizey);
            Texture2D t = factory.CreateTexture2D(sizex, sizey,mipmap); ///helper that creates a simple empty texture
            Color[] cor = new Color[sizex * sizey];
            for (int i = 0; i < sizex; i++)
            {
                for (int j = 0; j < sizey; j++)
                {
                    float value = pn.GetRandomHeight(i, j, 1, frequencia, amplitude, persistence, octave);
                    value =  0.5f * (1 + value);
                    cor[i + j * sizex] = new Color(value,value,value);
                }
            }

            t.SetData(cor);
            return t;            
        }

  1. #1 by kredit vergleich htm vergleich privatkredit zinsen on 17 de janeiro de 2017 - 12:02 am

    Yours is a clever way of thinking about it.

  2. #2 by android apps for pc on 17 de janeiro de 2017 - 12:07 am

    Some really nice and useful info on this internet site, too I think the layout contains excellent features.

  3. #3 by Hotels on 17 de janeiro de 2017 - 12:44 am

    I will right away seize your rss as I can not in finding your e-mail subscription link or e-newsletter service. Do you’ve any? Please permit me recognize in order that I may subscribe. Thanks.

  4. #4 by Venonat Pokemon on 17 de janeiro de 2017 - 1:54 am

    Nice post. I be taught something tougher on totally different blogs everyday. It’ll at all times be stimulating to learn content from other writers and practice a bit one thing from their store. I’d favor to use some with the content material on my blog whether you don’t mind. Natually I’ll offer you a hyperlink in your internet blog. Thanks for sharing.

  5. #5 by Legal Rights on 17 de janeiro de 2017 - 3:25 am

    I haven¡¦t checked in here for some time since I thought it was getting boring, but the last few posts are great quality so I guess I will add you back to my daily bloglist. You deserve it my friend :)

  6. #6 by Venusaur Pokemon on 17 de janeiro de 2017 - 4:12 am

    I like what you guys are up also. Such smart work and reporting! Keep up the excellent works guys I’ve incorporated you guys to my blogroll. I think it’ll improve the value of my website :)

  7. #7 by летище софия полети on 17 de janeiro de 2017 - 4:41 am

    The next time I read a blog, I hope that it doesnt disappoint me as much as this one. I mean, I know it was my choice to read, but I actually thought youd have something interesting to say. All I hear is a bunch of whining about something that you could fix if you werent too busy looking for attention.

1 236 237 238
(não será publicado)