I'm writing a shader which occasionally makes a point sparkle on a 2D map. (The "sparkle" is simply a brighter-colored pixel.) I'd like the sparkled blocks to appear randomly and uniformly distributed on the (infinite) plane, but I want the sparkling to be deterministic based on X and Y coordinates. I tried creating seed from the coordinates and creating a Java Random
from that seed, but my attempts have so far resulted in recognizable patterns. This function will be called frequently (many millions of times) so performance is critical.
I first tried to mimic my hashCode()
implementation, which uses a prime number multiplier to avoid collisions. This resulted in a visible gash across the map where a series of points shared the same seed.
I then tried to create a seed by concatenating the coordinates like so:
long seed = ((long) x << 32) | (long) y;
Random rand = new Random(seed);
This seems to result in patterned data as well, though the pattern isn't as obvious. The selected coordinates appear in lines, not evenly distributed at all.
I've avoided using MD5 or other cryptographic hashing algorithms because I'm afraid of the performance impact.
The linear congruential generator implemented in
java.util.Random
has the advantage of being repeatable for any chosenSEED
. Given these declarations,You can initialize a (repeatable) list of
N
randomly chosen points in the rectangle(0, 0, MAX_X, MAX_Y)
as follows:It may be convenient to give each point a
Timer
whose period is chosen from the same sequence: