Главная -
Статьи -
Проекты -
Ссылки -
Скачать -
Из гельминтов -
Юмор, приколы -
Почитать -
Обо мне -
Мысли -
Гостевая -

Расширение EXT_fog_coord в OpenGL

Хотя OpenGL поддерживает задание тумана, но используемая для этого модель предполагает, что все пространство равномерно заполнено туманом с заданной неизменяемой плотностью.

Поэтому реализовать другие варианты объемного тумана (например слой тумана заданной толщины над поверхностью Земли) этим способом невозможно.

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

При таком подходе степень "затуманивания" каждого пиксела грани получается путем билинейной интерполяции заданных в вершинах грани значений.

Данное расширение вводит две новых функции (glFogCoord и glFogCoordPointerEXT) и ряд констант. Интерфейс первой из вводимых функций задается следующим образом:

	void glFogCoordf ( float fogFactor );
Для непосредственного использования данного расширения необходимо настроить использование объемного тумана следующим образом:

	glEnable ( GL_FOG                 );
	glFogi   ( GL_FOG_MODE, GL_LINEAR );
	glFogfv  ( GL_FOG_COLOR, fogColor );
	glFogf   ( GL_FOG_START, s        );
	glFogf   ( GL_FOG_END,   e        );
	glFogi   ( GL_FOG_HINT, GL_NICEST );
	glFogi   ( GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT );
Данный фрагмент когда устанавливает, что в качесвте величины затуманивания будут использованы явно заданные значения для каждой вершины.

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

В качестве спсоба вычисления точной степени затуманивания выбран линейный закон

t = (f-s)/(e-s)

Значения затуманивая можно либо явно задавать в каждой вершине при помощи функции glFogCoordf или же можно воспользоваться для этого вершинными массивами:


     glEnableClientState  ( GL_FOG_COORDINATE_ARRAY );
     glFogCoordPointerEXT ( GL_FLOAT, 0, fogValues );

     ....

     glDisableClientState ( GL_FOG_COORDINATE_ARRAY );
Рассотрим теперь каким образом можно явно вычислить степень затуманивания для заданной вершины. Рассмотрим случай, когда у нас имеется слой тумана постоянной плотности, расположенный в диапазоне y0 <= y <= y1

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

Точное вычисление пути внутри слоя тумана

Рис. 1. Точное вычисление пути внутри слоя тумана.

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

В нашем случае в качестве такой плоскости выступает ось Оу.

Приближенное вычисление пути внутри слоя тумана по сравнению с точным

Рис. 2. Приближенное вычисление по сравнению с точным.

Для вычисления этого достаточно (в случае, когда камеры расположена выше полосы тумана), просто взять разницу у-координаты самой точки Р и y1, умножив ее на плотность тумана.

В случае использования закона GL_LINEAR, вместо вычитания и задания плотности тумана можно просто задать соответствующим образом величины s и e. В этом случае в качестве величины s будет выступать y1, а величина е будет равна плотности тумана плюс y1.

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

Все что, для этого следует сделать - это получиь текущую model-view матрицу при помощи glGet и для каждой вершины найти ее у-координату посмле преобразования этой матрицей.

Вращающийся тор в слое тумана

Рис3. Тор в слое тумана.

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


Copyright © 2004 Алексей В. Боресков

Используются технологии uCoz