OpenGL в Delphi

       

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




Реализовано все тривиально - у всех объектов, присутствующих на сцене, оптические свойства материала заданы с единичным значением альфа-компонента, для сферы это значение равно 0. 5. При вращении сферы на ее поверхности появляется узор, который портит всю картину. Эта проблема очень распространена, и новички часто натыкаются на нее. Связана она с наложением передней и задней полупрозрачных поверхностей сферы и вообще любой замкнутой полупрозрачной поверхности.
В этом разделе уже был пример с полупрозрачной сферой, где такой проблемы не возникало, но там сфера не вращалась, и мы всегда наблюдали ее с выгодной точки зрения. Если вы посмотрите проект из подкаталога Ex49, в котором та же полупрозрачная сфера вращается по всем осям, то обнаружите, что в некоторых положениях появляется паразитный узор.
Самым простым решением будет не воспроизводить внутреннюю часть сферы, но если по сценарию внутренняя поверхность изготовлена из другого материала, мы этого не увидим. To есть сфера не получится действительно полупрозрачной, как бы изготовленной из матового стекла. В проекте из подкаталога Ex50 предложено более изящное решение: вначале воспроизводится внутренняя поверхность сферы, а затем внешняя:

glEnable(GL_BLEND); // включаем смешение
glEnable(GL_CULL_FACE); // включаем отсечение сторон полигонов
glCullFace(GL_FRONT); // не воспроизводить лицевую поверхность сферы
draw_sphere(Angle); // вывести заднюю поверхность сферы
glCullFace(GL_BACK); // не воспроизводить заднюю поверхность сферы
draw_sphere(Angle); // вывести переднюю поверхность сферы
glDisable(GL_CULL_FACE); // отключить сортировку поверхностей
glDisable(GLJ3LEND); // отключить режим смешения

Замечание
Решение хорошее, но для простых задач можно все-таки воспроизводить только внешнюю сторону объекта, так будет быстрее

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

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

Учитывая то, что мы уже сталкивались с проблемой замкнутых полупрозрачных объектов, сортируем передние и задние поверхности и конуса, и сферы:

glEnable(GL_BLEND);
glEnable(GL_CULL_FACE);
// рисуем заднюю поверхность конуса и сферы
glCullFace(GL_FRONT);
draw_cone;
draw_sphere(Angle);
// рисуем переднюю поверхность конуса и сферы
glCullFace(GL_BACK);
draw_cone;
draw_sphere(Angle);
glDisable(GL_CULL_FACE);
glDisable(GL_BLEND);

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



Содержание раздела