Желание неровных результатов от симплексного шума или другого алгоритма так же быстро

Я хочу разместить объекты, такие как деревья и тому подобное, на основе шума для ландшафта игры/технической демонстрации.

Раньше я использовал шум значений и полагаю, что достаточно хорошо понимаю шум перлина. Однако симплексный шум довольно хорошо ускользает от меня (в настоящее время чуть выше моей головы).

У меня есть реализация симплексного шума на C#, однако она почти полностью украдена из здесь . Он прекрасно работает, но я просто не понимаю его достаточно хорошо, чтобы модифицировать его для своих целей.

Это довольно быстро, но также дает довольно гладкие результаты. Я на самом деле хочу что-то немного более неровное, как простая линейная интерполяция, когда я делаю стоимостной шум. Моя проблема здесь в том, что из-за количества вызовов, которые я буду делать для размещения этих объектов и использования фрактального броуновского движения, скорость алгоритма становится очень важной.

Есть предложения о том, как получить более "зубчатые" результаты, такие как линейная интерполяция, с шумом значений, используя более быстрый алгоритм, чем шум значений?


person Mythics    schedule 29.05.2013    source источник


Ответы (2)


если вы используете сложную функцию шума для выполнения простой задачи, такой как размещение деревьев, вы используете совершенно неправильный тип математической функции. Это очень специфическая функция, которая отлично подходит для создания текстур, 3D-форм и неправильных кривых. Размещение Treas на 2d, конечно же, не требует неправильных кривых! Если только вы не хотите размещать деревья неровными и изогнутыми линиями!

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

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

используйте целые числа от 0 до 10 и от 20 до 30, умноженные на номер вашего уровня, чтобы выбрать 10 точек X и 10 Y на той же кривой псевдослучайного шума. это даст вам 10 случайных точек на вашей карте, откуда можно делать что-то, почти не вычисляя.

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

Другой вариант, если вы хотите изменить кривую http://webstaff.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf — прочитать эту статью и посмотреть на полиномиальную функцию/любую функцию градиента, которую можно использовать в вашем коде, просмотреть комментарии к функции градиента, закомментировать и do X равно Y, что должно дать вам прямую кривую интерполяции.

если вы проголосуете за этот ответ, у меня должно быть достаточно баллов, чтобы прокомментировать этот форум:]

person DeltaEnfieldWaid    schedule 24.09.2013
comment
Моя главная проблема в то время, когда я опубликовал этот вопрос, заключалась в обработке функций шума таким образом, чтобы я мог обрабатывать каждую точку исключительно. Я разбиваю свой ландшафт, поэтому обработка одного куска без необходимости проверять другие куски была очень важна. Вместо этого я использовал очень похожее на то, что вы описываете, но по частям, а не по точкам, поэтому я мог легко определить, есть ли в куске деревья и насколько они плотны полуградиентным образом, «смешивая» эти значения между соседними фрагментами. - person Mythics; 26.09.2013
comment
вот псевдослучайная функция 1d зубчатого зигзага: half rn(float xx){ half x0=floor(xx); half x1=x0+1; half v0 = frac(sin (x0*.014686)*31718.927+x0); half v1 = frac(sin (x1*.014686)*31718.927+x1); half rs=(v0*(1-frac(xx))+v1*(frac(xx))); return rs; - person DeltaEnfieldWaid; 27.09.2013
comment
Шум Перлина всегда позволяет вам обрабатывать каждую точку исключительно, и позиции деревьев не должны обновлять более пары деревьев в каждом кадре. - person DeltaEnfieldWaid; 27.09.2013

Я понимаю, что это очень старый вопрос, но я чувствовал, что предыдущий ответ был совершенно неправильным, поэтому я хотел уточнить, как вы должны использовать функцию шума для определения размещения таких вещей, как деревья/камни/ кусты.

По сути, если вы хотите глобально разместить предметы на местности, вам понадобится некоторая функция, которая сообщает вам, где они могут появиться. Например, вы можете сказать, что деревья должны быть на склонах под углом 45 градусов или меньше и ниже 2000 метров. Это дает вам карту возможных мест для деревьев. Но теперь вам нужно выбрать для них случайные, но сгруппированные местоположения.

Лучший способ сделать это — умножить вашу карту нулей и единиц на фрактальную функцию (т. е. симплексную шумовую функцию или функцию, сгенерированную с помощью подразделения и смещения — см. https://fractal-landscapes.co.uk)./maths).

Затем это дает вам функцию плотности вероятности, где значение в точке представляет относительную вероятность размещения дерева в этом месте. Теперь вы сохраняете частичную сумму этой функции для каждого местоположения на карте. Чтобы разместить новое дерево:

  1. Выберите случайное число между 0 и максимумом суммируемой функции.
  2. Выполните бинарный поиск, чтобы найти местоположение на карте в этом диапазоне.
  3. Поместите туда дерево.
  4. Промыть и повторить.

Это позволяет вам размещать объекты там, где они должны быть, в соответствии с их естественным диапазоном и так далее.

person Adam Brown    schedule 20.08.2020