TarasB
А вот здесь
template <int N, int STEP> struct UselessWrapperFillPerlinStep <N, STEP, true> { static void FillPerlinStep(tblib::modarray <tblib::modarray<Fixed, N>, N> &texture) { UselessWrapperFillPerlinStep <N, STEP*2>::FillPerlinStep( texture); for ( int j=0; j<N; j+=STEP*2) for ( int i=0; i<N; i+=STEP*2) texture[j+STEP][i] = ( texture[j][i]+texture[j+STEP*2][i])>>1; for ( int j=0; j<N; j+=STEP) for ( int i=0; i<N; i+=STEP*2) texture[j][i+STEP] = ( texture[j][i]+texture[j][i+STEP*2])>>1; for ( int j=0; j<N; j+=STEP) for ( int i=0; i<N; i+=STEP) texture[j][i] += rnd.frandom( )*Fixed( STEP,N); } };
нету выхода за границы массива?
При i==N-STEP*2 или j==N-STEP*2.
MarkoPolo
>По поводу перлина, а он разве сам по себе не сумма кучи случайных гармоник?
Можно подробнее, что подразумевается здесь?
Спасибо за полезную инфу о генерации уровня. Было очень интересно вкурить.
TarasB
Алгоритм генерации кольцевых маршрутов для меня стал открытием таки. Здорово.
Ну и остальное тоже ничего, интересненько.
FordPerfect
Честно говоря, статья на Вики, которая на русском, порвала мой шаблон.
Почему "градиентный"? Вот как это понять:
Для генерации шума Перлина в одномерном пространстве необходимо для каждой точки этого пространства вычислить значение шумовой функции, используя направление градиента (или наклон) в указанной точке.
"Используя направление градиента"... Чтобы использовать, его нужно ИМЕТЬ, а нам предлагают ИСПОЛЬЗУЯ (то есть имея) его вычислить шумовую функцию.
состоящий из набора псевдослучайных единичных векторов (направлениях градиента), расположенных в определенных точках пространства
Во-первых - это неграмотно, не "направлениях градиента", а "направлений градиента", статья вообще с точки зрения грамотности и языковой выразительности... не очень.
Во-вторых - при чём тут вообще градиент? Это же и есть сама шумовая функция? Остаётся её интерполировать МЕЖДУ этими точками. Похоже, что автор переводил с английского, не понимая сути. Градиент - это метод, используемый для интерполяции значений МЕЖДУ сгенерированными.
В-третьих - почему "в определенных точках пространства"? Разве не конкретно по регулярной сетке?
До сих пор считал так.
По перлину рекомендовал бы использовать библиотеку libnoise, opensource,
- есть множество примеров, в том числе генерация тайловых текстур
- текстур под планеты (т.е. специальные такие текстуры для натягивания на сферы)
- возможность "бесконечной" детализации
более детализированный тот же участок
- и мн. др. + куча грамотного кода и документации в картинках.
Mikle
> Градиент - это метод, используемый для интерполяции значений МЕЖДУ сгенерированными
Насколько я понял, тут "градиент" используется как математический термин.
> Во-вторых - при чём тут вообще градиент? Это же и есть сама шумовая функция?
> Остаётся её интерполировать МЕЖДУ этими точками. Похоже, что автор переводил с
> английского, не понимая сути.
Функция шума получается так:
Берём градиенты из ближайших к нашей точке узлов решётки (для двумерного случая пусть будут g1, g2, g3, g4), и вектора из этих узлов до нашей точки (v1, v2, v3, v4)
Находим скалярные произведения si = dot(gi, vi), i=1..4, и вот по ним уже интерполируем итоговое значение шума.
> "Используя направление градиента"... Чтобы использовать, его нужно ИМЕТЬ, а нам предлагают ИСПОЛЬЗУЯ (то есть имея) его вычислить шумовую функцию.
Таки да, его нужно иметь заранее вычисленным.
FordPerfect
modarray в операторе [] содержит деление по модулю с нахождением положительного остатка
TarasB
Да, протормозил. Теперь вижу, спасибо.
Mikle
Статья о шуме Перлина на русской Википедии - не подарок, согласен.
И http://archive.today/BGnW , ИМХО, не сказать, чтобы сильно лучше, хотя и подробнее.
Вот английская статья на Википедии внятная, вроде.
Ради исторической ценности: http://mrl.nyu.edu/~perlin/doc/oscar.html#noise .
>"Используя направление градиента"... Чтобы использовать, его нужно ИМЕТЬ, а нам предлагают ИСПОЛЬЗУЯ (то есть имея) его вычислить шумовую функцию.
Градиенты (единичные векторы) задаются (генерируются случайным образом) изначально, в узлах решётки.
>В-третьих - почему "в определенных точках пространства"? Разве не конкретно по регулярной сетке?
Перлин использовал регулярную сетку. Мне примеры использовния чего-то другого для ШП не встречались. Но теоретически, можно наверное взять произвольный набор точек, построить триангуляцию Делоне и интерполировать на нём.
>> Градиент - это метод, используемый для интерполяции значений МЕЖДУ сгенерированными
>Насколько я понял, тут "градиент" используется как математический термин.
Вроде бы да.
FordPerfect
> Градиенты (единичные векторы) задаются (генерируются случайным образом)
> изначально, в узлах решётки.
В узлах решётки генерируются никак не векторы, а скаляры, скаляр можно назвать 1D вектором, но не единичным вектором, это разные вещи.
А что такое градиент, согласно той же Вики:
вектор, своим направлением указывающий направление наибольшего возрастания некоторой величины φ, значение которой меняется от одной точки пространства к другой (скалярного поля), а по величине (модулю) равный быстроте роста этой величины в этом направлении.
Это то есть, когда у нас всё скалярное поле определено, можно искать градиенты по разнице с соседями.
Mikle
http://en.wikipedia.org/wiki/Perlin_noise
Grid definition [edit]
Define an n-dimensional grid. At each grid coordinate assign a gradient vector of unit length in n dimensions. For a one-dimensional grid each coordinate will be assigned either +1 or -1, for a two-dimensional grid each coordinate will be assigned a random vector on the unit circle, and so forth for higher dimensions.
>Это то есть, когда у нас всё скалярное поле определено, можно искать градиенты по разнице с соседями.
Изначально задаются векторы в узлах решётки, и когда мы посчитаем скалярное поле, выяснится, что его градиент в узлах решётки совпадёт с наперёд заданным вектором в данном узле. По построению.
Выкладки показать?
FordPerfect
Сколько я видел примеров ШП, в узлах изначально задавали скаляры, потому я и пишу про разрыв шаблона.
А тут не просто векторы, а ещё и обязательно единичные...
Во избежание недоговорок, привожу выкладки.
Есть точка r в единичном квадрате (пусть для определённости [0..1]*[0..1]).
Есть 4 градиентных вектора n00, n01, n10, n11, в узлах g00, g01, g10, g11 рассматриваемого квадрата.
Есть функция интерполяции f(t) с очевидными требованиями: непрерывная, гладкая, f(0)=0, f(1)=1.
Quod erat demonstrandum.
TarasB
Приношу извинения за замусоривание темы текстом близким к оффтопу.
FordPerfect
> Приношу извинения за замусоривание темы текстом близким к оффтопу.
лол это ж гд
UnitPoint
>По перлину рекомендовал бы использовать библиотеку libnoise, opensource,
Для 3D Перлина ещё можно взглянуть на stb_perlin.h. Single-file, public domain, header-only.
Вообще на https://github.com/nothings/stb порядком вкусностей, смотрю.
FordPerfect
> Во избежание недоговорок, привожу выкладки.
Да я ж не спорю, просто говорю - шаблон порван. ШП - это несколько не то, чем я его считал. Впрочем, внешне похоже.