Headless rendering

Hi,

I am currently working on a use case where i need to make some offscreen rendering (i mean headless rendering) in a nodejs backend, with express.js to serve my offscreen rendering as an image accessible from any web client by calling my REST endpoint.

I saw 2 topics in this forum talking about headless rendering but i didn’t succeed with them. So my question is, is there a good way to do headless rendering with three.js and serve the result as an image with some framework like express js ?

Is it better to use something like ‘mock-browser’ or ‘canvas’ or / and ‘headless-gl’ ?
I also tried this famous example but it doesnt works as Threejs need to add some listener to the canvas object.

I really hope that my topic will not be considered as a duplicate, but i think it should be great for all for us to try to find a global solution ?

Thank you for reading.

Offscreen rendering usually refers to rendering in a worker, like in this example:
https://threejs.org/examples/#webgl_worker_offscreencanvas

Headless rendering means rendering without a browser. There’s some code on the repo which does this using puppeteer - I think this file is the entry point:

It runs with the npm run make-screenshot command and is used to create automated screenshots of the example for e2e testing.

The generated files are stored in the examples/screenshots folder.

Thank you for your answer. Really helpful.

Unfortunately it is not exactly what i was looking for, even if it’s a good entry point as you said.
The thing is, some people, including me, are looking for something maybe little bit easier to use.

I mean, for Babylonjs we can directly find some example of headless rendering with new BABYLON.NullEngine();

So my question was is there something as much easy as babylon to do headless rendering or not ? I really didn’t find the answer after some hours looking for it and i really think that it could be great for a lot of people, still including me :slight_smile:, to have a nice and easy example of how we can do headless rendering with threejs.

Thank’s a lot.

Are you sure you have understood this feature from Babylon.js correctly? The official documentation says:

The NullEngine will not produce any rendering and thus can be used in a node / server side environment. It can be used to: Run tests, Run a server side version of your application / game, Use specific Babylon.js services (like gltf loaders for instance)

Yeah you’re right.

Actually. Maybe there is no way to do it properly ? But I don’t know why, nobody say it’s not possible :slight_smile:

I’m a java developer so I don’t have real good skills in nodejs and headless rendering with this kind of technology. The thing is, threejs is really easy to use and that is why I like it a lot ( as a lot of people i think).

My needs are to generate a texture and do some processing with a shader and send it as a png to the client. I already wrote the code to render it in a canvas (Client side) and it’s pretty easy. Now, I really need to do that in the backend side to be able to allow python clients, java clients and so on, to request my images which are processed in the backend without having to reimplement it everywhere.

Now, maybe it’s not possible to do that with threejs ? That is why I’m asking here.
Or if it’s possible, maybe someone have a piece of code ? It would be really great.

Thanks again for your answer.

I think the pointer of @looeee towards puppeteer goes into the right direction. If you need to generate images on the backend, then the approach of three.js's regression tests is ideal for your use case.

The linked script generates screenshot of the official three.js examples and compares them with pre-defined ones. The tests pass if there are no discrepancies between the existing and new screenshots.

As @Mugen87 says, that doesn’t seem to be the purpose of NullEngine.
Instead, the Babylon.js docs also suggest using Puppeteer for headless rendering:

https://doc.babylonjs.com/how_to/render_scene_on_a_server

Ok great, thank you again for you answers. If I have time I’ll try to write a snippet of code to do that and give the link here.

I was thinking that another easier solution was possible, but Puppeteer seems to be the good way to do it.

Thanks again.

1 Like

This is a pretty good resource on headless stuff with Puppeteer (or Playwright): https://theheadless.dev/posts/basics-taking-screenshots/

1 Like