3

我使用 GL_POINTS 在 OpenGL 中有一个简单的粒子效果。调用以下方法,按照从最远的粒子到最接近相机的最后一个粒子的顺序传递粒子:

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);
}

但是,在渲染时会出现一些伪影,如以下效果所示:artifacted image http://img199.imageshack.us/img199/9574/particleeffect.png

如果我禁用深度测试,问题就会消失,但我需要效果能够与场景的其他元素交互,根据深度出现在相同 GL_TRIANGLE_STRIP 元素的前面和后面。

4

2 回答 2

3

如果您的粒子已经排序,您可以像这样呈现:

  • 使用 GL WRITE DEPTH 渲染粒子但没有深度测试(我不记得确切的常量)
  • 使用深度测试渲染场景的其余部分。

这样,您一定会获得与漂亮粒子的场景交互。

于 2009-05-23T16:47:39.543 回答
2

注意:请在发布问题时指定您使用的 OpenGL 版本。这适用于任何 API。当您想要使用 alpha 混合渲染图元时,您不能启用深度写入。您需要绘制从后到前排序的混合图元。如果场景中有不透明对象,请先渲染它们,然后以从后到前的排序方式绘制透明图元,启用深度测试并禁用深度写入。

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();
    ...
}
于 2009-05-23T16:49:38.510 回答