viv*_*dos 18 c++ perlin-noise random-seed
我正在尝试用C++实现2D Perlin噪声生成,我发现一些实现根本没有使用种子(这里,这里或这里).其他实现取种子值以根据噪声值获得不同的噪声.
但是我找到了示例代码,其中一个将种子值添加到函数参数中,计算每个八度音程的噪声值(请参阅链接代码中的PerlinNoise :: Total()).另一个使用3D种子函数并使用固定的种子值作为z值(刚刚找不到示例).其他文章建议使用其他噪音功能.
所以我的问题是,为Perlin噪音生成添加种子值的最佳方法是.给定相同的种子值,应生成相同的噪声值.如果解决方案是使用自定义噪声函数,我会感兴趣它是否可以使用Boost.Random(或C++ 11的标准C++库类)实现.
编辑:用"最好"的方式回答我的意思:什么是给我Perlin噪音的最佳方式,就像它应该工作一样,例如梯度噪音功能.
viv*_*dos 17
由于没有人会从评论中写出答案,我正在尝试自己.请在我正确的时候投票,否则请评论:)
有几种实现和示例代码(尝试)实现Perlin噪声.首先,Ken Perlin本人提供了改进的噪声参考实现.
噪声函数需要三个双精度值并输出一个值.当使用x和y生成2D位图并保持z恒定时,可以获得众所周知的Perlin噪声模式.当z在0.0和1.0之间变化时,噪声云似乎缓慢地"改变".因此,设置z的播种方法例如z = 10.0 * seed可以用于"播种".
种子噪声函数的另一种方法是:如果你总是得到[0.0; 64.0 [对于x和y,可以通过在调用噪声函数时向x,y或两者添加偏移来播种噪声:噪声(x + 64.0*种子,y + 64.0*种子).
然后有一个Perlin噪声的实现(适用于许多其他Perlin噪声教程),它具有这样的基本噪声函数(伪代码):
function Noise2(integer x, integer y)
n = x + y * 57
n = (n<<13) ^ n;
return ( 1.0 - ( (n * (n * n * 15731 + 789221) + 1376312589)
& 7fffffff) / 1073741824.0);
end function
Run Code Online (Sandbox Code Playgroud)
我的主要怀疑来自神奇数字和这些页面的作者的信任,该公式导致均匀分布的噪音.其他作者在此公式中的某处添加了种子值.
为这种类型的Perlin噪声实现添加种子的解决方案是编写一个函数,该函数均匀地分配给定x和y值的输出值(当然,通过为相同的x和y值返回相同的值).可以使用Boost.Random编写此函数(未测试代码):
double Noise2(int x, int y)
{
uint32_t seeds[3] = { uint32_t(x), uint32_t(y), seed };
boost::mt19937 rng(seeds, seeds+3);
boost::uniform_real<> dist(0.0, 1.0);
boost::variate_generator<boost::mt19937&, boost::uniform_real<> >
die(rng, dist);
return die();
}
Run Code Online (Sandbox Code Playgroud)
随机数生成器有一些ctors,其中一个取一系列uint32_t来确定RNG的初始状态.
还有一些库可以产生相干噪声,例如libnoise,这可能会有所帮助.
我没有问过Simplex噪音,但是我找到的一个实现(来自Stefan Gustavson)使用了类似Ken Perlin的参考实现的类似技术(一些预先计算的表),并且可以像上面的情况1那样播种.评论员Robinson在生成查找表时提到了种子,但我不知道这是怎么回事.
| 归档时间: |
|
| 查看次数: |
16864 次 |
| 最近记录: |