Скачиваний:
115
Добавлен:
23.02.2015
Размер:
702.98 Кб
Скачать
    1. Зеркальные отражения

В этом разделе мы рассмотрим алгоритм построения отражений от плоских объектов. Такие отражения придают бóльшую достоверность построенному изображению и их относительно легко реализовать.

Алгоритм использует интуитивное представление полной сцены с зеркалом как составленной из двух: «настоящей» и «виртуальной» – находящейся за зеркалом. Следовательно, процесс рисования отражений состоит из двух частей: 1) визуализации обычной сцены и 2) построения и визуализации виртуальной. Для каждого объекта «настоящей» сцены строится его отраженный двойник, который наблюдатель и увидит в зеркале.

Рис. 9 Зеркальное отражение

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

Упрощенный вариант алгоритма создания плоского отражения состоит из следующих шагов:

  1. Рисуем сцену как обычно, но без объектов-зеркал.

  2. Используя буфер маски, ограничиваем дальнейший вывод проекцией зеркала на экран.

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

Эта последовательность действий позволит получить убедительный эффект отражения.

Рассмотрим этапы более подробно:

Сначала необходимо нарисовать сцену как обычно. Не будем останавливаться на этом этапе подробно. Заметим только, что, очищая буферы OpenGLнепосредственно перед рисованием, нужно не забыть очистить буфер маски:

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT| GL_STENCIL_BUFFER_BIT);

Во время визуализации сцены лучше не рисовать объекты, которые затем станут зеркальными.

На втором этапе необходимо ограничить дальнейший вывод проекцией зеркального объекта на экран.

Для этого настраиваем буфер маски и рисуем зеркало

glEnable(GL_STENCIL_TEST);

/* условие всегда выполнено и значение в буфере будет равно 1*/

glStencilFunc(GL_ALWAYS, 1, 0);

glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);

RenderMirrorObject();

В результате мы получили:

  • в буфере кадра – корректно нарисованная сцена, за исключением области зеркала;

  • в области зеркала (там, где мы хотим видеть отражение) значение буфера маски равно 1.

На третьем этапе нужно нарисовать сцену, отраженную относительно плоскости зеркального объекта.

Сначала настраиваем матрицу отражения. Матрица отражения должна зеркально отражать всю геометрию относительно плоскости, в которой лежит объект-зеркало. Ее можно получить, например, с помощью такой функции (попробуйте получить эту матрицу самостоятельно в качестве упражнения):

void

reflectionmatrix(GLfloat reflection_matrix[4][4], GLfloat plane_point[3], Glfloat plane_normal[3])

{

GLfloat* p;

GLfloat* v; float pv;

GLfloat* p = (Glfloat*)plane_point; Glfloat* v = (Glfloat*)plane_normal;

float pv = p[0]*v[0]+p[1]*v[1]+p[2]*v[2];

reflection_matrix[0][0] = 1 - 2 * v[0] * v[0];

reflection_matrix[1][0] = - 2 * v[0] * v[1];

reflection_matrix[2][0] = - 2 * v[0] * v[2];

reflection_matrix[3][0] = 2 * pv * v[0];

reflection_matrix[0][1] = - 2 * v[0] * v[1];

reflection_matrix[1][1] = 1- 2 * v[1] * v[1];

reflection_matrix[2][1] = - 2 * v[1] * v[2];

reflection_matrix[3][1] = 2 * pv * v[1];

reflection_matrix[0][2] = - 2 * v[0] * v[2];

reflection_matrix[1][2] = - 2 * v[1] * v[2];

reflection_matrix[2][2] = 1 - 2 * v[2] * v[2];

reflection_matrix[3][2] = 2 * pv * v[2];

reflection_matrix[0][3] = 0;

reflection_matrix[1][3] = 0;

reflection_matrix[2][3] = 0;

reflection_matrix[3][3] = 1;

}

и рисуем сцену еще раз (без зеркальных объектов)

glPushMatrix();

glMultMatrixf((float *)reflection_matrix);

RenderScene();

GlPopMatrix();

Наконец, отключаем маскирование

glDisable(GL_STENCIL_TEST);

После этого можно опционально еще раз вывести зеркальный объект, например, с альфа-смешением – для создания эффекта замутнения зеркала и т.д.

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

Соседние файлы в папке Программирование графических приложений