如何从 X/Y 坐标确定性地生成伪随机模式?
我正在编写一个着色器,它偶尔会使 2D 地图上的点闪闪发光。 (“闪烁”只是一个颜色较亮的像素。)我希望闪烁的块随机出现且均匀分布在(无限)平面上,但我希望闪烁基于 X 和 Y 坐标是确定性的。我尝试从坐标创建种子,并从该种子创建 Java Random
,但到目前为止,我的尝试已经产生了可识别的模式。该函数将被频繁调用(数百万次),因此性能至关重要。
我首先尝试模仿我的 hashCode()
实现,它使用素数乘法器来避免冲突。这导致地图上出现明显的裂缝,其中一系列点共享相同的种子。
然后,我尝试通过连接坐标来创建种子,如下所示:
long seed = ((long) x << 32) | (long) y;
Random rand = new Random(seed);
这似乎也会产生图案化数据,尽管图案并不那么明显。选定的坐标以线的形式出现,根本不均匀分布。
我避免使用 MD5 或其他加密哈希算法,因为我担心性能影响。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
以下是一个非常有效的函数,用于以伪随机但确定性的方式混合位:
因此,如果您想要来自 x 和 y 坐标的伪随机长结果,您可以执行以下操作:
我已经在之前的图形,给出了相当不错的结果!随机数的质量与 java.util.Random 一样好,但速度更快......
The following is a very efficient function for mixing bits in a pseudo-random but deterministic fashion:
So if you want a pseudo-random long result from x and y co-ordinates you could do something like:
I've used this approach successfully in graphics before, gives pretty good results! The quality of random numbers is about as good as java.util.Random but it is much faster....
线性同余生成器在
java.util.Random
的优点是可重复用于任何选定的SEED
。给定这些声明,您可以初始化矩形
(0, 0, MAX_X, MAX_Y)
中随机选择的N
点的(可重复)列表,如下所示:这可能很方便给每个点一个
Timer
谁的周期从相同的序列中选择: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:这是我所做的事情,它有效(产生了预期的效果),但绝对不完美。
除了特别冗长之外,使用
Random
可能有点过多,因为我只调用nextInt()
两次。它对于生成特定范围内的值很有用,但无论如何我应该能够使用模算术来做到这一点。我喜欢 MD5 是一种易于理解的算法,并且加密安全性对于此应用程序来说并不重要。不过,我肯定想要更快(而且不那么混乱)的东西。
This is something I did which works (produces the desired effect) but definitely isn't perfect.
Aside from being particularly verbose, the use of the
Random
is probably excessive since I only pull callnextInt()
twice. It's useful for generating values in a specific range, but I should be able to do that with modulo arithmetic anyway.I like that MD5 is a well-understood algorithm, and cryptographic security is not important for this application. I would definitely like something faster (and less messy), though.