Симплексный шум черепицы? - PullRequest
4 голосов
/ 21 августа 2009

Меня интересует (как любитель) генерация псевдослучайного шума, в частности, алгоритмы Perlin и Simplex. Преимущество Simplex - это скорость (особенно при больших размерах), но Perlin может быть сравнительно легко выложен плиткой. Мне было интересно, если кто-нибудь знал о алгоритме листов симплекс? Фиксированная размерность в порядке, общая - лучше; с псевдокодом все в порядке, с / с ++ лучше.

Ответы [ 4 ]

3 голосов
/ 27 ноября 2010

Просто разбейте свой шум так же, как в Perlin, только после перекоса. Вы можете сделать это, изменив часть, которая получает перестановки, чтобы сделать мод 256 (или & 255, независимо от того, что вы используете) после того, как (а не до) вы добавили к смещениям, чтобы получить другие углы из базового угла. Это модифицированный бит кода в HLSL:

uint3 iIdx0 = p0SI % 256;
uint3 iIdx1 = (p0SI + pI1) % 256;
uint3 iIdx2 = (p0SI + pI2) % 256;
uint3 iIdx3 = (p0SI + 1.0f) % 256;
uint iGI0 = gPerm[ iIdx0.x + gPerm[ iIdx0.y + gPerm[ iIdx0.z ] ] ] % 12;
uint iGI1 = gPerm[ iIdx1.x + gPerm[ iIdx1.y + gPerm[ iIdx1.z ] ] ] % 12;
uint iGI2 = gPerm[ iIdx2.x + gPerm[ iIdx2.y + gPerm[ iIdx2.z ] ] ] % 12;
uint iGI3 = gPerm[ iIdx3.x + gPerm[ iIdx3.y + gPerm[ iIdx3.z ] ] ] % 12;

p0SI - это точка угла 0, а pI2 и PI2 - векторы для угла один и угла 2, рассчитанные обычным способом. Обратите внимание, что в HLSL скаляры автоматически переносят векторы в смешанных операциях, так что, например, 1.0f на самом деле (1.0,1.0,1.0). Я только что разобрался с этой плиткой, но, по-видимому, она работает. Если вам нужно затенить большую планету или какое-то дерьмо, но иметь только одну точность на вашей карте, есть еще несколько шагов. Ударь меня.

Редактировать: вы знаете, подумав еще немного, я не думаю, что вам нужно что-то менять. Я думаю, что это автоматически в 256 единиц, как реализовано.

2 голосов
/ 27 апреля 2012

Казалось бы, этот вопрос был разумно решен здесь , с подробным описанием идеи рабочего решения здесь . Фантастический ответ на давнюю проблему!

2 голосов
/ 27 апреля 2012

Даже если прошло несколько лет, этот вопрос по-прежнему остается одним из лучших результатов в Google.

В симплексном шуме x и y из прямой (ортонормированной) сетки искажаются, чтобы найти симплекс, в котором находится точка (треугольник в 2D), поэтому с обычными методами разбиения на листы (% 255 или чем-то другим), он ДЕЛАЕТ плитку, но плитки на скошенных координатах, то есть это плитки по диагонали, что совершенно бесполезно.

Простое решение, которое я нашел, состоит в том, чтобы «отменить» результат, так чтобы исходные X и Y сначала были перекошены «влево», затем алгоритм переместит их «вправо», а финальный результат будет перенастроен на не перекошенную сетку.

Если, например, ваша симплексная реализация похожа на SimplexNoise.java, которую вы можете найти везде в сети, она искажает сетку с помощью:

var F2 = 0.5*(Math.sqrt(3.0)-1.0);
var s = (xin+yin)*F2; // Hairy factor for 2D
var i = Math.floor(xin+s);
var j = Math.floor(yin+s);

Вы можете просто «предварительно наклонить» его в противоположном направлении в точке входа метода:

var G2 = (3.0-Math.sqrt(3.0))/6.0;
var t = (xin+yin)*G2;
xin-=t;
yin-=t;

К сожалению, он производит странный эффект (то есть выглядит немного искаженным: D), что обычно не проблема, но зависит от того, для чего вам нужен этот шум.

Поскольку это было проблемой для меня, я попытался применить этот «обратный перекос» только к нескольким октавам, тем, которые больше весят в конечном результате, и вместо этого использовал интерполяцию для «более легких» октав. Это решение дало мне удовлетворительную мозаику, основанную на симплексном шуме Перлина, потому что интерполяция на всех октавах привела бы к слишком большому затуханию на границах мозаики, и когда добавление большего количества октав без искусственного перекоса, эффект внешнего вида скрывается под дополнительным шумом.

1 голос
/ 08 сентября 2010

Мне недавно понадобился плиточный симплексный шум, и я столкнулся с этим вопросом.

Для шума мозаичного изображения с использованием любой шумовой функции вы можете линейно интерполировать дополнительные выборки мозаичного изображения:

Ftileable(x, y) = ( 
       F(x, y) * (w - x) * (h - y) + 
       F(x - w, y) * (x) * (h - y) + 
       F(x - w, y - h) * (x) * (y) + 
       F(x, y - h) * (w - x) * (y)
) / (wh)

где F () - ваша функция шума. Обратите внимание, что x, y должны быть координатами в пределах отдельной плитки: x в [0, w), y в [0, h). Вы можете использовать что-то вроде tileX = x - Math.Floor (x / w) * w или fmod ().

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

Взято из: http://webstaff.itn.liu.se/~stegu/TNM022-2005/perlinnoiselinks/perlin-noise-math-faq.html

...