Base – модуль для включения основных стандартных библиотек
Win32 – модуль, связанный с включением библиотек среды Windows
При проектировании программы важно сразу решить, как будут представлены исходные данные, то есть, в условиях данной работы – как будет описана карта высот и трехмерный ландшафт, какими будут форматы файлов для хранения информации о карте и ландшафте.
В данной работе был выбран полигональный способ аппроксимации пространственных фигур. Сущность полигональной модели состоит в том, что каждое тело представляется в виде определенного набора граней-многоугольников, с определенной точностью приближающих форму исходного тела. В качестве грани-многоугольника был выбран треугольник, так как это наиболее простой многоугольник, его точки всегда лежат в одной плоскости и любой более сложный многоугольник можно разбить на несколько треугольников. Но ускорения вычислений я не стал вводить тип треугольник в моей программе. Вместо этого есть массив вершин и массив индексов, которые и указывают на определенные треугольники (0, 1, 2 – первый треугольник; 1, 2, 3 – второй треугольник и т.д.)
Разработанные типы данных и форматы файлов подробно описаны в последующих разделах.
// в данной структуре вместо целого значения цвета используется вектор с реальными координатами
classLight
{
publicVector Ambient;
publicVector Diffuse;
publicVector Mirror;
public Light() { }
public Light(Vector Ambient, Vector Diffuse, Vector Mirror)
{
this.Ambient = Ambient;
this.Diffuse = Diffuse;
this.Mirror = Mirror;
}
}
classDirLight : Light
{
publicVector Dir;
public DirLight() { }
public DirLight(Vector Ambient, Vector Diffuse, Vector Mirror, Vector Dir)
: base(Ambient, Diffuse, Mirror)
{
this.Dir = Dir;
}
}
classPointLight : Light
{
publicVector Point;
publicdouble c1, c2, c3;
public PointLight(Vector Ambient, Vector Diffuse, Vector Mirror, double c1, double c2, double c3, Vector Point)
: base(Ambient, Diffuse, Mirror)
{
this.Point = Point;
this.c1 = c1;
this.c2 = c2;
this.c3 = c3;
}
}
classMaterial
{
publicVector Ambient;
publicVector Diffuse;
publicVector Mirror;
public Material(Vector Ambient, Vector Diffuse, Vector Mirror)
{
this.Ambient = Ambient;
this.Diffuse = Diffuse;
this.Mirror = Mirror;
}
}
classPerlinNoise
{
int TableSize;
int TableMask;
structvec2
{
publicdouble x, y;
public vec2(double x, double y) { this.x = x; this.y = y; }
};
vec2[] VectorTable;
byte[] lut;
public PerlinNoise(int TableSize)
void setup()
// вычисляется значение шумовой функции (в данной программе высота) с коэффициентом scale (чем больше scale, тем более изломанная карта) в координате xy
publicdouble Generate(double x, double y, double scale)
publicdouble Generate(int x, int y, double scale)
}
classLandscape
{
GenMethod LandGenMethod;
Convolution[] Convs;
bool Smoothing;
bool Valley;
bool Island;
publicdouble[,] Heightmap;
int[,] Lightmap;
int[,] Colormap;
publicint SizeX, SizeY;
int LSizeX, LSizeY;
int CSizeX, CSizeY;
Vector[,] Points;
int[] Indexes;
Vector[] FaceNormals;
Vector[,] VertexNormals;
Vector Pos;
Vector Dimen;
publicMaterial Ground;
public Landscape() { }
// генерирует карту высот с размером SizeX, SizeY, по методу LandGenMethod c коэффициентами Convs, со сглаживанием или нет (Smoothing) с долинизацией (Valley)
publicvoid GenerateHeightmap(int SizeX, int SizeY, GenMethod LandGenMethod, Convolution[] Convs, bool Smoothing, bool Valley, bool Island)
// строить трехмерную модель ландшафта с размерами Dimen.X Dimen.Y Dimen.Z
// Также просчитываются нормали к граням FaceNormals и к вершинам VertexNormals
publicvoid BuildMesh(Vector Dimen)
// Цвет данной точки ландшафта с координатами Pos нормальную Normal добавляетсякрезультирующему Color
publicvoid AddColor(Vector Pos, Vector Normal, Light Source, refint Color)
// построение карты освещенности с учетом Sources источников света. Размеркарты SizeX*Size SizeY*Size
publicvoid BuildLightmap(Light[] Sources, int Size)
// построение карты теней и смешение ее с картой освещенности
publicvoid BuildShadowmap(Light[] Lights, int Size)
// построение "цветовой" карты (или текстуры) на основе массива Colors
publicvoid GenerateColormap(Color[] Colors, int Size)
// сохранение карты высот в файл BMP
publicvoid SaveHeightmap(string FileName, outBitmap Result)
// сохранение карты освещенности в файл BMP
publicvoid SaveLightmap(string FileName, outBitmap Result)
// сохранениетекстурывфайл BMP
publicvoid SaveColormap(string FileName, outBitmap Result)
}
Эта программа позволяет настроить загрузку изображений карты высот и текстуры, а также текстур неба и воды из файла или сгенерировать их автоматически.
Параметры генерации карты высот настраиваются в разделе «Параметры генерации». В этом разделе можно загрузить готовый шаблон или установить параметры вручную.
Поле размер – установка ширины, длины карты высот, а высота нужна для дальнейшего построения карты освещенности (регулирование пропорций ландшафта)
Поле материал – установка отражающей способности материала ландшафта для фонового и диффузного отражений соответственно (белый цвет – отражение всех цветов)
Шкала цветов используется при построении текстуры ландшафта (каждому значению высоты соответствует цвет из этой шкалы цветов)
Далее можно выбирать алгоритм генерации ландшафта: с помощью шума Перлина или простого холмового алгоритма
Флажок «Остров» используется для генерации таких типов ландшафтов, на границе которых высота равна нулю (для плавного спуска в воду)
Флажок «Долина» используется для долинизации ландшафта
В данной программе можно создавать карту освещенности с различно настроенными источниками света в количестве не более 5.
Для каждого источника света также можно настривать цвет фонового освещения, диффузного освещения, вектор направления (или позицию с коэффициентами угасания c1 c2 c3 для точечных источников)
Создание карт
Создать карту высот можно двумя способами:
· загрузить уже имеющееся изображение в формате BMP (поддерживается работа только с 24-битным цветом).
· сгенерировать новую карту
При создании карты высот, автоматически создаются карта освещенности и текстура.
Сохранение карт
Сохранение производится автоматически при нажатии на кнопку «Генерировать». При сохранении создаются 3 файла:
· карта высот *.bmp
· карта освещенности *.bmp
· текстура *.bmp
Эта программа позволяет просматривать ландшафты в интерактивном режиме, построенные из ранее сгенерированных карты высот, текстур и карт освещенности. Также в этой программе есть поддержка неба, водной поверхности, отражений от воды.
W, A, S, D – навигация по пространству
[ ] – увеличение/уменьшение уровня моря.
z, x, c – включение/отключение соответственно текстуры, карты освещенности и карты деталей.
v – привязка камеры к поверхности ландшафта (нельзя будет опуститься под поверхность) .
Входными данными для данной программы является карта высот, карта освещенности и текстура ландшафта, 5 кубических текстур неба и текстура воды в графических файлах в формате “.bmp”, также файл конфигурации, где указаны пути к этим ресурсам. В нем содержится вся информация, необходимая для работы программы. Так же при изображении ландшафта принимаются данные с клавиатуры и мышки, которые интерпретируются как команды пользователя, и в зависимости от них строится последующее изображение.
Выходными данными программы является анимационный ряд с изображением трехмерного ландшафта, построенного и отображенного на основании входных данных. Также выходными данными является информация о количестве кадров, выводимых на экран за секунду.
Рекомендуемые требования к аппаратному обеспечению:
· x86-совместимый процессор Intel или AMD с тактовой частотой 1 ГГц и выше;
· Оперативная память объемом от 512 Гб и выше;
· Видеоадаптер, совместимый с OpenGL 1.2.
· Операционная система: WindowsXPили выше
Тестирование проводилось на компьютере IntelCore 2 Duo 3 Hz, 1 GbRAM, GeForce 8800 Gts 320 Mb.
Были проведены следующие исследования:
Из данного графика видно, что скорость просчета карты освещенности прямо пропорциональна количеству источников света на сцене. Это соответствует и теоретическим расчетам: каждый пиксель карты освещенности обрабатывается от одного источника освещения только один раз.
Из данной зависимости становится понятным, что затрачиваемое время на просчет карты освещенности ~ 2^N, где N – размер карты.
Следующие графики показывают зависимости числа кадров в секунду, генерируемых программой, от числа граней с наложением карт освещения и без него, для двух способов наложения карт освещения – двухпроходного рисования и мультитекстурирования.
Двухпроходное рисование | Мультитекстурирование |
Суть двухпроходного рисования в том, что каждая грань рисуется два раза – один раз с основной текстурой, второй раз с картой освещения в режиме «смешивания» - поэтому скорость рисования сцены падает в два раза. Мультитекстурирование – операция, реализованная аппаратно и позволяющая наложить несколько текстур в один проход, поэтому скорость рисования сцены падает очень незначительно. В обоих случаях число кадров в секунду выше требуемого для интерактивных программ уровня в 25 кадров/с.
Сравним использование карт освещения с простой моделью освещения, реализованной программно (освещенность вычисляется для каждой грани в момент рисования):