Blender’s command line interface and Python API can both be used to trigger renders without using the GUI, and more generally without a graphical display. This can for example be useful to orchestrate renders on a set of servers.
Recall that Blender’s three main renderers are:
- Cycles, a path tracer.
- Eevee, based on OpenGL and optimized for speed.
- Workbench, mostly for the viewport.
Headless Eevee rendering
Cycles should work out of the box headlessly (as long as CUDA or the like are properly set up), but Eevee is trickier due to OpenGL. A naive attempt will yield either a fallback to the CPU (and render very slowly) or a crash.
There are quite a few discussions on the internet about that topic, with some fairly complex solutions:
- https://blender.stackexchange.com/questions/230728/is-there-no-way-of-rendering-headless-using-eevee
- https://blender.stackexchange.com/questions/232961/how-do-you-use-eevee-renderer-in-a-docker-container-using-bpy
- https://blender.stackexchange.com/questions/150526/blender-2-8-aws-ec2-command-line-eevee-render
- https://stackoverflow.com/questions/50107530/how-to-render-openai-gym-in-google-colab
- https://devtalk.blender.org/t/blender-2-8-unable-to-open-a-display-by-the-rendering-on-the-background-eevee/1436
Solution with EGL and libglvnd
Eevee supports EGL thanks to this commit.
On NVIDIA GPUs, we can leverage this with libglvnd as follows:
RUN git clone https://github.com/NVIDIA/libglvnd.git && cd libglvnd \
&& apt-get install -y libxext-dev libx11-dev x11proto-gl-dev \
&& ./autogen.sh && ./configure && make && make install \
&& mkdir -p /usr/share/glvnd/egl_vendor.d \
&& printf "{\n\
\"file_format_version\" : \"1.0.0\",\n\
\"ICD\": {\n\
\"library_path\": \"libEGL_nvidia.so.0\"\n\
}\n\
}" > /usr/share/glvnd/egl_vendor.d/10_nvidia.json
When using NVIDIA’s container runtime, libEGL_nvidia.so
is added automatically by the runtime when passing the NVIDIA_DRIVER_CAPABILITIES=all
environment variable.