2009-05-23 12 views
3

GL_POINTSを使用してOpenGLで単純パーティクルエフェクトを使用しています。カメラからの最初の最後のカメラに最も近いものに粒子遠い側から順に粒子を通過され、呼び出される次しかしながら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の要素の前後に登場する、シーンの他の要素と対話できるようにする必要があります。

+1

コードについてのご意見です。 1.使用するものを有効にし、ブレンド関数を設定し、glPointParameterfvARBなどを呼び出してください。 2. draw_particles(const std ::)関数を呼び出します。ベクトル & v); 3.無効になど – ralphtheninja

答えて

3

あなたparticulesがすでにこのようにレンダリングすることができますソートされている場合は、次の

  • GLの書込み深度とparticuleが、ノーデプステストをレンダリング(私は正確に定数を覚えていない)
  • の残りの部分をレンダリング深度テスト付きのシーン。

このようにして、見た目のいいパーティクルとシーンのやりとりを確実にすることができます。

+0

が同時に答えを見つけることができたブレンドソリューションを使用することです。 glDepthMask(GL_FALSEを); は[パーティクルをレンダリング] glDepthMask(GL_TRUE); – ICR

+0

その他の方法で回避したいです。深さに基づいて破棄することはできますが、新しい深度を書き込むことによってブレンドされたプリミティブが互いに影響を及ぼすことはありません 実際の深度バッファの内容は、glClearまたは不透明なオブジェクトからのみです。 –

2

注:質問を投稿するときに使用する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(); 
    ... 
} 
関連する問題