代码之家  ›  专栏  ›  技术社区  ›  ICR

OpenGL中粒子效果的alpha透明度

  •  3
  • ICR  · 技术社区  · 15 年前

    我在OpenGL中使用gl_点有一个简单的粒子效果。以下称为,将粒子按顺序从距离摄影机最远的粒子传递到距离摄影机最近的粒子:

    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_三角形条的元素前面和后面。

    2 回复  |  直到 15 年前
        1
  •  3
  •   Raoul Supercopter    15 年前

    如果你的分词已经排序,你可以这样渲染:

    • 使用gl write depth呈现particle,但不进行深度测试(我不记得具体的常量)
    • 使用深度测试渲染场景的其余部分。

    这样,你就可以用好看的分割来进行场景交互。

        2
  •  2
  •   Mads Elvheim    15 年前

    注意:请指定在发布问题时使用的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();
        ...
    }
    
    推荐文章