0

シェーダーについてはわかりませんが、その概念の基本的な考え方は知っています。

深度ピーリングを実装する必要があるため、最初にシェーダーの世界に深く入り込む必要があるかどうか、または glDepthFunc をスマートに使用するだけでシェーダーなしで実装できるかどうかを知りたい..

4

1 に答える 1

1

はい、面倒ですが、GL_ARB_depth_texture と GL_ARB_shadow があればできます。

GL_ARB_occlusion_query は、ピーリングを停止するタイミングを決定できるため、非常に便利です。これがない場合でも実行できますが、ループを一定回数反復する必要があります。高すぎると時間とメモリが無駄になり、低すぎると視覚的なアーティファクトが発生する可能性があります。

このコードは、少し前にデプス ピーリング アルゴリズムをデバッグするために使用したテスト コードからハッキングされたものです。システム固有のものをすべて取り除き、疑似コードに置き換え、再構築を行ったので、コンパイルされるとは思わないでください。うまくいけば、あなたはアイデアを得ることができるはずです。

このアプローチを使用して順序に依存しない透明度を得るには、おそらく深度テクスチャのリストを作成してから、逆の順序でトラバースします。

[コード] bool DrawNthSurface(size_t パス) { GLboolean cached_stencil_test_enabled; GLboolean cached_alpha_test_enabled; GLboolean cached_depth_test_enabled; GLboolean cached_face_cull_enabled;

    glGetBooleanv(GL_STENCIL_TEST, &cached_stencil_test_enabled);
    glGetBooleanv(GL_ALPHA_TEST, &cached_alpha_test_enabled);
    glGetBooleanv(GL_DEPTH_TEST, &cached_depth_test_enabled);
    glGetBooleanv(GL_CULL_FACE, &cached_face_cull_enabled);

    if(HasShadow()) // Checks GL_ARB_shadow
    {
        return false; 
    }
    else
    {
        GLuint depthTexture(0);

        bool status(true);

        glEnable(GL_DEPTH_TEST);
        glDepthFunc(GL_LEQUAL);
        glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);

        // Draw geometry into the depth buffer.  No textures, shaders etc.
        //
        // This could easily be folded into next part by restructuring into 
        // do...while()
        status&= DrawSimpleGeometry();

        if(status)
        {
            // for transparency etc. you would build a list of these inside the 
            // loop.  For finding the nth surface we can recycle one.
            glGenTextures(1, &depthTexture);

            if(depthTexture)
            {
                glBindTexture(GL_TEXTURE_2D, depthTexture);

                glTexImage2D(GL_TEXTURE_2D, 0,
                             GL_DEPTH_COMPONENT, 
                             ctx->GetViewportWidth(), 
                             ctx->GetViewportHeight(), 0,
                             GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);


                // Set up texture unit.
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 
                                GL_NEAREST);
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, 
                                GL_NEAREST);
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, 
                                GL_CLAMP);
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, 
                                GL_CLAMP); 

                glEnable(GL_TEXTURE_2D);

                // Set up texture coord generation.  Should get bias from depth buffer 
                // precision.
                SetupTexGen(-0.004);

                // Set up shadow test.

                glTexParameteri(GL_TEXTURE_2D, 
                                GL_TEXTURE_COMPARE_MODE_ARB, 
                                        GL_COMPARE_R_TO_TEXTURE_ARB);

                glTexParameteri(GL_TEXTURE_2D, 
                                GL_TEXTURE_COMPARE_FUNC_ARB, 
                                GL_GREATER);

                glTexParameteri(GL_TEXTURE_2D, 
                                GL_DEPTH_TEXTURE_MODE_ARB, 
                                GL_ALPHA);

                glAlphaFunc(GL_GREATER, 0.5f);
                glEnable(GL_ALPHA_TEST); 

                for(size_t n=0;(n<passes) && status;n++)
                {
                    // Update depth texture.
                    glBindTexture(GL_TEXTURE_2D, depthTexture);
                    glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 
                                        ctx->GetViewportWidth(), 
                                        ctx->GetViewportHeight());


                    glClear(GL_DEPTH_BUFFER_BIT);

                    status&= DrawSimpleGeometry();
                }

                // deactivate shadow test.
                {
                    // Texgen
                    glDisable(GL_TEXTURE_GEN_S);
                    glDisable(GL_TEXTURE_GEN_T);
                    glDisable(GL_TEXTURE_GEN_R);
                    glDisable(GL_TEXTURE_GEN_Q);

                    // Texture unit
                    glDisable(GL_TEXTURE_2D);

                    // Shadow comparison
                    glDisable(GL_ALPHA_TEST); 
                }

                glDeleteTextures(1, &depthTexture);
            }
            else
            {
                status = false;
            }
        }

        // Restore some of the rendering state.
        if(cached_face_cull_enabled)
        {
            glEnable(GL_CULL_FACE);
            glCullFace(GL_BACK);
        }
        else
        {
            glDisable(GL_CULL_FACE);
        }

        glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);

        if(cached_face_cull_enabled)
        {
            glEnable(GL_CULL_FACE);
            glCullFace(GL_BACK);
        }
        else
        {
            glDisable(GL_CULL_FACE);
        }

        if(!cached_stencil_test_enabled)
        {
            glDisable(GL_STENCIL_TEST);
        }
        else
        {
            glEnable(GL_STENCIL_TEST);
        }

        if(!cached_alpha_test_enabled)
        {
            glDisable(GL_ALPHA_TEST);
        }
        else
        {
            glEnable(GL_ALPHA_TEST);
        }

        if(!cached_depth_test_enabled)
        {
            glDisable(GL_DEPTH_TEST);
        }
        else
        {
            glEnable(GL_DEPTH_TEST);
        }

        // FINALLY: Draw everything.
        if(status)
        {
            glDepthFunc(GL_EQUAL);
            status&= DrawAllGeometry();
        }

        glDepthFunc(GL_LEQUAL);

        return status;
    }
}

[/コード]

私見で最も難しいのは、texgenを正しくセットアップすることです。コードはとてもシンプルです。Zファイティングアーティファクトを避けるために、バイアスパラメータを含めました。

[コード] マトリックス CreateTextureMatrix(二重バイアス) { マトリックス射影、cmay;

    double tmp[16];

    glGetDoublev(GL_PROJECTION_MATRIX, tmp);

    projection = Matrix(tmp);

    Matrix bias_matrix(0.5, 0.0, 0.0,        0.0,
                       0.0, 0.5, 0.0,        0.0,
                       0.0, 0.0, 0.5,        0.0,
                       0.5, 0.5, 0.5 + bias, 1.0);


    return (projection * bias_matrix);
}

void SetupTexGen(double bias)
{
    Matrix texmat;
    Matrix mv, imv;

    {
        double tmp[16];
        glGetDoublev(GL_MODELVIEW_MATRIX, tmp);
        mv = Matrix(tmp);

        imv = mv.GetInverse();
    }

    glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
    glTexGendv(GL_S, GL_EYE_PLANE, imv.Row(0));
    glEnable(GL_TEXTURE_GEN_S);

    glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
    glTexGendv(GL_T, GL_EYE_PLANE, imv.Row(1));
    glEnable(GL_TEXTURE_GEN_T);

    glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
    glTexGendv(GL_R, GL_EYE_PLANE, imv.Row(2));
    glEnable(GL_TEXTURE_GEN_R);

    glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
    glTexGendv(GL_Q, GL_EYE_PLANE, imv.Row(3));
    glEnable(GL_TEXTURE_GEN_Q);

    texmat = CreateTextureMatrix(bias);

    glMatrixMode(GL_TEXTURE);
    glLoadIdentity();

    glMultMatrixd(texmat);
    glMatrixMode(GL_MODELVIEW);
}

[/コード]

HTH。

于 2014-05-30T17:55:40.533 に答える