Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Визуализация воды.doc
Скачиваний:
46
Добавлен:
01.05.2014
Размер:
438.78 Кб
Скачать

Отражения.

Вода является очень хорошим отражателем, и реалистичность отображаемой водной поверхности существенно зависит от реализации отражения объектов, находящихся над водой и у поверхности воды. Но, так как вода является динамически изменяемым объектом (в данной задаче), то отражения тоже должны, по возможности, повторять форму движения водной поверхности.

Сложность моделирования отражений состоит в том, что отражения являются зависимыми от вектора наблюдения и положения наблюдателя: если наблюдатель сдвинется или повернется, то отражения изменятся. То есть при статическом положении наблюдателя можно заранее просчитать отражение, но если существует возможность изменения положения наблюдателя или вектора наблюдения, то отражения заранее просчитаны быть не могут, поскольку дискретность изменения положения наблюдателя и вектора наблюдения должна быть произвольной.

Обычно, водные поверхности моделируются на открытом пространстве. И здесь необходимо учитывать эффект отражения неба от поверхности воды. Для этого берется текстура неба и накладывается на поверхность воды, но координаты текстуры не изменяются в зависимости от изменения водной поверхности. В OpenGL это достигается следующим образом:

Прозрачность и преломление.

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

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

Для водных поверхностей также характерны каустики - эффект прохождения света сквозь водную поверхность, подверженную колебаниям. В этом случае на дне возникают некоторые световые пятна, которые также можно визуализировать. Для этого над поверхностью дна делается еще один полупрозрачный слой из плоскостей, с наложенными на них текстурами каустиков. Также нельзя забывать, что так как поверхность динамична, то и текстура с каустиками должна динамически изменяться. Обычно поступают следующим образом: берется некий заранее просчитанный набор текстур с каустиками (10-15) и попеременно сменяют одну другой в соответствие с изменением соответствующей водной поверхности, в конце данный процесс зацикливают.

Bump mapping.

Bumpmappingиспользуется для передачи неровностей поверхности. Реально в природе не существует абсолютно плоских объектов, и большинство объектов, которые мы видим в реальной жизни обладают различными шероховатостями. В моделировании при передаче общей формы объекта мы разбиваем его на полигоны. Но для передачи таких "мелких" свойств, как неровности необходимо модифицировать текстуру объекта или накладывать на одну плоскость несколько текстур (делать несколько полупрозрачных плоскостей, параллельных данной, но находящихся "немного выше" нее или использовать мультитекстурирование, входящие в расширениеOpenGL).

Условно говоря, нам необходимо лишь менять направление нормали в каждой точке плоскости для передачи неровностей, и это возможно, используя расширения OpenGL. Но мы будем рассматривать лишь стандартOpenGL. Здесь подобного можно добиться, если выводить вместо каждой плоскости, для которой мы хотим произвестиbumpmapping, три плоскости, параллельные друг другу и находящиеся на небольшом отдалении друг от друга (чтобы визуально этого было не заметно).

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

Сначала мы загружаем исходную текстуру воды (1), а из карты поверхности создаем две текстуры: первая(2)- точно такая же, но в каждой точке значение делиться на два (так как текстура черно-белая, то будем считать что мы уменьшаем яркость в два раза); вторая(3)- это инвертированная (по значению яркости) карта поверхности, для которой также значение яркости делится на 2, то есть здесь: <source_pixel> = (255 - <map_pixel>) / 2.

Вывод на экран происходит в следующей последовательности: сначала выводится текстура (2), перед этим вOpenGLдолжны быть установлены следующие параметры:

Перед выводом следующей плоскости устанавливаются следующие параметры:

Сама плоскость выводится выводится на том же месте, что и предыдущая, но "чуть-чуть" приподнята относительно вектора наблюдения (чтобы не было перекрытий) и наложенной текстурой (3). Для нее изменяются координаты текстурами, чтобы отобразить эффект неровности поверхности. Пересчет текстурных координат происходит относительно вектора наблюдения. То есть вызывается командаglTexCoord2f(old_tex_x + tex_dx, old_tex_y + tex_dy),tex_dxиtex_dyберутся при подсчете вектора свига:tex_d = {tex_dx, tex_dy, tex_dz}. Вычисляется он следующим образом:tex_d = man_pos - plane_center, гдеman_pos- вектор координат месторасположения наблюдателя,plane_center- центральная точка текущей плоскости (вместо нее, для ускорения, можно взять одну из вершин рассматриваемой плоскости). Далееtex_dнормируется (представляется в единичный вектор) и далее все координаты домножаются на некоторое небольшое число (в зависимости от глобальной метрики сцены), которое и будет характеризовать расхождение, а значит и высоту шероховатости. Если указать это число достаточно большим, то будут видны просто две плоскости и никакого эффекта шероховатости создаваться не будет. В этом особенность этого метода: можно передать лишь небольшие ("невысокие") неровности, для других необходимо производить дополнительную триангуляцию.

Перед выводом третей (последней плоскости) необходимо установить следующие параметры OpenGL:

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

В итоге получается изображение, на котором виден "микрорельеф".

Расскажем теперь, как bumpmappingприменяется по отношению к моделированию водных поверхностей. Предположим, что необходимо моделировать большую водную поверхность, без видимых границ (граница - линия горизонта), на которой присутствуют лишь небольшие волны, то есть она достаточно "спокойна". Тогда можно не разбивать водную поверхность на множество плоскостей, а сделать одну большую плоскость, для которой применитьbumpmappingс динамически изменяемой картой поверхности. Обычно сразу загружается достаточное количество карт глубины (10-15), затем они меняют друг друга, в соответствие со временем изменения водной поверхности, а в конце происходит их зацикливание. Таким образом нам достаточно выводить только один полигон (то есть 3 - в нашей реализацииbumpmapping'а), а не разбивать поверхность на множество полигонов.

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

Соседние файлы в предмете Компьютерная Графика