当前位置: 首页 > 知识库问答 >
问题:

从OpenGL深度缓冲区获取世界坐标

梁丘权
2023-03-14

我正在使用pyBullet,它是bullet3物理引擎的python包装器,我需要从虚拟相机创建点云。
这个引擎使用基本的OpenGL渲染器,我可以从OpenGL深度缓冲区中获得值

img = p.getCameraImage(imgW, imgH, renderer=p.ER_BULLET_HARDWARE_OPENGL)
rgbBuffer = img[2]
depthBuffer = img[3]

现在我有了具有深度值的Width*Height数组。我怎么能从中得到世界坐标?我试图保存。ply点云和点(width,height,depthBuffer(width,height)),但这并不能创建看起来像场景中对象的点云。

我还尝试用远近平面校正深度:

depthImg = float(depthBuffer[h, w])
far = 1000.
near = 0.01
depth = far * near / (far - (far - near) * depthImg)

但结果也是一些奇怪的点云。如何从深度缓冲区的数据中创建逼真的点云?有可能吗?

我在C++中做了类似的事情,但在那里我使用了GLM::Unproject

for (size_t i = 0; i < height; i = i = i+density) {
        for (size_t j = 0; j < width; j = j = j+density) {

            glm::vec3 win(i, j, depth);
            glm::vec4 position(glm::unProject(win, identity, projection, viewport), 0.0);

编辑:

    for h in range(0, imgH, stepX):
       for w in range(0, imgW, stepY):
          depthImg = float(np.array(depthBuffer)[h, w])
          far = 1000.
          near = 0.01
          depth = far * near / (far - (far - near) * depthImg)
          win = glm.vec3(h, w, depthBuffer[h][w])
          position = glm.unProject(win, model, projGLM, viewport)
          f.write(str(position[0]) + " " + str(position[1]) + " " + str(depth) + "\n")

共有1个答案

巫马劲
2023-03-14

以下是我的解决方案。我们只需要知道视图矩阵和投影矩阵是如何工作的。PyBullet中有computeProjectionMatrixFOV和computeViewMatrix功能。http://www.songho.ca/opengl/gl_projectionmatrix.html和http://ksimek.github.io/2012/08/22/extrinsic/总之,point_in_world=inv(projection_matrix*viewMatrix)*NDC_pos

unproject是另一种解决方案

    stepX = 10
    stepY = 10        
    pointCloud = np.empty([np.int(img_height/stepY), np.int(img_width/stepX), 4])
    projectionMatrix = np.asarray(projection_matrix).reshape([4,4],order='F')
    viewMatrix = np.asarray(view_matrix).reshape([4,4],order='F')
    tran_pix_world = np.linalg.inv(np.matmul(projectionMatrix, viewMatrix))
    for h in range(0, img_height, stepY):
        for w in range(0, img_width, stepX):
            x = (2*w - img_width)/img_width
            y = -(2*h - img_height)/img_height  # be careful! deepth and its corresponding position
            z = 2*depth_np_arr[h,w] - 1
            pixPos = np.asarray([x, y, z, 1])
            position = np.matmul(tran_pix_world, pixPos)

            pointCloud[np.int(h/stepY),np.int(w/stepX),:] = position / position[3]
 类似资料:
  • 我有一个正在开发的OpenGL应用程序。正在渲染的地形似乎没有遵循深度缓冲规则,所以我猜我在某个地方搞砸了 我的代码中有GL11.glEnable(GL11.GL_CULL_FACE) 这是飞机在没有四边形在另一个后面的情况下的样子,所以即使没有z缓冲区,事情看起来也很正常。请注意,这是从“自上而下”的视图中,其中“相机”在飞机上方 而现在,从不同的角度看 离场景最远的四边形正在更靠近计算机的四边

  • 我对openGL渲染很陌生,无论我做什么,深度深度都不起作用。我显然已经启用了深度测试(),并且我清除了每一帧的缓冲区。 但是 openGL 不断显示最后在其他人面前渲染的对象... 你可以在我的github上看到我的代码。这是两个相关的文件:主循环。我的主循环在,渲染在。 我正在使用java和lwjgl。

  • 在DirectX中,您可以有单独的渲染目标和深度缓冲区,因此可以绑定渲染目标和一个深度缓冲区、执行一些渲染、移除深度缓冲区然后使用旧的深度缓冲区作为纹理进行更多渲染。 你会如何在opengl中做到这一点?根据我的理解,您有一个帧缓冲区对象,其中包含颜色缓冲区和可选的深度缓冲区。我不认为我可以同时绑定多个帧缓冲器对象,我是否必须在每次更改时(可能一帧几次)重新创建帧缓冲器对象?普通的 opengl

  • 我在游戏中使用延迟渲染器。因此,第一个渲染过程是使用多个渲染rarget创建反照率和法线缓冲区,并填充深度缓冲区。所有这些缓冲区实际上都是纹理。 现在我想从其他渲染通道访问深度缓冲区,从而访问其他帧缓冲区,而不改变深度纹理。我只想读取深度值。对于这些通道,我主要绘制全屏四边形,我不希望他们更新深度纹理并将其消隐为深度值0。 如何将一个给定的深度纹理附加到另一个帧缓冲区,并确保它是只写的?

  • 通过前两节课的学习,想必你已经对Threejs的层级模型有了一定认识,那么本节课就在层级模型概念的基础上,继续给家讲解两个新的概念,即本地坐标系和世界坐标系。 如果你对本地坐标系和世界坐标系已经有了一定概念,那么可以直接访问模型的位置属性.position获得模型在本地坐标系或者说模型坐标系下的三维坐标,通过模型的.getWorldPosition()方法获得该模型在世界坐标下的三维坐标。 .ge

  • 我正在使用JOGL,但这个问题一般适用于OpenGL。似乎存在类似的问题,但它们要么针对GLSL代码,要么与复制帧缓冲区的内容有关,要么是一般建议-使用帧缓冲区对象,而不是。 我正在做一些阴影映射。如何使用帧缓冲对象将深度通道直接渲染到纹理? 能否请你贴一段初始化纹理和帧缓冲对象的代码,以及渲染场景前初始化一切的代码? 目前,我使用<code>glCopyTexSubImage2D<code>。我