Генератор случайных чисел с белым шумом 3D с произвольным доступом
У меня практически нулевой опыт работы со случайными генераторами. Я использовал стандартные функции rand в C, и я использовал перлин-шум.
Но теперь мне нужен куб с разрешением NxNxN (с N, может быть, 1e6 или больше), заполненный белым шумом (без плавности perlin или чего-либо еще), в котором я могу просто "выбрать" одно значение, и если я перефиксирую это же значение, оно должно быть один и тот же результат каждый раз. Нужно посеять, чтобы, если я снова запустил приложение, результаты должны были быть такими же. Он не должен быть безопасным или чем-то еще, достаточно случайным, чтобы человек не мог предсказывать ценности, просто думая. Если он действительно анализирует это с помощью компьютера, это нормально, что это предсказуемо.
Это как если бы я использовал стандартную функцию C rand, устанавливая начальное значение и выполняя вложенный цикл for для 3 измерений и генерируя случайное число каждый раз, пока я не достигну координаты. Это конечно ужасно медленно. Мне нужно что-то быстрое!
Я искал в Интернете и нашел много и ничего одновременно. Может быть, я ищу неправильные ключевые слова, но я не нашел ничего, что я мог бы использовать.
Кто-нибудь может помочь мне начать? Код? Ссылка? Мне все равно, понимаю ли я алгоритмы, но он должен быть легким в реализации и использовании и особенно быстрым.
1 ответ
Поскольку, кажется, никто не может ответить на этот вопрос, я исследовал этот вопрос и решил его следующим решением:
int pseudoRandom(int &seed)
{
const int a = 16807; // 7^5
const int m = 2147483647; // 2^31 - 1
seed = int(unsigned(seed * a) % m);
return seed;
}
Я беру вышеупомянутую, хорошо известную, случайную функцию. Это хорошая функция, так как она может быть легко преобразована в язык шейдеров и может быть легко расширена до 64-битных целых или чего-то еще.
Теперь я должен иметь возможность создавать случайные числа между 0,0 и? в 3 измерениях, и они всегда должны иметь одинаковый результат с одним и тем же базовым начальным числом, поэтому я взял целую часть каждого компонента x, y и z и базовое начальное число.
int seed = baseseed;
pseudoRandom(seed);
pseudoRandom(seed * (int(x) + seed) * (int(y) + seed) * (int(z) + seed);
=> seed теперь на значении, где я могу начать создавать детальную случайную сетку. Так что, если мне нужна деталь из 32x32x32 случайных значений, я просто сгенерирую ее здесь в массив. Если бы мне понадобился больший массив, я мог бы сделать тот же шаг снова, чтобы сгенерировать другой слой, например:
pseudoRandom(seed * (int(x * 100) + seed) * (int(y * 100) + seed) * (int(z * 100) + seed);
Таким образом, вы на самом деле совершенно свободны в том, как вы рандомизируете, и у вас есть полный контроль над деталями.
Это решило мою проблему.