1

プログラム可能なパイプライン (glsl を使用) を使用し、固定パイプラインを使用せずにボリューム レンダリングを実行したいと考えています。2 つのシェーダー プログラムを使用して 2 つのパスで実装しexitPointProgますrayCastProg。最初のパスは、レイキャスティングを行う次のパスでテクスチャとして使用されるキューブ バウンディング ボックスの出口ポイント (つまり背面) を取得することです。レイキャスティング ボリューム レンダリングを行うというアイデアは、ここから生まれました。プログラム可能なパイプラインと組み合わせた固定パイプラインでこれを実装したので、ほとんどのことを正しく行ったと思います。私を混乱させたのは、最初のフレームで結果を達成し、フラッシュで画面上の表示が完全に白くなったことです(glClearColor(1.0f, 1.0f, 1.0f, 1.0f). シェーダープログラムやFBOの切り替えに問題があるのではないかと思います。render() 関数で行うことは次のとおりです。

  1. 最初のパスでは、テクスチャがバインドされた fbo にレンダリングして、exitPointsシェーダー プログラムを使用してキューブ バウンディング ボックスの出口ポイントを取得しますexitPointProg
  2. 2ed パスで、シェーダーで使用される均一な sampler2D 変数として、exitPointsテクスチャー (にバインドGL_TEXTURE1) をシェーダー プログラムにマップしました。rayCastProgここにsetupFBOandrenderと 2 つのサブルーチンがありsetupFBO()ます: 関数:

    void SimpleRayCasting::setupFBO()
    {
        GLuint textureHandles[1];
        glGenTextures(1, textureHandles);
        entryPoints = textureHandles[0];
    
    
        glActiveTexture(GL_TEXTURE1);
        glBindTexture(GL_TEXTURE_2D, exitPoints);
        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
        glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA16F, width, height, 0, GL_RGBA, GL_FLOAT, NULL);
    
    
        GLuint depthRenderBuffer;
        glGenRenderbuffers(1, &depthRenderBuffer);
        glBindRenderbuffer(GL_RENDERBUFFER, depthRenderBuffer);
        glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height);
    
        glGenFramebuffers(1, &frameBuffer);
        glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 
                        exitPoints, 0/* level */);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 
                        depthRenderBuffer);
    
    
        checkFramebufferState(__FILE__, __LINE__);
        GLenum drawbufs[] = {GL_COLOR_ATTACHMENT0};
        glDrawBuffers(1, drawbufs);
        glBindFramebuffer(GL_FRAMEBUFFER,0);
    }
    

    関数render():

    void SimpleRayCasting::render()
    {
        getExitPoints();
        GLUtils::checkForOpenGLError(__FILE__,__LINE__);
        rayCasting();
        GLUtils::checkForOpenGLError(__FILE__,__LINE__);
    }
    

    関数getExitPoints():

    void SimpleRayCasting::getExitPoints() 
    {
        // render to the texture
        glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
        glEnable(GL_DEPTH_TEST);
        glViewport(0, 0, width, height);
        // checkFramebufferState(__FILE__, __LINE__); 
        glClearColor(0.2f, 0.2f, 0.2f, 1.0);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        exitPointsProg.use();
        // note that the model will recalculated.
        model = mat4(1.0f);
        model *= glm::rotate(angle , vec3(0.0f,1.0f,0.0f));
        model *= glm::rotate(90.0f, vec3(1.0f, 0.0f, 0.0f));
        model *= glm::translate(vec3(-0.5f, -0.5f, -0.5f));
        view = glm::lookAt(vec3(0.0f,0.0f,2.0f), vec3(0.0f,0.0f,0.0f), vec3(0.0f,1.0f,0.0f));
        projection = mat4(1.0f);
        projection = glm::perspective(60.0f, (float)width/(float)height,0.01f, 400.0f);   
        setMatrices(exitPointsProg);
        glEnable(GL_CULL_FACE);
        glCullFace(GL_FRONT);
        drawBoundBox();
        glDisable(GL_CULL_FACE);
        glBindFramebuffer(GL_FRAMEBUFFER, 0);
    }
    

    関数rayCasting:

    void SimpleRayCasting::rayCasting()
    {
        // Directly render to the screen
        glBindFramebuffer(GL_FRAMEBUFFER, 0);
        glEnable(GL_DEPTH_TEST);
        glViewport(0, 0, width, height);
        glClearColor(1.0f, 1.0f, 1.0f, 1.0);
        glClear(GL_COLOR_BUFFER_BIT |  GL_DEPTH_BUFFER_BIT);
        rayCastProg.use();
        model = mat4(1.0f);
        model *= glm::rotate(angle, vec3(0.0f,1.0f,0.0f));
        model *= glm::rotate(90.0f, vec3(1.0f, 0.0f, 0.0f));
        model *= glm::translate(vec3(-0.5f, -0.5f, -0.5f));
        view = glm::lookAt(vec3(0.0f,0.0f,2.0f), vec3(0.0f,0.0f,0.0f), vec3(0.0f,1.0f,0.0f));
        projection = mat4(1.0f);
        projection = glm::perspective(60.0f, (float)width/(float)height,0.01f, 400.0f);   
        setMatrices(rayCastProg);
        rayCastProg.setUniform("StepSize", stepSize);
        glActiveTexture(GL_TEXTURE1);
        glBindTexture(GL_TEXTURE_2D, exitPoints);
        rayCastProg.setUniform("ExitPoints", 1);
        glActiveTexture(GL_TEXTURE4);
        glBindTexture(GL_TEXTURE_3D, volume_to);
        rayCastProg.setUniform("VolumeTex", 4);
        glActiveTexture(GL_TEXTURE5);
        glBindTexture(GL_TEXTURE_1D, transferFunc_to);
        rayCastProg.setUniform("TransferFunc", 5);
        glEnable(GL_CULL_FACE);
        glCullFace(GL_BACK);
        drawBoundBox();
        glDisable(GL_CULL_FACE);
        glBindFramebuffer(GL_FRAMEBUFFER, 0);
    }
    

    Qt で QGLWidget から継承したクラスを使用しています。先に述べたように、最初のフレームだけで正しい結果が得られ、すぐにフラッシュして完全に白くなりました。これのどこが悪いのかわからないのですが、シェーダープログラムの切り替えかFBOの事で何か問題があるのでしょうか?私はこれに長い間取り組んできましたが、それを理解することはできません。

編集して 、FBOで複数のglslシェーダープログラムを使用する方法を示すデモまたはチュートリアルはありますか?

4

0 に答える 0