Всем привет, в 3D графике помимо решения задач тени/света, и примитивов, а так же физики и возможно каких-то базовых задач, которые сегодня могут заменить библиотеки по математике, стоит отметить генерацию поверхностей. Какие-то поверхности впуклые, какие-то поверхности выпуклые, поверхности можно комбинировать. Как это влияет на процесс в графике? Например иммерсив - погружение. Влияет следующим образом, конечно все вкусы учесть невозможно. Задаём какие-то характеристики, которые характеризуют площадь поверхности и далее если она "подходит" в целом по ощущениям и по логике, её можно использовать как декорацию, возможно оптимизировав - если постараться, или оставить как есть. В этой статье хочу продемонстрировать как удалось добиться генерации пещер, конечно при помощи открытых источников. Все источники будут указаны в конце обзора, гит.

*
*

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

Так же, есть в API или в движках возможность оптимизированной прорисовки, в Opengl это например PRIMITIVE_RESTART****, в движках Unity/Unreal/Godot и т.д. Надо смотреть какие апи используются и смотреть документацию API, если есть интерес разобраться как организовать такую технику отрисовки. Можно рисовать и в простом режиме треугольников это должно всегда работать, надеюсь читатель знает как сгенерировать горизонтальную поверхность в нужном шаге сетки на нужной высоте.

Итак приступим

Буду использовать Linux, gcc 14.2(из репозитория), glfw(из репозитория) - только пк, lua(5.3 (cd src; make liblua.a)) - мечта организовать конфиг из файла таблицы lua, stb_image, assimp(из репозитория) - перечислил все основные зависимости моего микро-проекта на данный момент, читатель может заметить нету математики, за место всей математики, можно воспользоваться cglm.

Алгоритм генерации

Алгоритм подогнан под задачу, на текущем этапе пока присматриваюсь к нему, мне нравится.

//c ***
void generateCaverns(Heightmap1 *heightmap, 
                     int rows, int columns, 
                     int numHills, 
                     int hillRadiusMin, int hillRadiusMax, 
                     float hillMinHeight, float hillMaxHeight){
    for (int i = 0; i < numHills; i++)
    {
      
      int hillCenterRow = random1(0,(rows-1));//random от до
      int hillCenterCol = random1(0,(columns-1));
      int hillRadius = random1(hillRadiusMin,hillRadiusMax);
      float hillHeight = random1(hillMinHeight,hillMaxHeight);

      for (int r = hillCenterRow - hillRadius; r < hillCenterRow + hillRadius; r++)
      {
        for (int c = hillCenterCol - hillRadius; c < hillCenterCol + hillRadius; c++)
        {
          if (r < 0 || r >= rows || c < 0 || c >= columns)
          {
            continue;
          }
          int r2 = hillRadius * hillRadius;
          int x2x1 = hillCenterCol - c;     
          int y2y1 = hillCenterRow - r;     
          float height = (float)(r2 - (x2x1 * x2x1) - (y2y1 * y2y1));
          if (height < 0.0f)
          {
            continue;
          }
          float factor = height / r2;
          heightmap->heighData[r][c] += hillHeight*factor;
          if (heightmap->heighData[r][c] > 1.0f)
          {
            heightmap->heighData[r][c] = 1.0f;
          }
        }
      }
    }
}

может показаться что тут нет ничего особенного мол всё тривиально, вставим *(200,200,125,10,20,1,3) затем применим Scale(800,50,800)***** - если верить точкам в блендере будет 40 тысяч вершин

пара примеров
пара примеров

https://github.com/richKirl/TestDSAOpenglWorld

ресурсы

youtube.com/watch?v=qChQrNWU9Xw - подробная вводная по террейнам от ThinkMatrix

libnoise.sourceforge.net/noisegen/index.html - вводная библиотеки либнойс

libnoise.sourceforge.net/glossary/index.html#perlinnoise

https://www.mbsoftworks.sk/tutorials/opengl4/016-heightmap-pt1-random-terrain/ - вводная в сам подход ***

stuffwithstuff.com/robot-frog/3d/hills/hill.html

computergraphics.stackexchange.com/questions/8242/can-you-disable-strip-cutting-aka-primitive-restart-on-direct3d-11 ****

без домножения внутри присваивания высоты *****

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

тут 2 вида генерации, сама поверхность этажа, и декорация пещеры
тут 2 вида генерации, сама поверхность этажа, и декорация пещеры

видимо с редактированием вообще можно получать минималистичные слепки

так же хочу добавить/отметить сильную сторону алгоритма - если еще плюс ко всему это инстанс то верх можно не рисовать вроде.

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

Комментарии (0)