opengl 创建深度立方体[复制]

b5lpy0ml  于 2023-08-04  发布在  其他
关注(0)|答案(1)|浏览(158)

此问题在此处已有答案

How to correctly make a depth cubemap for shadow mapping?(1个答案)
Omnidirectional shadow mapping with depth cubemap(2个答案)
13天前关闭

此文章已更新

我使用以下两个stackoverflow引用ab,来帮助我构建一个具有场景深度值的立方体贴图。然而,我一直有多个问题,我不知道如何解决这些。
以下是我的代码:

def create_empty_cubemap(self) -> None:
    '''creates an empty cubemap ready to store depth values'''
    
    self.cube_tex = glGenTextures(1)
    glBindTexture(GL_TEXTURE_CUBE_MAP, self.cube_tex)
    
    for i in range(6):
        glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X+i, 0, GL_DEPTH_COMPONENT32F, 1024, 1024,
                        0, GL_DEPTH_COMPONENT, GL_FLOAT, None)

    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST) # or GL_LINEAR?
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE)

    glBindTexture(GL_TEXTURE_CUBE_MAP, 0)

字符集
我用来创建深度立方体贴图的函数如下,

def create_depthcube(self) -> None:
    '''Generates a cubemap with depth values'''

    #                   pitch, yaw, name
    rotation_dict = {0: [  0,  90,   'X+'],
                     1: [  0, -90,   'X-'],
                     2: [-90, 180,   'Y+'],
                     3: [ 90, 180,   'Y-'],
                     4: [  0, 180,   'Z+'],
                     5: [  0,   0,   'Z-']}
    
    self.cube_framebuffer = glGenFramebuffers(1)
    glBindFramebuffer(GL_FRAMEBUFFER, self.cube_framebuffer)
    # glClear(GL_DEPTH_BUFFER_BIT) # PROBLEM 1
    
    # use shader
    self.cubemap_shader.use()

    # generate a cubemap camera
    cubemap_camera = Camera(self.camera.position)
    cubemap_camera.width = 1024
    cubemap_camera.height = 1024
    cubemap_camera.zoom = 90.0

    # set viewport size to cubemap size
    glViewport(0, 0, 1024, 1024)

    # create a projection matrix
    projection = glm.perspective(glm.radians(90.0), 1.0, 0.1, 100)
    self.cubemap_shader.set_uniform_mat4('projection', projection)        

    # create depthcube by capturing depth 
    for i in range(6):

        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, 
                               GL_TEXTURE_CUBE_MAP_POSITIVE_X+i, self.cube_tex, 0) #PROBLEM2
        
        # all fine?
        if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE):
            raise RuntimeError("ERROR.FRAMEBUFFER. Framebuffer is not complete!")

        # clear colors and buffers
        glClearColor(0.1,0.1,0.1,0.1)
        glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT)

        # rotate camera
        cubemap_camera.pitch = rotation_dict[i][0]
        cubemap_camera.yaw =  rotation_dict[i][1]
        cubemap_camera.update_camera_vectors()
        
        # update view (look at matrix)?
        view = cubemap_camera.get_matrix_view()
        self.cubemap_shader.set_uniform_mat4('view',view)
        self.cubemap_shader.set_uniform_mat4('projection', projection)

        # render scene
        self.render()

    # unbind fbo
    glBindFramebuffer(GL_FRAMEBUFFER, 0)

    # reset viewport dimensions to display dimensions
    glViewport(self.camera.width, self.camera.height)


我的顶点着色器如下:

#version 330 core
layout (location = 0) in vec3 aPos;

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

void main()
{   
    gl_Position = projection * view * model * vec4(aPos, 1.0);
}


而且我的片段着色器是最小的

#version 330 core
// depth cubemap

out float fragmentDepth;

void main()
{    
    //fragmentDepth = gl_FragCoord.z;
}


现在,当我执行程序时,我在PROBLEM1位置得到一个错误,函数为glClear。如果我注解这一行,我会在PROBLEM2的位置得到一个错误,函数是“glFramebufferTexture2D”。这两个问题我都无法解释(尤其是问题1)。这是生成立方体贴图来存储场景深度的正确方法吗?我做错了什么?

2nc8po8w

2nc8po8w1#

最后,我的代码中有几个错误。首先,我的create_empy_cubemap()函数不正确。以下函数起作用,

def create_empty_cubemap(self) -> None:
    '''creates an empty cubemap ready to store depth values'''
    
    self.depth_map_fbo = glGenFramebuffers(1)
    glBindFramebuffer(GL_FRAMEBUFFER, self.depth_map_fbo)
    
    self.depth_tex = glGenTextures(1)
    glBindTexture(GL_TEXTURE_CUBE_MAP, self.depth_tex)
    
    for i in range(6):
        glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X+i, 0, GL_DEPTH_COMPONENT32, CM*1024, CM*1024,
                        0, GL_DEPTH_COMPONENT, GL_FLOAT, None)

    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST) # or GL_LINEAR?
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE)

    # attach depth texture to  fbo depth buffer
    glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, self.depth_tex,0)
    glDrawBuffer(GL_NONE)
    glReadBuffer(GL_NONE)
    glBindFramebuffer(GL_FRAMEBUFFER, 0)

字符集
其次,我的create_depthcube()函数经过一些细微的修改后非常相似,

def create_depthcube(self) -> None:
    '''Generates a cubemap with depth values'''

    #                   pitch, yaw, rel_pitch, rel_yaw, name, location
    rotation_dict = {0: [   0,  90,         0,      90, 'X+', 'Right'],
                        1: [   0, -90,         0,    -180, 'X-', 'Left'],
                        2: [  90, 180,       -90,      90, 'Y+', 'Top'],
                        3: [ -90, 180,       180,       0, 'Y-', 'Bottom'],
                        4: [   0,   0,       -90,     180, 'Z+', 'Back'],
                        5: [   0, 180,         0,    -180, 'Z-', 'Front']}
    
    # create empty cubemap
    self.create_empty_cubemap()
    
    # generate a cubemap camera
    cubemap_camera = Camera(self.camera.position)
    cubemap_camera.width = 1024
    cubemap_camera.height = 1024
    cubemap_camera.zoom = 90.0

    # # bind depth map buffer
    glBindFramebuffer(GL_FRAMEBUFFER, self.depth_map_fbo)
    
    # set viewport size to cubemap size
    glViewport(0, 0, 1024, 1024)

    # create a projection matrix
    projection = glm.perspective(glm.radians(90.0), 1.0, 0.1, 100)
    self.cubemap_shader.set_uniform_mat4('projection', projection)        

    # RENDER TO DEPTH CUBEMAP
    for i in range(6):

        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_POSITIVE_X+i,
                                self.depth_tex, 0)
        
        # all fine?
        if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE):
            raise RuntimeError("ERROR.FRAMEBUFFER. Framebuffer is not complete!")

        # clear colors and buffers
        glClearColor(0.1,0.1,0.1,0.1)
        glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT)

        # rotate camera
        cubemap_camera.pitch = rotation_dict[i][0] #0
        cubemap_camera.yaw =  rotation_dict[i][1] #1
        cubemap_camera.update_camera_vectors()
        
        # update view (lookat matrix)?
        view = cubemap_camera.get_matrix_view()
        self.cubemap_shader.set_uniform_mat4('view',view)

        # render scene
        self.render(self.cubemap_shader, cubemap_camera, projection)

        # #output ?
        zbuffer = glReadPixelsf(0, 0, 1024, 1024, GL_DEPTH_COMPONENT, GL_FLOAT)
        zbuffer = zbuffer.reshape((1024, 1024))
        np.save(f'{rotation_dict[i][5]}_cube', np.flipud(zbuffer))

    # unbind fbo
    glBindFramebuffer(GL_FRAMEBUFFER, 0)

    # reset viewport dimensions to display dimensions
    glViewport(0,0, self.camera.width, self.camera.height)


然而,更重要的是,当我想要渲染以生成立方体贴图时,我必须改变我原来的render()函数,以便能够接受不同的着色器,相机和投影矩阵作为参数。

相关问题