Как создать многомерный PRNG? - PullRequest
0 голосов
/ 09 апреля 2020

Я работаю над процедурным генератором рельефа, но 3d-карта постоянно меняется и меняется, вызывая минимум 4d шума (5d, если мне нужно сделать его l oop). Я не нашел хорошую библиотеку perlin / simplex noise, которая бы работала во многих измерениях, поэтому я подумал, что сейчас самое время узнать, как работают эти алгоритмы. После того, как я начал делать собственный перлин-шум, я обнаружил большую проблему. Мне нужно получить псевдослучайное значение, основанное на nD координатах этой точки. До сих пор я нашел в Интернете решения, в которых используется скалярное произведение одной точки и вектора, сгенерированного входными данными, но они стали очень предсказуемыми очень быстро (я не уверен почему). Затем я попробовал рекурсивный подход (ниже), и это сработало нормально, но у меня было странное поведение по краям. Рекурсивная попытка трехмерной случайности:

function Rand(seed  = 123456, deg = 1){
    let s = seed % 2147483647;
    s = s < 1 ? s + 2147483647 : s;
    while(deg > 0){
        s = s * 16807 % 2147483647;
        deg--;
    }

    return (s - 1) / 2147483646;
}
function DimRand(seed, args){
    if(args.length < 2){
        return Rand(seed, args[0]);
    }else{
        let zero = args[0];
        args.shift();
        return DimRand(Rand(seed, zero), args);
    }
}
var T = 1;
var c = document.getElementById('canvas').getContext('2d');
document.getElementById('canvas').height = innerHeight;
document.getElementById('canvas').width = innerWidth;
c.width = innerWidth;
c.height = innerHeight;
var size = 50;
function display(){
    for(let i = 0; i < 20; i ++){
        for(let j = 0; j < 20; j ++){
            var bright = DimRand(89,[i,j])*255
            c.fillStyle = `rgb(${bright},${bright},${bright})`
            c.fillRect(i*size, j*size, size, size);
        }   
    }
    T++;
}


window.onmousedown=()=>{display();}

И вот результат:

Recursive approach Верхний ряд всегда был 1 (белый), 2-й ряд и первый все столбцы были 0 (черный), а 3d-строка всегда была очень темной (меньше ≈ 0,3)

Это может быть просто ошибка, или мне, возможно, придется просто с ней справиться, но мне было интересно, был лучший подход.

...