Is it possible to do offscreen rendering with multithreading or multiprocessing?
Does anyone have any relevant experience? As I don't want Scenes to interfere with each other due to multithreading and multiprocessing, I created multi OffscreenRenderers running on independent threads. The parts of code show below
import threading
import pyrender
...
# load meshes
fuze_mesh = Mesh.from_trimesh(fuze_trimesh)
# offscreen rendering for multithreading
def offrendering():
r = OffscreenRenderer(viewpoint_width = 640*2, viewpoint_height = 480*2)
scene = Scene()
# add object and camera
scene.add(fuze_mesh, pose = fuze_pose)
scene.add(camera, pose = cam_pose)
color, depth = r.render(scene)
# threadlist
renderList = list()
# 4 threads
for _ in range(4);
t= threading.Thread(target= offrendering)
renderList.append(t)
t.start()
waitthreads = [t.join() for t in renderList]
But it comes up with OpenGL.error.Error - No valid context in thread
I know that rendering run on multiple threads, but is it mean that pyrender can't do multithreading rendering? also, I've tried multi-processing rendering and it doesn't work.
I hope some experts can solve the problem. Thanks
This should work with multiprocessing. However, be careful to only import pyrender in the process-specific part.
import os
os.environ["PYOPENGL_PLATFORM"] = "egl"
from multiprocessing import Process
def render_offscreen():
import pyrender # <-- This is important!
# Render away ...
processes = []
for _ in range(4):
process = Process(target=render_offscreen)
process.start()
processes.append(process)
for process in processes:
process.join()
@pderoovere interestingly I keep getting segfault even I tried this (I'm using joblib to launch multi-process jobs). I verified the call pyrender.OffscreenRenderer is crashing the program. I didn't find anything useful online regarding the issue in joblib context though. Any suggestions? Thanks.
@danielyan86129 Does your program work if you don't use parallel processing? And if you use only 1 job? Anyway, there is not a lot of information here. Can you provide (a simplified version of) your code?
Thanks for the quick reply @pderoovere . In fact my program works if I don't use sharedmem of joblib, and yes it also works with 1 job. I need the shared mem because I have a set maintaining available GPU ids which I assign to process.
It seems that things also work if I use a multiprocessing.Queue to maintain the GPU ids, and turn off joblib's sharedmem. Does that make sense?
It's hard to estimate how using sharedmem interacts with pyrender just from your explanation. Again, it would be easier if you could provide your code.
Using a Queue to exchange data between processes does make sense.