Альфа-прозрачность с эффектами частиц в OpenGL - PullRequest
3 голосов
/ 23 мая 2009

У меня есть простой эффект частиц в 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 в зависимости от глубины.

Ответы [ 2 ]

3 голосов
/ 23 мая 2009

Если ваши частицы уже отсортированы, вы можете сделать так:

  • Визуализация частиц с помощью GL WRITE DEPTH, но без проверки глубины (я не помню точно, константы)
  • Визуализация остальной части сцены с помощью теста глубины.

Таким образом, вы точно получите взаимодействие сцены с красивыми частицами.

2 голосов
/ 23 мая 2009

Примечание. Укажите, какую версию 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();
    ...
}
...