2

I am looking for a random number generator with 3 inputs for a terrain generator. The inputs are an x, y (position) and a seed value. And the function returns back a random number from 0-1.

So far I found this question, but this has 2 inputs. Although I can combine x and y to a single number, to get two inputs, this will restrict the choices I will have for x, y as they need to be sufficiently large (the terrain is infinite).

Is there any random function that takes in 3 inputs, or would I need to end up using the 2 input version?

6
  • What type are the three inputs? uint32/uint64/double/something else? Commented Mar 10, 2022 at 10:57
  • uint32 is the type @Leo Commented Mar 10, 2022 at 11:11
  • 1
    Your intention to pass a seed value for every invocation of your generator indicates a conceptual misunderstanding of how PRNGs work. Frequent manual seeding will not increase the quality of the pseudo-random numbers, and in fact usually does the opposite. Commented Mar 10, 2022 at 14:21
  • 1
    @pjs I don't think the intention is to increase the quality of the numbers. It is to have a repeatable way to generate a 2D map from different seeds while being able to generate the points in an arbitrary order (like when the player moves around in directions they pick). Kind of like a CTR mode of a cipher but non-cryptographic. Commented Mar 10, 2022 at 14:29
  • 1
    This is similar to an earlier SO question #61969876. You can combine x and y with the Cantor pairing function. Then use the result of the pairing function as an offset into some pseudo-random serie. Pseudo-random generators that efficiently support this arbitrary access into their serie can be CTRs, or MRGs such as MRG32k3a. That way, only a single seed value is required for the whole game. Commented Mar 10, 2022 at 16:43

1 Answer 1

2

Something like this should work. It takes three 32-bit integers, and outputs a single 32-bit integer. If you want to turn the output into a double between 0 and 1, just divide by UINT32_MAX.

The input and output sizes can be adjusted.

You can also tweak the balance between output quality and speed. You'll notice that the middle section is just repeated 3 lines, remove or add more of them to make the output more or less biased.

Here's the C code.

uint32_t rotl32(uint32_t n, uint8_t k) {
  uint32_t a = n << k;
  uint32_t b = n >> (32 - k);
  return a | b;
}

uint32_t three_input_random(uint32_t x, uint32_t y, uint32_t z) {
  uint32_t a = x;
  uint32_t b = y;
  uint32_t c = z;

  b ^= rotl32(a + c, 7);
  c ^= rotl32(b + a, 9);
  a ^= rotl32(c + b, 18);
  b ^= rotl32(a + c, 7);
  c ^= rotl32(b + a, 9);
  a ^= rotl32(c + b, 18);
  b ^= rotl32(a + c, 7);
  c ^= rotl32(b + a, 9);
  a ^= rotl32(c + b, 18);

  return a + b + c + x + y + z;
}
Sign up to request clarification or add additional context in comments.

1 Comment

I found many implementations of noise functions in GLSL that can be used for this purpose as well.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.