Войти
ПроектыФорумУтилиты

Космический симулятор SpaceEngine (47 стр)

Advanced: Тема повышенной сложности или важная.

Страницы: 146 47 48 49217 Следующая »
#690
21:18, 15 сен. 2010

Neptune
> float height = HeightMapTerra(point);
> float сolor = ColorMapTerra(point, height);
а покажи эти функции )?


#691
15:27, 16 сен. 2010

2Neptune
>Сфера поделена на изогнутые четырёхугольные куски, на каждом текстура и нормалмапа

А как ты делаешь синхронизацию между кусками по центрам лодов (ну где глаз висит) .. А в свое время делал 6 сторон куба оттрансформенные в сферу - у меня так и не получилось сделать совпадение центров лодов между всеми 6 гранями


Я про чтото типо такого - но тут тупо куб
я и на кубе не сделал

http://img398.imageshack.us/img398/2509/cerr.jpg

#692
16:04, 16 сен. 2010

The Andreyp
Надо просто грани тоже в соседи (neighbor) прописать, а алгоритм quad-tree уже сам разрулит на автомате.

#693
16:25, 16 сен. 2010

У меня 6 клипмапов. Не дерево!

Я слышал что камеру перводят в какое то простарнство и чета какието точки пересечения проектируют куда то хз

#694
18:04, 16 сен. 2010

cNoNim
> а покажи эти функции )?

Пожалуйста:

float   HeightMapTerra(float3 point)
{
    float height = (fBm(point * surfParams.freq + Randomize) - surfParams.offset) * surfParams.norm;
    float montes = 3.0 * RidgedMultifractal(point * surfParams.freq * 117.3 + Randomize, 14, 2.7, 0.5, 0.7, 1.8);
    height += surfParams.montDistMagn * montes * saturate(10.0 * (height - surfParams.heightMont));
    return saturate(height);
}

float4  ColorMapTerra(float3 point, float height, float slope)
{
    float4 color;

    // Assign a climate type, roughly by latitude
    float  climate;
    float  latitude = abs(point.y);

    // Perturb climate zone with small noise
    noiseParams.NOctaves = 6.0;
    latitude += surfParams.colorDistMagn * fBm(point * surfParams.colorDistFreq + Randomize);
    latitude = saturate(latitude);

    if (latitude < surfParams.latTropic - tropicWidth)
        climate = lerp(surfParams.climateTropic, surfParams.climateEquator, (surfParams.latTropic - tropicWidth - latitude) / surfParams.latTropic);
    else if (latitude > surfParams.latTropic + tropicWidth)
        climate = lerp(surfParams.climateTropic, surfParams.climatePole, (latitude - surfParams.latTropic - tropicWidth) / (1.0 - surfParams.latTropic));
    else
        climate = surfParams.climateTropic;

    if (height < surfParams.heightBeach)
        climate = 0.375;
    else
        climate = lerp(climate, surfParams.climatePole, pow((height - surfParams.heightSea) / (1.0 - surfParams.heightSea), 2.0));

    if (height > surfParams.heightSea)
    {
        // Land
        //if (climate > 0.8) climate = 1.0;
        climate += 0.05 * fBm(point * surfParams.colorDistFreq * 73.7);
        color = tex2D(ColorTable, float2(climate, slope));
        if (climate < 0.75)
            color.rgb += surfParams.colorDistMagn * DistfBm(point * surfParams.colorDistFreq * 100.0, 1.5);
        //color.rgb += 5.0 * surfParams.colorDistMagn * fBm(point * surfParams.colorDistFreq * 100.0);
    }
    else
    {
        // Oceans
        noiseParams.NOctaves = 2.0;
        float shelfZone = saturate((fBm(point * surfParams.freq * 0.47 + Randomize) - surfParams.offset) * surfParams.norm);
        float depth = 1.0 - 15.0 * (1.0 - height / surfParams.heightSea);
        color = tex2D(ColorTable, float2(0.2 * shelfZone * depth, slope));
        color.rgb *= 1.0 + max(height - surfParams.heightSea, -0.5);
        color.a = 1.0;
    }

    // Ice caps
    if (latitude > surfParams.latIceCaps)
        color = tex2D(ColorTable, float2(1.0, slope));

    return color;
}

Функции типа fBm(), RidgedMultifractal() и т.д. описаны в книге Texturing & Modeling - A Procedural Approach.
Это пока очень примитивно и требует дальнейших экспериментов. Например горные массивы как-то нездорово кучкуются в центре материков (второй скрин). Надо вводить геологическое моделирование...

scr00100 | Космический симулятор SpaceEngine
scr00101 | Космический симулятор SpaceEngine
scr00102 | Космический симулятор SpaceEngine
scr00103 | Космический симулятор SpaceEngine
scr00104 | Космический симулятор SpaceEngine

#695
18:05, 16 сен. 2010

Нeптун - не мог ты ответить на мой вопрос. Наверняка сам делал клипмапами тоже

#696
18:16, 16 сен. 2010

The Andreyp
> Наверняка сам делал клипмапами тоже
Quadtree, он уже раз десять объяснял. )

#697
18:16, 16 сен. 2010

  Опишу ландшафтный движок ещё раз.
  Больше всего похоже на geo mipmap (chunked lod) на кубе. Берётся куб (точнее сфера, типа "надутого куба"), каждая грань - корень quad tree. Каждой грани соответствует большая текстура например 32768*32768 (текстура поверхности с водой в альфа-канале и 16-битная карта высот). В корене дерева - эта текстура, уменьшенная до размера например 512*512. Корень сплитится на 4 потомка, каждый из них тоже сплитится на 4 узла-потомка и так далее, если надо (это зависит от положения камеры и fov'а (угла зрения)). Первый уровень - 4 потомка корня - исходная текстура, уменьшенная до 1024*1024, и порезанная на тайлы 512*512 (4 штуки). Второй уровень - 2048*2048, - 16 узлов и 16 тайлов по 512*512, и так далее. 6 уровень - исходная детализация 32768*32768, 4096 тайлов. В принципе, максимальная детализация не ограничена. При рендере отпределяется, какие узлы видны, какие нужно сплитить на потомки, нужные текстуры грузятся в параллельном потоке (а при записи демки в потоке рендерера). Из тайла карты высот делается нормал мапа для освещения и меш с геометрией этого куска поверхности. Наиболее давно использованные текстуры и меши удаляются из памяти (LRU-кэш). Для процедурных планет всё то же самое, просто вместо загрузки текстуры с диска она генерируется специальным шейдером, описанным выше.
  Меш имеет меньшее, чем текстура, разрешене (32*32), поэтому для самого детального лода текстур строятся ещё 4 уровня лодов мешей (32 * 2^4 = 512), использующих всё ту же текстуру. Поэтому в демке и на видео детализация геометрии и текстуры совпадают (на каждый пиксель по вершине). Разрешения текстур и меша могут быть другими (например у процедурных планет 256*256 и 32*32), алгоритму всё равно.
  Критерий, по которому определяется, когда надо делить узел на потомки - это примерный размер его на экране. Если разрешение текстуры 512*512, а размер узла стал k пикселей, значит пора подгружать его потомки. Этот параметр k обычно равен 512, т.е. экранная детализация всегда примерно с пиксельной точностью (пока не достигнут максимальный уровень), но это приводит к чудовищному потреблению памяти... Если сделать k = 1024, памяти потребляется меньше, и планета загружается быстрее (меньше узлов), но становится немного размытой. В общем, этот момент ещё надо обдумать и переделать. Например ввести зависимость k от уровня лода. Ещё один момент - для рендера лода N нужно чтоб в памяти уже был лод N-1, т.к. пока текстуры лода N ещё грузятся, нужно что-то рендерить. В итоге в памяти всегда находится пирамида лодов для текущей позиции камеры. И наоборот, нельзя выгрузить 1 или 2 уровень, даже если камера летает у поверхности с лодами 10 уровня, иначе при быстром взлёте вверх рендерить-то будет нечего, придётся ждать, пока снова подгрузятся лоды 1 или 2 уровня.

Вот картинка (вместо текстур планеты - дефолтная, чтоб было понятно):
scr00000 | Космический симулятор SpaceEngine

Подлетаем ближе - раз! ближняя "грань" - узел одного из 6 quad tree - разделилась на 4 дочерних узла. Подгрузились свои текстуры, создалась геометрия...
scr00001 | Космический симулятор SpaceEngine

Подлетаем ещё ближе - теперь уже дочерние узлы делятся.
scr00002 | Космический симулятор SpaceEngine

А вот несколько скринов подлёта к Марсу, справа в wireframe режиме
Mars | Космический симулятор SpaceEngine

  Проблема стыковки мешей решается как обычно - определяется лод соседа, и если он меньше на 1, берётся другой индексный буффер, в котором по этой стороне квадрата пропущена каждая вторая вершина. Данные о высоте в соседнем узле такие же, как в текущем, если они оба построены по одной и той же текстуре, а если по разным - тут я поступил хитро, при подготовке текстур включил по их периметру пиксели из соседних текстур (так что разрешение стало 514*514). Это заодно решило проблему бесшовной стыковки цветовых текстур при рендере (но не нормалмапов, для них надо брать по 2 дополнительных пикселя). Эта схема простая, но работает не очень хорошо. Например, трещины в ландшафте появляются, если лоды соседей отличаются больше, чем на 1 (это бывает при резких поворотах камеры), так же они всегда есть, хоть и малые, при переходах между текстурами разных уровней, ведь в этом случае пиксели по периметру всё равно разные (у текстуры другого лода их вообще в 2-4-8-... раз больше, чем у текущей). С процедурными планетами простое увеличение разрешения на 2 пикселя вообще не прокатывает. Короче, эту систему надо переделывать.
Правка от 06.03.2011: Пока что тупо добавил "юбки" по периметру патчей, щели пропали, но зато немного тормознее стало рендериться.

  По поводу того, как производится тесселяция. Представьте куб, на каждой грани которого работает описанное выше quad tree. Для каждого узла дерева загружаются/генерируюся карта высот и цвета. По карте высот создаётся нормалмапа, и строится плоский меш меньшего, чем текстура, разрешения, вершины которого сдвинуты по вертикали на величину h из карты высот. Всё плоское. А теперь возьмём координаты вершины (x,y,h) и нормализуем её, опустив на сферу, а потом учтём высоту:
  vec3 point = normalize(vec3(x, y, 1.0)) * (1.0 + h/planetRadius)
  Другие грани куба получаются так же путём поворотов/отражений, или перестановкой компонентов вектора, если хотите.

#698
18:17, 16 сен. 2010

The Andreyp
> Нeптун - не мог ты ответить на мой вопрос. Наверняка сам делал клипмапами тоже
У меня не клипмапы, да, а квад-три. Читай выше))

#699
19:10, 16 сен. 2010

Neptune
> просто вместо загрузки текстуры с диска она генерируется специальным шейдером, описанным выше.
а ты не пробовал не использовать текстуру вообще, а генерировать высоту и цвет на лету, в вертексном и пиксельном шейдере соответственно?

#700
19:40, 16 сен. 2010

Neptune
> Texturing & Modeling - A Procedural Approach
ухты годная книжка )))

#701
21:05, 16 сен. 2010

cNoNim
> а ты не пробовал не использовать текстуру вообще, а генерировать высоту и цвет
> на лету, в вертексном и пиксельном шейдере соответственно?
Ага, по 10 мс на патч, 150 патчей в кадре - получается 1.5 секунды на кадр:)))

#702
21:51, 16 сен. 2010

хм... а патч у тебя какой? и почему их так много?

#703
13:01, 17 сен. 2010

Neptune

Cyan planet - PowerOfOrion DeepBattle CP MK3 | Космический симулятор SpaceEngine
Cyan planet | Космический симулятор SpaceEngine

вот , Neptune - есть такой вопрос - тут две картинки - одна , та что поменьше - имеет почти такую же синюю планету , как и вторая - та что побольше - во всяком случае так воспринимается - хотя на маленькой картинке в реале в Игре текстура там намного ниже порядком , но так как картинка сжата то и детализация повысилась - так вот , если картинку сжать и вкинуть в GPU - а там обратно Zoom-ировать до того же размера - можно ли получить выше качество . И другое , если ты не будешь к примеру напрямую на экран выводить изображение ( которое ты генеришь ) , а увеличишь допустим виртуальную картинку раза в четыре - потом ужмешь до размеров экрана ( требуемого расширения ) и будешь выводить по столько картинок в секунду - по сколько тебе нужно ( к тому же если картинка еще не преобразовалась - можно заменить ее другой предыдущей - но уже со спецэффектом ) - плюс легче сделать анимацию для PR-ного ролика .

#704
19:26, 17 сен. 2010

Нептун, а какой Лод системой отрисовываешь ландшафт ? Пи методом или другим ? И вообще какие бывают методы отрисовки ландшафта ?

Страницы: 146 47 48 49217 Следующая »
ПроектыФорумУтилиты