采样深度立方体贴图生成360°视图时出现空白2D图像问题
问题:采样深度立方体贴图生成360°视图得到空白图像
目标
通过给定的angle_step,使用球面坐标采样深度立方体贴图,生成场景的360°视图。其中x代表水平方位角,y代表仰角,每个像素存储深度值。
问题现象
无任何报错,但最终仅得到一张空白2D图像。无法确定无输出的原因
补充说明
depth_cube_tex是预先生成的包含深度信息的深度立方体贴图quad_vao是标准化设备坐标下覆盖整个屏幕的两个三角形
现有采样流程代码
# SAMPLING CUBEMAP ################## glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS) # angular ranges and step angle_step = 0.025 hangle = np.array([0, 360, angle_step], dtype=np.float32) vangle = np.array([-90, 90, angle_step], dtype=np.float32) width = int( (hangle[1]-hangle[0]) / hangle[2]) height = int( (vangle[1]-vangle[0]) / hangle[2]) # create scene fbo scene_buffer = glGenFramebuffers(1) glBindFramebuffer(GL_FRAMEBUFFER, scene_buffer) # generate color depth buffer and attache it to scene fbo color_depth = glGenTextures(1) glBindTexture(GL_TEXTURE_2D, color_depth) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_FLOAT, None) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color_depth, 0) # send information to sampling shader cubemap_sampling_shader.use() cubemap_sampling_shader.set_uniform_int('depth_cube', depth_cube_tex) cubemap_sampling_shader.set_uniform_vec3('display_size', glm.vec2(width,height)) cubemap_sampling_shader.set_uniform_float('angle_step', angle_step) #draw onto my scene buffer glBindVertexArray(quad_vao) glBindTexture(GL_TEXTURE_2D, color_depth) glDrawArrays(GL_TRIANGLES, 0, 6) glBindVertexArray(0) # save output ? zbuffer = glReadPixelsf(0, 0, width, height, GL_RED, GL_FLOAT) zbuffer = zbuffer.reshape((height, width)) np.save('Scene', np.flipud(zbuffer)) glBindFramebuffer(GL_FRAMEBUFFER, 0) #scene_buffer
现有着色器代码
顶点着色器
#version 330 core layout (location = 0) in vec2 aPos; void main() { gl_Position = vec4(aPos.x, aPos.y, 0.0f, 1.0f); }
片元着色器
#version 330 core uniform samplerCube depth_cube; uniform float angle_step; uniform vec2 display_size; // width, height of display out float depth; void main() { // psi is the horizontal deviation angle float psi = (gl_FragCoord.x - display_size.x / 2 ) * radians(angle_step); // theta is the vertical deviation angle float theta = (gl_FragCoord.y - display_size.y / 2 ) * radians(angle_step); // create sampling direction vector float x = sin(theta) * sin(psi); float z = cos(theta) * sin(psi); float y = cos(theta); depth = texture(depth_cube,vec3(x,y,z)).s; }
问题分析与修复方案
1. FBO纹理格式不匹配
片元着色器输出单通道float深度值,但创建纹理时使用GL_RGB三通道格式,导致深度值无法正确存储,读取后为空白。
修复:改用单通道浮点纹理格式,并添加FBO完整性检查:
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, width, height, 0, GL_RED, GL_FLOAT, None) # 检查FBO是否初始化成功 if glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE: print("FBO初始化失败!")
2. Uniform传递类型错误
代码用set_uniform_vec3传递vec2类型的display_size,导致着色器获取的尺寸值错误,角度计算完全偏离。
修复:改用vec2类型传递:
cubemap_sampling_shader.set_uniform_vec2('display_size', glm.vec2(width,height))
3. 球面坐标转笛卡尔坐标计算错误
原片元着色器的方向向量计算逻辑错误,导致采样方向不符合球面坐标规则,无法正确采样立方体贴图。
修复:修正方向向量计算(调整水平角度范围为0~360°):
void main() { // 水平方位角psi:0~360° float psi = gl_FragCoord.x * radians(angle_step); // 仰角theta:-90~90° float theta = (gl_FragCoord.y - display_size.y / 2) * radians(angle_step); // 正确的球面坐标转笛卡尔坐标 float x = cos(theta) * sin(psi); float y = sin(theta); float z = cos(theta) * cos(psi); depth = texture(depth_cube, vec3(x, y, z)).r; }
4. 绘制时多余的纹理绑定
绘制到FBO时绑定作为颜色附件的color_depth纹理属于无效操作,可能干扰采样流程。
修复:移除绘制时的纹理绑定代码:
# 移除该行:glBindTexture(GL_TEXTURE_2D, color_depth)
内容的提问来源于stack exchange,提问作者Marc
相关产品推荐
相关产品推荐

