Главная страница

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


Скачать 0.66 Mb.
НазваниеРуководство по работе с графической библиотекой OpenGL. Руководство разработано с учетом опыта чтения курса Компьютерная графика
Дата21.10.2022
Размер0.66 Mb.
Формат файлаdocx
Имя файла221937-83556.docx
ТипРуководство
#747097
страница14 из 30
1   ...   10   11   12   13   14   15   16   17   ...   30
G =


Zn

W

Точка, в которой луч, проведенный от источника света через данную точку Р, пересекает плоскость G, определяется парамет­рами а и Ь, удовлетворяющими следующему уравнению:

8.2. Построение теней

105

{аР + bL)G = 0

Отсюда получаем: a(PG) + b(LG) = 0. Этому уравнению удо­влетворяют

a = (LG),b = -(PG)

Следовательно, координаты искомой точки S = (LG)P — (PG)L. Пользуясь ассоциативностью матричного произведения, получим

S = P[(LG)I-GL] (8.1)

где / — единичная матрица.

Матрица (LG)I — GL используется для получения теней на произвольной плоскости.

Рассмотрим некоторые аспекты практической реализации данного метода с помощью OpenGL.

Предположим, что матрица floorShadow была ранее получена нами из формулы (LG)I — GL. Следующий код с ее помощью строит тени для заданной плоскости:

/* Визуализируем сцену в обычном режиме. */ RenderGeometry () ;

/* Делаем тени полупрозрачными с использованием

смешивания цветов(blending) */ glEnable (GL_BLEND) ;

glBlendFunc (GL_SRC_ALPHA,GL_ONE_MNUS_SRC_ALPHA); glDisable (GL_LIGHTING); glColor4f(0.0, 0.0, 0.0, 0.5); glPushMatrix ();

/* Проецируем тень */

glMultMatrixf ((GLfloat *) floorShadow);

/* Визуализируем сцену в проекции */

106 Глава 8. Графические алгоритмы на основе OFENGL

RenderGeometry (); glPopMatrix (); glEnable (GL_LIGHTING); glDisable(GL_BLEND);

Матрица floorShadow может быть получена из уравнения 8.1 с помощью следующей функции:

/* параметры:

plane — коэффициенты уравнения плоскости lightpos — координаты источника света возвращает: matrix — результирующая матрица

*/

void shadowmatrix( GLfloat matrix [4] [4] ,

GLfloat plane [4] , GLfloat lightpos [4])

{

GLfloat dot ;

dot = plane [0] * lightpos [0] +

plane[l] * lightpos [1] +

plane[2] * lightpos [2] +

plane [3] * lightpos [3];



atrix

ol [

atrix

11 [

atrix

21 [

atrix

3] [

atrix

ol f

atrix

11 [

atrix

21 [

atrix

3] [

atrix

ol f

atrix

11 [

atrix

21 [

atrix

31 f

0] = dot

0] = O.f

0] = O.f

01 = O.f

] = O.f dot O.f O.f

O.f O.f dot O.f

lightpos lightpos lightpos lightpos

lightpos lightpos lightpos lightpos

lightpos lightpos lightpos lightpos

*

plane

0]

*

plane

lj

*

plane

2J

*

plane

3J

*

plane

o]

*

plane

lj

*

plane

2J

*

plane

3J

*

plane

o]

*

plane

lj

*

plane

2J

*

plane

3|




8.2. Построение теней

107

matrix [0][3] = O.f - lightpos [3] * plane[0]

matrix[l][3] = O.f - lightpos [3] * plane [1]

matrix [2][3] = O.f - lightpos [3] * plane[2]

matrix [3][3] = dot - lightpos [3] * plane [3]

}


Заметим, что тени, построенные таким образом, имеют ряд недостатков:

  • Описанный алгоритм предполагает, что плоскости беско­нечны, и не отрезает тени по границе. Например, если неко­торый объект отбрасывает тень на стол, она не будет отсе­каться по границе, и, тем более, «заворачиваться» на боко­вую поверхность стола.

  • В некоторых местах теней может наблюдаться эффект «двойного смешивания» (rcblcnding), т.е. темные пятна в тех участках, где спроецированные треугольники перекры­вают друг друга.

  • С увеличением числа поверхностей сложность алгоритма резко увеличивается, т.к. для каждой поверхности нужно заново строить всю сцену, даже если проблема отсечения теней по границе будет решена.

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

Имеется решение первой и второй проблемы. Для этого ис­пользуется буфер маски (см. п. 7.2).

Итак, задача — отсечь вывод геометрии (тени) по границе некоторой произвольной области и избежать «двойного смеши-

108 Глава 8. Графические алгоритмы на основе OFENGL

вания». Общий алгоритм решения с использованием буфера мас­ки таков:

  1. очищаем буфер маски значением 0;

  2. отображаем заданную область отсечения, устанавливая значения в буфере маски в 1;

  3. рисуем тени в тех областях, где в буфере маски установ­лены значения; если тест проходит, устанавливаем в эти области значение 2.

Теперь рассмотрим эти этапы более подробно. 1.

/* очищаем буфер маски*/

glClearStencil(OxO)

glClear (GL_STENCIL_BUFFER_BIT);

/* включаем тест */

gl En able (GL_STENCIL_TEST);

1   ...   10   11   12   13   14   15   16   17   ...   30


написать администратору сайта