You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

采样深度立方体贴图生成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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 00:59:51