1

シーンを 6 回レンダリングして、キューブマップの側面に配置しようとしています。これを 1 回のパスで実行できるジオメトリ シェーダーの学習に移る前に、まずこれを適切に実行したいと思います。コードは次のとおりです。

    void Scene::setupFBO()
    {
        glGenTextures(1, &cubemap);
        glBindTexture(GL_TEXTURE_CUBE_MAP,cubemap);
        glActiveTexture(GL_TEXTURE0);           
        const int size = 128;           
            // create the fbo
        glGenFramebuffers(1, &fbo);
        glBindFramebuffer(GL_FRAMEBUFFER, fbo);

        for(int i=0;i<6;i++)
        {
            glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB,
                size, size, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);

        }
        glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER,
        GL_LINEAR);
        glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER,
        GL_LINEAR);
        glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S,
        GL_CLAMP_TO_EDGE);
        glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T,
        GL_CLAMP_TO_EDGE);
        glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R,
        GL_CLAMP_TO_EDGE);

        // create the uniform depth buffer
        glGenRenderbuffers(1, &depthbuff);
        glBindRenderbuffer(GL_RENDERBUFFER, depthbuff);
        glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, size, size);
        //glBindRenderbuffer(GL_RENDERBUFFER, 0);
        GLenum drawBufs[] = {GL_COLOR_ATTACHMENT0};
        // attach it
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fbo);
        //glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X, cubemap, 0);
        glDrawBuffers(1, drawBufs);

        glBindFramebuffer(GL_FRAMEBUFFER, 0);    
        glBindTexture(GL_TEXTURE_CUBE_MAP, 0);

    }

    void Scene::pass1()
    {
        GLuint p = glGetSubroutineIndex(program->id,GL_FRAGMENT_SHADER,"pass1");
        glUniformSubroutinesuiv(GL_FRAGMENT_SHADER,1,&p);

        mat4 view;
        glBindFramebuffer(GL_FRAMEBUFFER, fbo);
        for(int i=0;i<6;i++)
        {
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, cubemap, 0);
            if(i==0) //X+
                cam->Update(vec3(0),vec3(10,0,0)); // position, target
            else if(i==1) //X-
                cam->Update(vec3(0),vec3(-10,0,0));
            else if(i==2) //Y+
                cam->Update(vec3(0),vec3(0,10,0));
            else if(i == 3) //....
                cam->Update(vec3(0),vec3(0,-10,0));
            else if(i == 4)
                cam->Update(vec3(0),vec3(0,0,10));
            else if(i == 5)
                cam->Update(vec3(0),vec3(0,0,-10));

            view = cam->getViewMat();
            for(int ii=1;ii<SHAPE_COUNT;ii++){
                shapes[ii]->setViewMat(view);
                shapes[ii]->Draw();
            }

        }
    }

    void Scene::pass2()
    {
        GLuint p = glGetSubroutineIndex(program->id,GL_FRAGMENT_SHADER,"pass2");
        glUniformSubroutinesuiv(GL_FRAGMENT_SHADER,1,&p);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glBindFramebuffer(GL_FRAMEBUFFER, 0);
        cam->Update(vec3(0,0,10),vec3(0));
        mat4 view = cam->getViewMat();
        for(int i=0;i<SHAPE_COUNT;i++){
            shapes[i]->setViewMat(view);
            (*shapes[i]).Draw();
        }
    }

void Scene::Draw(){
    pass1(); // Create the cubemap
    pass2(); // Draw the scene normally
}

IBL と反射/屈折に使用される静的キューブマップを実装した以前のプロジェクトのコードを変更しました。必要であると思われる場合は、シェーダー コードを提供します。この段階では、意味不明な部分のみがレンダリングされます。

最終結果 最終結果

実際のシーン 実際のシーン

更新 大きな四角形は、積み重ねられた変換を適用しなかった setViewMat 関数のバグの結果です。シーンのみをレンダリングするようになり、テクスチャは黒になります。AMD gDEBugger を使用して、結果のキューブマップを確認しましたが、これは黒だけです。したがって、最初のfboバインディングか、最初のパスで各面をどのようにレンダリングするかが問題だと思います。

4

1 に答える 1

0

OK、ようやく機能しました。setupFBO では、キューブマップをアンバインドするべきではありませんでした。とにかく、更新された pass1,2 コードを投稿しました。レンダリングは機能しますが、側面が予想どおりにマッピングされていないように見えるため、側面の順序付けに問題があります.X+、X-、....

 void Scene::pass1()
  {
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    GLuint p = glGetSubroutineIndex(program->id,GL_FRAGMENT_SHADER,"pass1");
    glUniformSubroutinesuiv(GL_FRAGMENT_SHADER,1,&p);
    glViewport(0,0,512,512);
    mat4 view, proj;
    proj = glm::perspective(90.0f, 1.0f, 1.0f, 500.0f);
    for(int i=0;i<6;i++)
    {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
       if(i==0)
          view = Camera::Update(vec3(0),vec3(1,0,0),vec3(0,1,0));// pos, target, up
       else if(i==1)
          view =  Camera::Update(vec3(0),vec3(-1,0,0),vec3(0,1,0));
       else if(i==2)
         view =  Camera::Update(vec3(0),vec3(0,1,0),vec3(0,0,1));
       else if(i == 3)
         view =  Camera::Update(vec3(0),vec3(0,-1,0),vec3(0,0,-1));
       else if(i == 4)
         view =  Camera::Update(vec3(0),vec3(0,0,1),vec3(0,1,0));
       else if(i == 5)
         view =  Camera::Update(vec3(0),vec3(0,0,-1),vec3(0,1,0));
        for(int ii=1;ii<SHAPE_COUNT;ii++){
            shapes[ii]->setProjMat(proj);
            shapes[ii]->setViewMatAndUpdate(view); // Empties the transformation stack, pushes the new view matrix and applies all the transformations again
            shapes[ii]->Draw();
                    //Reverts back to the original stack
            shapes[ii]->setViewMatAndUpdate(cam->getViewMat());
        }
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
            GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, cubemap,0);
     }
   }

void Scene::pass2()
{
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    GLuint p = glGetSubroutineIndex(program->id,GL_FRAGMENT_SHADER,"pass2");
    glUniformSubroutinesuiv(GL_FRAGMENT_SHADER,1,&p);
    glViewport(0,0,Constants::Instance()->gWidth,Constants::Instance()->gHeight);
    float  aspectRatio = 8.0f/6.0f;
    mat4 proj = cam->getProjMat();
    for(int i=0;i<SHAPE_COUNT;i++){
        shapes[i]->setProjMat(proj);
        (*shapes[i]).Draw();
    }
}

OK、立方体の各面を色分けすることで順序を理解しましたが、なぜこのようになっているのかわかりません。

if(i==1)
    view = Camera::Update(vec3(0),vec3(1,0,0),vec3(0,1,0));
else if(i==2)
    view =  Camera::Update(vec3(0),vec3(-1,0,0),vec3(0,1,0));
else if(i==4)
    view =  Camera::Update(vec3(0),vec3(0,1,0),vec3(0,0,1));
else if(i == 3)
    view =  Camera::Update(vec3(0),vec3(0,-1,0),vec3(0,0,-1));
else if(i == 0)
    view =  Camera::Update(vec3(0),vec3(0,0,1),vec3(0,1,0));
else if(i == 5)
    view =  Camera::Update(vec3(0),vec3(0,0,-1),vec3(0,1,0));
于 2015-03-06T20:09:40.543 に答える