Hi,
I am trying to render a scene not only in the ShowBase window but also into an off-screen buffer. This worked quite well until now, but now I am trying to introduce shadows from a directional light and I am observing strange artifacts. Here is a minimal code sample illustrating the problem:
import cv2
import numpy as np
from direct.showbase.ShowBase import ShowBase
from panda3d.core import (Camera, DirectionalLight, Filename,
FrameBufferProperties, GraphicsEngine, GraphicsOutput, GraphicsPipe,
GraphicsPipeSelection, Loader, NodePath, Texture, WindowProperties)
base = ShowBase()
base.cam.set_pos(-3, 3, 3)
base.cam.look_at(0, 0, 0)
root = NodePath("root")
root.set_shader_auto()
model_path = Filename(__file__).get_dirname() + '/models/box.egg'
root.attach_new_node(Loader().load_sync(model_path)).set_scale((5, 5, 0.1))
root.attach_new_node(Loader().load_sync(model_path)).set_pos((0, 0, 1))
dlight = DirectionalLight("dlight")
dlight.get_lens().set_film_size(5, 5)
dlight.get_lens().set_near_far(1, 8)
dlight.set_shadow_caster(True, 1024, 1024)
dlight.show_frustum()
dlnp = root.attach_new_node(dlight)
dlnp.set_pos(2, 2, 4)
dlnp.look_at(0, 0, 0)
root.set_light(dlnp)
cam = Camera("my camera")
cam_np = root.attach_new_node(cam)
cam_np.set_pos(-3, 3, 3)
cam_np.look_at(0, 0, 0)
graphics_engine = GraphicsEngine().get_global_ptr()
my_buffer = graphics_engine.makeOutput(
pipe=GraphicsPipeSelection.get_global_ptr().make_default_pipe(),
name='my buffer',
sort=1,
fb_prop=FrameBufferProperties.get_default(),
win_prop=WindowProperties.size(400, 400),
flags=GraphicsPipe.BFRefuseWindow)
display_region = my_buffer.make_display_region()
display_region.set_camera(cam_np)
texture = Texture()
my_buffer.add_render_texture(
texture, GraphicsOutput.RTM_copy_ram, GraphicsOutput.RTP_color)
# variant 1:
root.reparent_to(base.render)
graphics_engine.render_frame()
graphics_engine.render_frame()
# variant 2:
#root.reparent_to(base.render)
ram = texture.get_ram_image()
rgb_im = np.frombuffer(ram.get_data(), dtype=np.uint8)
rgb_im = rgb_im.reshape(400, 400, 4)
rgb_im = cv2.flip(rgb_im, 0)
cv2.imshow('my image', rgb_im)
cv2.waitKey(100)
base.run()
Depending on whether I first reparent my scene to base.render (variant 1) or whether I first call render_frame (variant 2) the artifacts occur either in the ShowBase window or in the read out offscreen buffer:
Variant 1:
Variant 2:
Obviously, I’d like to have both images look nice
Any help would be really appreciated!
Thanks!
Best
Timo