Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to run Three.js WebGLRenderer on node.js server?

I am in need of running WebGLRenderer on the server, but there are different voices regarding this. Some say that it's not possible and some say they are trying to get it working, but that's when the discussions end.

Is it possible to do it and in that case, what is the approach? Is it possible using moch-browser combined with node-gl or something?

[edit] Added solution

like image 727
JakobMiller Avatar asked Dec 06 '25 19:12

JakobMiller


2 Answers

This is my own solution to the problem. Depending on the size of the scene and its objects, it might take some time. In my case I want to return pretty small versions of the object, but still takes about 400ms to respond with a 400x400px png. Hope this helps someone out there!

enter image description here

Server.js

var THREE = require("three.js");

// Create a DOM
var MockBrowser = require('mock-browser').mocks.MockBrowser;
var mock = new MockBrowser();
var document = MockBrowser.createDocument();
var window = MockBrowser.createWindow();

//REST API
var express     = require('express');      
var app         = express();    
var bodyParser  = require('body-parser');
var router = express.Router();

var gl = require('gl')(1,1); //headless-gl

var pngStream = require('three-png-stream');
var port = process.env.PORT || 8080;

router.get('/render', function(req, res){

    var scene = new THREE.Scene();
    var camera = new THREE.PerspectiveCamera(75, this.width / this.height, 0.1, 1000);
    var renderer = new THREE.WebGLRenderer({context:gl});

    scene.add(camera);

    renderer.setSize(this.width, this.height);
    renderer.setClearColor(0xFFFFFF, 1);

    /*...
        Add your objects & light to the scene 
    ...*/

    var target = new THREE.WebGLRenderTarget(this.width, this.height);
    renderer.render(scene, camera, target);


   res.setHeader('Content-Type', 'image/png');
   pngStream(renderer, target).pipe(res);
});

app.use('/api', router);

app.listen(port);
console.log('Server active on port: ' + port);
like image 149
JakobMiller Avatar answered Dec 08 '25 08:12

JakobMiller


You could try headless-gl but you'd need to use some other libraries to emulate the DOM and Image tags (for texture loading) and Canvas tags and/or Canvas2D if you need that as well.

Otherwise you could shell to a browser running on top of OSMESA maybe or try headless chromium


Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!