Object render order

Hi,

does anyone have any idea why depth information is not taken into account when rendering two cubes with the “graphicsEngine.make_output”? In the example code below, box_a is simply drawn in front of box_b, regardless of whether it is actually spatially in front of or behind box_b:
image
vs.
image

import cv2 as cv
import numpy as np
from direct.showbase.ShowBase import ShowBase
from panda3d.core import FrameBufferProperties, WindowProperties, GraphicsPipe, GraphicsOutput
from panda3d.core import Texture, PerspectiveLens


class SceneSimulator(ShowBase):
    IMAGE_CAMERA_RENDER_ORDER = -2

    def __init__(self):
        ShowBase.__init__(self, fStartDirect=True, windowType='offscreen')

    def render_image(self, pos, name=None):
        # set up texture and graphics buffer
        window_props = WindowProperties.size(540, 540)
        frame_buffer_props = FrameBufferProperties()
        buffer = self.graphicsEngine.make_output(self.pipe,
                                                 f'Image Buffer [{name}]',
                                                 self.IMAGE_CAMERA_RENDER_ORDER,
                                                 frame_buffer_props,
                                                 window_props,
                                                 GraphicsPipe.BFRefuseWindow,  # don't open a window
                                                 self.win.getGsg(),
                                                 self.win
                                                 )
        texture = Texture()
        buffer.addRenderTexture(texture, GraphicsOutput.RTMCopyRam)

        lens = PerspectiveLens()
        lens.set_film_size((540, 540))
        lens.set_fov(80)
        lens.set_near_far(0.1, 1000)

        camera = self.makeCamera(buffer, lens=lens, camName=f'Image Camera [{name}]')
        camera.reparentTo(self.render)
        camera.setPos(*pos)

        self.graphics_engine.render_frame()

        tex = buffer.getTexture()
        data = tex.getRamImage()
        image = np.frombuffer(data, np.uint8)
        image.shape = (tex.getYSize(), tex.getXSize(), tex.getNumComponents())
        return np.flipud(image)


if __name__ == '__main__':
    sim = SceneSimulator()

    box_b = sim.loader.loadModel("models/misc/rgbCube")
    box_b.setPos((1, 0, 0))  # change to position (1,2,0)
    box_b.reparentTo(sim.render)

    box_a = sim.loader.loadModel("models/misc/rgbCube")
    box_a.setPos((1, 2, 0))  # change to position (1,0,0)
    box_a.reparentTo(sim.render)

    out = sim.render_image((0, -5, 2))

    cv.imshow("frame", out)
    cv.waitKey(0)

I think obviously you haven’t configured the FrameBufferProperties object. You need to request a depth buffer.

frame_buffer_props = FrameBufferProperties()
frame_buffer_props.rgb_color = 1
frame_buffer_props.color_bits = 24
frame_buffer_props.depth_bits = 24
frame_buffer_props.back_buffers = 1

Something like this.

1 Like

Ah, yes, of course, that makes sense! I thought the FrameBufferProperties had some sort of default values. It’s working now (with back_buffers = 0)

Thank you! :slight_smile: