Войти
ПрограммированиеФорумГрафика

Фрактальный игровой мир

Страницы: 1 2 320 21 Следующая »
#0
18:39, 20 апр. 2011

Не так давно я стал замечать в Инете очень красивые 3D картинки. Стало интересно, как их делали, поскольку удивляла деталировка и большое количество объектов. Оказалось что год назад программист Tом Лав (Tom Lowe) придумал новый тип фракталов, он назвал их mandelbox. Надо сказать, что незадолго до этого, другой математик - Даниел Вайт (Daniel White) предложил свой концепт 3D фрактала используя сфрические координаты (он назвал его mandelbulb), но Том пошел другим путем, хотя общее у обоих методов имеется.

Теперь картинка:
Изображение

Неплохо да?
Но самое интересное, что ВСЕ ЭТО делается одной функцией:

float DE2(vec3 pos)
{
  vec4 scale = 12;
    vec4 p = vec4(pos,1.0), p0 = p; 
    for (int i=0; i<10; i++)
  {
        p.xyz = clamp(p.xyz, -1.0,1.0)) * 2.0 - p.xyz;
        p.w+=0.2;
        float r2 = dot(p.xyz, p.xyz);
        p *= clamp(max(0.25/r2, 0.25), 0.0, 1.0);
        p = p*scale + p0;
    }
  return length(p.xyz)/p.w;
}

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

Теперь как это можно использовать:

Вообще-то получился очень сложный и красивый игровой мир. Полностью процедуральный (генеративный). Никаких моделей - голая математика.  Да, подход необычный, но при этом появляются интересные возможности, Например я сделал "пролет через стены". Если просто двигаться то при попадании в стенку "свет гаснет". Я чуть подшаманил функцию и получилось вот что: про подлете к стене она начинает покрываться пузырями, потом лопается и в ней появляется отверстие. Попробуйте сделать что-то подобное традиционными средствами! А в этом случае все свелось к такому коду:

float DE0(vec3 pos)
{
  vec3 z=pos-from;
  float r=dot(pos-from,pos-from);
  return (0.01/(pow(r,16.0)+0.01))*0.1;
}
float DE(vec3 pos)
{
  float d0=DE0(pos);
  float d2=DE2(pos);
  return max(d0,d2);
}

ВСЕ! Легко реализуются коллизии, фактически это делается на этапе трассировки, если расстояние до поверхности меньше радиуса камеры - значит вы на что-то наткнулись. Освещение проблемм не представляет - нормали к поверхностям считаются на лету. Можно совмещать несколько формул вместе, вот например я объединил mandelbox и mandelbulb, для этого надо просто выводить минимальное расстояние до поверхности, вот так:

DE(vec3 pos)
{
        return min(DE1(pos), DE2(pos));
}
где DE1 это формула манделбалба (она не сложнее чем манделбокс - тоже 20 строк). Вот что получается:

Изображение


Короче весьма интересный подход.
Плюсы: очень простой код, буквально несколько строк (полный размер шейдера со всеми пробамбасами (трайсер, освещение и т.п.) - 200 строк на GLSL. Фактически это воксели, т.е. есть информация о всем объеме сцены. Можно трансформировать объекты просто меняя параметры - все движется весьма сложным образом (например так: http://www.youtube.com/watch?v=DXtCOXvLvYA - это манделбалб). Я выложу на ютуб видео с полетом по такому миру, пока не успел записать.

Минусы: нужна крутая карта, у меня на 480 и на экране 1920х1080 получается только 15 фреймов. Но можно похерить слегка точность и на консолях где сильные карты наверно пойдет. Вторая проблема - поскольку мир создается формулой, его не так просто контролировать. Непонятно как делать текстурирование - скорее всего надо использовать 3 проекции, благо нормали имеются.

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


#1
18:50, 20 апр. 2011

А какой практический смысл от этих бесформенных фиговин для игр?

#2
19:11, 20 апр. 2011

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

#3
19:25, 20 апр. 2011

Кастую демку.

#4
19:31, 20 апр. 2011

Практический смысл неочевиден, но его можно ~извлечь~. При должном старании, конечно.

#5
19:33, 20 апр. 2011

subs.

Лучше думать в направлении генерируемого арта на базе более привычных человеку примитивов: труба, стенка, здание и т.д.

#6
19:34, 20 апр. 2011

Barzoque
> это параметрическая поверхность все-таки

Да нет, в том то и дело что это не поверхность а объем. Хотя довольно своеобразный - в точке считается производная от расстояния до камеры. Не понимаю физический смысл этого, но реальное расстояние до точки это сумма (т.е. интеграл) по лучу всех значений формулы DE().

Barzoque
> все-таки скорость маленькая получается

Так ведь это пока. А через года 2-3 уже вполне можно будет использовать. Скоро новые карты пойдут по 28nm технологии. Сразу производительность подскочит минимум вдвое. Но что бы через 2 года продукт выпустить, сначала надо технологию освоить. А для этого 480 карты и 15 фраймов вполне достаточно.

Собственно я просто показал подход к конструированию мира. А нужен он вам или нет - это каждый сам решает. Но информация никогда лишней не бывает.

Подкупает простота - попробуйте сварганить что-то похожее традиционными средствами. Сразу понадобятся моделеры, движок и т.п. А тут я вывожу один квад в размер экрана и 200 строк на шейдере. И картинка очень даже ничего. Без движка и без моделей. Камера летает, коллизии, деформация поверхностей, освещение и все на 200 строчках. Элементарно скажем стрелялку сделать. Можно будет например шарики подбивать. Шарик это еще 5 строк кода, выстрел - просто еще один луч. Попал в шарик - он пропал. А так они летают в металлоконструкциях и попробуй их найди среди всего этого мусора. Вся игра будет занимать строк 250-300.

#7
19:48, 20 апр. 2011

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

#8
20:11, 20 апр. 2011

Синий Дракон

Ну вот так выглядит функция трассировки:

vec3 trace(vec3 from, vec3 dir)
{
  vec3 direction = normalize(dir); 
  float dist = 0.0;
  float totalDist = 0.0;
 
  float steps;
  for (steps=0; steps<MaxRaySteps; steps++) 
  {
    vec3 p = from + totalDist * direction;

    dist = DE(p);
    dist = clamp(dist, 0.0, MaxDist);

    totalDist += dist;

    if(totalDist>MaxDist)  // если расстояние больше предельного - будет небо
      break;

  }

в результате totalDist будет содержать расстояние до точки.

Что важно, если скажем DE() дает значения, 0,0,0,0,1000,0,0,0,0, то суммарное расстояние будет 1000, т.е. в этом случае это будет дырка. Другими словами DE это не само расстояние, а его производная, а расстояние - интеграл. Т.е. расстояние - это сумма всех DE.

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

Вот лови:
http://www.sanbasestudio.com/art/download/Mandelbox.frag  // это формула со всеми параметрами
http://www.sanbasestudio.com/art/download/DE-Raytracer.frag // а это трейсер

Или тут скачай весь проект: http://sourceforge.net/projects/mandelbulber/ он с исходниками.

#9
20:27, 20 апр. 2011

san
>подход совсем новый, только в прошлом году изобрели.
Расскажи это нвидям
Generating Complex Procedural Terrains Using the GPU
Изображение

#10
20:29, 20 апр. 2011

stopkin
> Расскажи это нвидям
Читай лучше. Тут ничего общего.

#11
20:33, 20 апр. 2011

nes
> А какой практический смысл от этих бесформенных фиговин для игр?
Допустим, mandelbox - огромная космическая станция, человеческая колония, а mandelbulb - гигантская разросшаяся загадочная инопланетная фигня.
Пользователь может играть лесными эльфами, охраной дворца и злодеем. за инопланетян, охрану станции и космических пиратов.
Для целой игры это может оказаться маловато, но в качестве лётной части игры - очень даже хватит.
Если соединить это с генерацией внутренних помещений станции по рандому (и запоминать двухбайтовый сид, по которому помещение можно всегда воссоздать чтобы вернуться в него), то получится огромный детализированный игровой мир, которые не ставит вообще никаких ограничений в перемещениях перед игроком.

#12
20:36, 20 апр. 2011

san
>Тут ничего общего.
Опа... Заменили растеризацию на трассировку - и уже ничего общего? Ф-ция плотности, фрактал, GPU. Ничего общего :)

#13
20:38, 20 апр. 2011

Имхо было бы полезнее, если твои 200 строчек кода генерировали некую сущность реального мира, например горы, моря и прочее
А так польза очень не очевидна, по крайней мере мне

#14
20:41, 20 апр. 2011

pacos
Хороший пример, нужно подумать

Страницы: 1 2 320 21 Следующая »
ПрограммированиеФорумГрафика

Тема в архиве.