【问题标题】:OpenGL rendering to cubemapOpenGL 渲染到立方体贴图
【发布时间】:2016-06-20 18:53:42
【问题描述】:

我正在尝试渲染到立方体贴图。正在渲染的场景是地形。 我使用经纬度调试显示来查看某个立方体贴图中的内容。 左下角的两个调试视图是只显示方向的虚拟立方体贴图和一个带有真实图片的立方体贴图。

右下半部分的调试视图显示了我在我所追求的立方体贴图中呈现的内容。

我尝试了许多不同的组合来设置相机,但没有一个给出任何合乎逻辑的结果。我还将代码与几个用于实现动态立方体贴图的示例进行了比较,但我仍然无法发现问题。我不知道下一步该尝试什么,因此欢迎任何帮助或建议。

绘制到立方体贴图函数:

void Draw(GLuint cubemap, glm::ivec2 res, glm::vec3 position)
{

    glBindFramebuffer(GL_FRAMEBUFFER, fbo);

    glBindRenderbuffer(GL_RENDERBUFFER, rb);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, res.x, res.y);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rb);

    // camera
    glm::mat4 p = glm::perspective(90.0f, 1.0f, 0.01f, 10.0f);
    glm::mat4 v;

    glm::vec3 targets[6] = {
        glm::vec3(+1.0f, 0.0f, 0.0f),
        glm::vec3(-1.0f, 0.0f, 0.0f),
        glm::vec3(0.0f, +1.0f, 0.0f),
        glm::vec3(0.0f, -1.0f, 0.0f),
        glm::vec3(0.0f, 0.0f, +1.0f),
        glm::vec3(0.0f, 0.0f, -1.0f)
    };
    glm::vec3 ups[6] = {
        glm::vec3(0.0f, 1.0f, 0.0f),
        glm::vec3(0.0f, 1.0f, 0.0f),
        glm::vec3(0.0f, 0.0f, 1.0f),
        glm::vec3(0.0f, 0.0f, -1.0f),
        glm::vec3(0.0f, 1.0f, 0.0f),
        glm::vec3(0.0f, 1.0f, 0.0f)
    };

    // render
    for (int i = 0; i < 6; i++)
    {
        glViewport(0, 0, res.x, res.y);
        // setup target face
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, cubemap, 0);
        // setup camera
        v = glm::lookAt(position, position + targets[i], ups[i]);
        // draw
        DrawTerrain(terrain.heightmap, terrain.m, v, p);    // model, view, projection matrices
    }
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
}

【问题讨论】:

    标签: opengl rendering render-to-texture


    【解决方案1】:

    矩阵错误。在对值进行了非常彻底的检查之后,glm 返回的值对于投影矩阵和视图矩阵都是不正确的。我会看看我是否会报告错误修复请求,但现在,这里是实际修复矩阵的代码。

    // projection matrix (fov = 90 degrees, aspect = 1.0)
    glm::mat4 p;
    float n = 0.1f, f = 2.0f; // near and far
    p[0][0] = 1.0f;
    p[1][1] = 1.0f;
    p[2][2] = -f / (f - n);
    p[2][3] = -1.0f;
    p[3][2] = -(f*n) / (f - n);
    
    glm::vec3 targets[6] = {
        glm::vec3(+1.0f, 0.0f, 0.0f),
        glm::vec3(-1.0f, 0.0f, 0.0f),
        glm::vec3(0.0f, +1.0f, 0.0f),
        glm::vec3(0.0f, -1.0f, 0.0f),
        glm::vec3(0.0f, 0.0f, +1.0f),
        glm::vec3(0.0f, 0.0f, -1.0f)
    };
    glm::vec3 ups[6] = {
        glm::vec3(0.0f, 1.0f, 0.0f),
        glm::vec3(0.0f, 1.0f, 0.0f),
        glm::vec3(0.0f, 0.0f, -1.0f),
        glm::vec3(0.0f, 0.0f, 1.0f),
        glm::vec3(0.0f, 1.0f, 0.0f),
        glm::vec3(0.0f, 1.0f, 0.0f)
    };
    for(int i=0; i<6; ++i)
    {
        // view matrix
        v = glm::lookAt(position, position + targets[i], ups[i]);
        v[0][2] *= -1.0f;
        v[1][2] *= -1.0f;
        v[2][2] *= -1.0f;
        v[3][2] *= -1.0f;   
        // render...
    }
    

    编辑:

    在 Andreas 的 cmets 之后,我进行了更多调查。

    glm::perspective 需要以弧度为单位的 FOV,但由于每个使用该函数的示例都用度数调用它,所以我从来没有真正怀疑过它。在检查scrathapixel 之后,我确信透视矩阵是正确的(即使行列式是负数)。所以,FOV 是弧度的,这是我的错误。

    但是,lookAt 是错误的。我在多个资源中比较了该函数,并且肯定与bgfx's lookAt 进行了比较,实际上,整个第三列的符号应该颠倒了。因此,我将视图矩阵的该列与 -1 相乘的变化仍然存在。

    【讨论】:

    • 好吧,glm 只是标题,因此您可以轻松地自己修复它,而不是“请求修复”。 perspective 几乎是 gluPerspective 的 1:1 副本,这是一个非常简单的函数,所以我有点困惑,怎么可能存在错误。
    • 查看p[2][2] 值我怀疑您可能不知道z 轴指向相机,而不是远离相机。 x轴向右,y轴向上,所以如果坐标系应该是右手的,z轴需要指向相机。但是,您的矩阵有一个负行列式,这是错误的。
    • @AndreasHaferburg 我已经进一步编辑了答案。
    • glm::perspective() 的困难在于它曾经是度数,除非您使用 GLM_FORCE_RADIANS 定义。但现在默认为弧度。因此,您找到的任何 GLM 示例都可以使用。谷歌总是提取旧的 GLM 文档而不是最新的(希望他们使用 robots.txt 来解决这个问题)这一事实并没有帮助。 Google result (0.9.4)Current at the time of posting (0.9.9)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-21
    相关资源
    最近更新 更多