Альфа-прозрачность с эффектами частиц в OpenGL
Вопрос
У меня есть простой эффект частиц в OpenGL с использованием GL_POINTS.Вызывается следующее: частицы передаются в порядке от частицы, наиболее удаленной от камеры первой, к частице, ближайшей к камере последней:
void draw_particle(particle* part) {
/* The following is how the distance is calculated when ordering.
* GLfloat distance = sqrt(pow(get_camera_pos_x() - part->pos_x, 2) + pow(get_camera_pos_y() - part->pos_y, 2) + pow(get_camera_pos_z() - part->pos_z, 2));
*/
static GLfloat quadratic[] = {0.005, 0.01, 1/600.0};
glPointParameterfvARB(GL_POINT_DISTANCE_ATTENUATION_ARB, quadratic);
glPointSize(part->size);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_POINT_SPRITE_ARB);
glEnable(GL_TEXTURE_2D);
glBegin(GL_POINTS);
glColor4f(part->r, part->g, part->b, part->a);
glVertex3f(part->pos_x, part->pos_y, part->pos_z);
glEnd();
glDisable(GL_BLEND);
glDisable(GL_POINT_SPRITE_ARB);
}
Однако при рендеринге происходит некоторое искажение, как можно видеть в следующем эффекте:искусственное изображение http://img199.imageshack.us/img199/9574/particleeffect.png
Проблемы исчезнут, если я отключу тестирование глубины, но мне нужно, чтобы эффекты могли взаимодействовать с другими элементами сцены, появляясь перед и за элементами одного и того же GL_TRIANGLE_STRIP в зависимости от глубины.
Решение
Если ваши частицы уже отсортированы, вы можете визуализировать их следующим образом :
- Отрисовка частицы с ГЛУБИНОЙ ЗАПИСИ GL, но без тестирования глубины (я не помню точно константы)
- Отрендерьте остальную часть сцены с помощью теста глубины.
Таким образом, вы обязательно получите взаимодействие сцены с симпатичными частицами.
Другие советы
Примечание:Пожалуйста, укажите, какую версию OpenGL вы используете, когда отправляете вопросы.Это относится к любому API.Если вы хотите визуализировать примитивы с альфа-смешиванием, вы не можете включить запись в глубину.Вам нужно нарисовать ваши смешанные примитивы отсортированными задом наперед.Если у вас есть непрозрачные объекты в сцене, сначала отрисовайте их, а затем отрисуйте свои прозрачные примитивы в отсортированном виде задом наперед с включенным тестированием глубины и отключенной записью глубины.
glEnable(GL_DEPTH_TEST);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_POINT_SPRITE);
glEnable(GL_CULL_FACE);
while(1)
{
...
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDisable(GL_BLEND);
glDepthMask(1);
RenderOpaque();
SortSprites();
glEnable(GL_BLEND);
glDepthMask(0);
DrawSprites();
...
}