Search code examples
c#unity-game-enginerandomrandom-seedperlin-noise

Random float using coordinate as seed


The Mathf.PerlinNoise(float x, float y) function returns a float that I use. I want a more completely random function that can use coordinates as it's seed.

My ideal would have the exact same input and output as the aforementioned Mathf.PerlinNoise function, . The point is that it can be switched out with the Perlin Noise function to return completely random floats that return the same float for any given coordinate each and every time.


Solution

  • So your question consists of 2 problems:

    1. Create a seed from the 2 float values that always maps the same input to the same seed.

    2. Using a seed to generate a random float.

    For the first problem this can be solved by creating a hashcode, there are different ways to do it but I'll refer to this answer by John Skeet for more information on that. For you the hashing would look like this:

    public int GetHashCode(float x, float y)
    {
        unchecked // Overflow is fine, just wrap
        {
            int hash = (int)2166136261;
            // Suitable nullity checks etc, of course :)
            hash = (hash * 16777619) ^ x.GetHashCode();
            hash = (hash * 16777619) ^ y.GetHashCode();
            return hash;
        }
    }
    

    So now problem 1 is solved we can move on to problem 2, here we have a problem since you require a float which the Random class doesn't support. If a double is good enough for you (floats from your PerlinNoise can be converted to double's), you could then do this:

    public double GenerateRandom(float x, float y)
    {
        return new Random(GetHashCode(x, y)).NextDouble();
    }
    

    If double is not good enough and you require it to be a float, I'll refer to this answer, all his solutions should work with a Random instance created using the hash function above as seed.

    Hope this helps and good luck with your project!