OpenGL渲染到立方体贴图

时间:2016-06-20 18:53:43

标签: opengl rendering render-to-texture

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

右下半部分的调试视图显示了我在立方图中渲染的内容。

我尝试了许多不同的组合来设置相机,但没有一个能给出任何合理的结果。我还将代码与几个样本进行了比较,以实现动态立方体贴图,但我仍然无法发现问题。我没想到接下来会尝试什么,所以欢迎任何帮助或建议。

绘制到立方体贴图功能:

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);
}

screenshot

1 个答案:

答案 0 :(得分:1)

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

// 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...
}

编辑:

在安德烈亚斯的评论之后,我进行了更多调查。

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

然而,lookAt错了。我将这个函数与几个资源进行了比较,并且肯定与bgfx's lookAt进行了比较,实际上,整个第三列应该反转符号。因此,我将视图矩阵的列乘以-1的变化仍然存在。

相关问题