105

Поскольку результаты поисков по вопросу неудовлетворительны, то решил-таки задать вопрос.

Требуется эффективный алгоритм рисования чего-то, похожего на звёздные туманности. Крайне желательно, чтобы рендер мог выполняться в реальном времени и почти настоятельно требуется, чтобы алгоритм был стабильным (выдавал одну и ту же картину при неизменных входных параметрах).

В ходе поисков я обнаружил фрактальный алгоритм Buddhabrot, но он довольно медленный, насколько я могу судить по той реализации, что я увидел (http://cabin.users.geeky.net/classes/buddhabrot.html запустить и подождать около минуты)

UPD: я выставил теги не совсем верно (поправьте, если кто знает, какие тэги здесь более уместны). Не обязательна реализация на яве. Главное - понять идею, а перенести на J2D я уж как-нибудь сумею.

UDP2: без сомнения идея с зарядами дала результаты. Пока они незначительные, но уже кое что.. немного поправить распределение зарядов и цветовую гамму + звёзды + сглаживание шума вместо грубого шума и будет то что надо. На этом основании закрываю вопрос и помечаю ответ как правильный. Возможно также попробую наложить спирали на эту сцену: вместе со звёздами должно получиться неплохо.

скриншот

UPD

Итак, скрещивание спиралей с точечными зарядами удалось.. теперь надо наложить облакообразный шум (в чём мне очень помогла статья Simple Clouds Part 1)

скриншот со спиралью

UPD 21 сентября

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

скриншот со спиралью, звёздами и центричностью зарядов

qwerty
  • 3,957
cy6erGn0m
  • 19,707
  • 1
  • 33
  • 39
  • 2
    Не совсем то, но может пригодиться: http://libnoise.sourceforge.net/ – stanislav Feb 01 '11 at 21:48
  • Да, это хотя и не то, что надо, но тоже интересно.. особенно про Землю. – cy6erGn0m Feb 01 '11 at 22:03
  • одна и та же картинка - может сохранять/кешировать на сервере/клиенте проще?..

    Для генерации туманностей в виде правильных галактик можно использовать кривые архимеда/логарифмические (http://www.exponenta.ru/soft/others/stud1/main.asp), с добавление шума в виде randoma, но тут опять же это условие)

    – Бодров Андрей Feb 02 '11 at 08:28
  • Сервера нет. Кэширование обязательно будет, но я не могу кэшировать всё.. придётся иногда рисовать их заново, если туманность будет вытеснена из кэша. – cy6erGn0m Feb 02 '11 at 08:41
  • может проще тогда будет вообще занести растр в двухмерный массив, забив прямо в коде? – Бодров Андрей Feb 02 '11 at 09:31
  • Тогда надо сделать много вариантов.. либо придумать какие-то искажения, которые бы делали исходные изображения неузнаввемыми.. – cy6erGn0m Feb 02 '11 at 09:45
  • А что плохого в том, что в выводимых туманностях специалисты узнают реально существующие туманности?

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

    – Бодров Андрей Feb 02 '11 at 09:59
  • Проблема не в том, что знатоки спалят, а в том, что нужно достаточное разнообразие. Иначе будет много повторов. – cy6erGn0m Feb 02 '11 at 10:39
  • В Eve-Online фоновое изображение туманностей не просто повторяется, оно вообще одинаковое в всех звездных системах одного региона, незначительно изменяясь по оттенку цвета. Так же было во Freelancer, кстати) Вместо изменения по оттенку можно делать комбинации со вторым изображением сверху с альфа-каналом 50%. В Eve-Online ~7к звездных систем и 50к игроков на пиках, на отсутствия разнообразия никто не жаловался) – Бодров Андрей Feb 02 '11 at 10:52
  • Возможно, вы правы. Всё же я попытаюсь зарендерить и начну "нарезать" только в случае, если у меня ничего не получится. Спасибо за совет. – cy6erGn0m Feb 02 '11 at 11:02
  • Отпишите алгоритм, когда будут первые результаты, плиз) – Бодров Андрей Feb 02 '11 at 11:28
  • не очень понимаю что такое рендер туманности.

    если это просто генерация из рандомных чисел двухмерного массива - все просто используете rand а перед ним ОБЯЗАТЕЛЬНО srand(100) (число должно быть одикаково ипри одинаковых исходных параметрах). если библиотека генерации рандомных чисел одинакова - то всегда получете одно и то же.

    если это что то более сложное - то это более сложные алгоритмы (например не просто рандоные числа а рандомные числа сгруппированные вокруг какого то центра или нескольких центров).

    – Денис Feb 03 '11 at 11:30
  • Ну да. Нужно сгенерировать случайную туманность. То что надо рандом использовать, это ясно и так, но проблема в том, что его ещё надо применить к чему-то. Да, должен быть какой-то центр (или центры), но как? Даже просто какое-то абстрактное облако сделать не так-то просто, как кажется. – cy6erGn0m Feb 03 '11 at 11:36
  • ну если туманность это несколько центров а вокруг них несколько точек. первый рандом - генрация числа центров center_count.

    for (int i=0; i<center_count; ++i) {

    } потом в

    – Денис Feb 03 '11 at 11:40
  • Нужен же не просто шум вокруг точек, а надо чтобы облако туманности было "гладким" и выглядело естественно. – cy6erGn0m Feb 03 '11 at 11:44
  • 2
    http://fractalworld.xaoc.ru/Plasma_fractal – Ivlev Denis Aug 14 '11 at 14:18
  • Красиво получилось, но (посмотрел фотки) не очень похоже. В настоящих ощущается некая динамика, какие-то перекрученные рукава.

    Может быть при моделировании с зарядами (а скорее от зарядов надо перейти к массам) им надо задать начальные импульсы, чтобы они двигались и отслеживать "историю засветки" (напряженности поля по точкам). А при получении итогового кадра "вклад" предыдущих состояний должен убывать.

    Жалко не обратил должного внимания на этот вопрос раньше и похоже свободного времени для экспериментов нет, а задачка интересная.

    – avp Sep 14 '11 at 21:25
  • Обновите вопрос, когда сделаете спирали. – avp Sep 15 '11 at 11:34
  • Здорово !

    А заряды Вы, похоже, случайно размещаете в квадрате ?

    Попробуйте разбрасывать и в случайном эллипсе (случайным делать размер и поворот осей), мне кажется будет еще более похоже на природу.

    – avp Sep 16 '11 at 12:06
  • 1
    А можно открыть исходник от UPD 21 сентября. народу будет легче помочь и улучшить – kandi Aug 07 '13 at 13:20
  • Да, это уже здорово! (без всякой иронии). Если тема еще интересна, рекомендую посмотреть статью в в ноябрьском номере журнала "Популярная механика". Но http://www.popmech.ru/article/9909-zvezdnyie-ostrova/ отсылает читать печатный номер журнала. – avp Sep 21 '11 at 06:33
  • Ага.. думаю, мне надо что-то сделать со звёздами, чтобы они "реагировали" на туманность, а то по центру не аккуратно накладываются. – cy6erGn0m Sep 21 '11 at 07:20

3 Answers3

39

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

Я пробовал, медленно генерирует, и нужно долго подбирать коэффициенты для нормального вида.

Попробуйте другой метод: расположить несколько точек (зарядов), а цвет туманности задать как потенциал или эл.поле от этих зарядов f = k/r или E = k/(r^2) не забывая про суперпозицию.

sanmai
  • 12,320
Sanaff
  • 596
  • 3
  • 4
23

Насчет функции генерации облака вокруг центра. Если взять приближение (не четкие мат функции). Например, первый rand дает значение от 0 до 1 (дробное).

Разобьем значение 0 - 1 на части:

  • 0 - 0,5 - вероятность 50%, значит расстояние должно быть маленькое, максимум 10 (можно от 0 до 10)
  • 0,5 - 0,7 - вероятность меньше, расстояние максимум 100 (можно от 10 до 100)
  • 0,7 - 0,8 - вероятность еще меньше, расстояние максимум 1000 (можно от 100 до 1000)

Потом применяем найденное максимальное расстояние к рандому нахождения координат: (второй и третий ранд) = (x,y)

Тут можете сами задавать кратность и вероятность 'рисовать' какие угодно функции распределения - я не специалист как они выглядят более естественно. Главное алгоритм - если будете вызывать напрямую функцию генерации точек, то они могут быть медленными, а тут сами рулите.

Кстати насчет функций - вероятно, есть какие-то алгоритмы: задаете текущий srand, задаете центр распределения, вызываете функцию с предопределенными параметрами и она вам генерирует точки, например, по нормальному закону или по экспоненте (какие-то такие функции я видел в математических пакетах, сразу не вспомню)

phen0menon
  • 653
  • 5
  • 19
Денис
  • 457
  • 2
  • 8
  • ОК. За три+ рандомов можно определить примерный размер (радиус описанной окружности вокруг туманности) и центр(ы). Спору нет, что это действительно просто. – cy6erGn0m Feb 03 '11 at 11:53
  • такие функции я использовал, когда делал Asteroids на паскале лет 10 назад. хотелось бы что-то более реалистичное, и, к сожалению, альтернативы спрайтам не вижу. но хотел бы увидеть) – Бодров Андрей Feb 03 '11 at 15:03
  • Нужна какая-то хорошая волновая функция.. можно конечно наложить несколько синусоид с разными масштабами.. но, боюсь, это будет очень уж бесформенная лажа :) – cy6erGn0m Feb 03 '11 at 15:14
0

Если объём туманности не нужен, то можно выполнить лишь часть из этой статьи-перевода на хабре: Алгоритм быстрого и простого объёмного рендеринга (Автор оригинала: Chris Wallis)

Merlin
  • 5,491
  • 5
  • 47
  • 90