xeolabs bio photo


Lindsay Kay

3D software engineer / WebGL developer

Twitter LinkedIn Github

My chapter on SceneJS for OpenGL Insights is now free to download!

SceneJS v4.0 Released


SceneJS v4.0 adds:

  • custom effects pipelines (AKA postprocessing),
  • multi-pass rendering,
  • procedural textures,
  • reflection maps,
  • a bunch of sweet performance optimizations by NVIDIA,
  • a change to texture nodes (which unfortunately breaks backwards compatibility),
  • renamings of some plugins, and
  • a new examples browser.

I’m going to write more tutorials on these new features at some point, but hopefully the examples will help for now.

Postproccessing effects

SceneJS 4.0 lets you build effects pipelines of virtually unlimited complexity. You can render portions of your scene to colour and depth render targets, which you then apply as textures, or feed into custom shaders in other parts of your scene. In the example below, I’m doing a depth-of-field postprocessing effect by rendering the scene to colour and depth targets, then piping those targets into a second stage where we render the colour target to a screen-aligned quad, while blurring each pixel in proportion to its value in the depth buffer.

Run this demo

I’ve implemented a few postprocessing effects as node types that you can just drop into your scene:

Stay tuned - I’ll do a few more soon, such as a bloom filter and maybe motion blur.

Multipass rendering

SceneJS v4.0 also supports multi-pass rendering, where you can configure the scene to render multiple passes per frame, while updating scene state for each pass. This is really useful for stereoscopic effects like Anaglyph 3D, where we render one pass to the green-blue color channels with camera looking through the left eye, and a second pass to the red channel with the camera looking through the right eye.

Run this demo

Oculus Rift support didn’t make it into this release unfortunately (I don’t actually have a Rift device, so need a bit more time to tweak things).

Procedural textures

Now that we can render portions of our scenes to render targets, then apply those as textures, we can generate textures using shaders lifted straight off GLSL sharing sites like ShaderToy and GLSL Sandbox. Check this one out, copied from GLSL Sandbox:

Run this demo

Reflection mapping

SceneJS v4.0 now supports reflection mapping, a feature that was actually in alpha status in the previous version. Check out this tutorial for more info.

Reflection Example 1

Run this demo

Optimisations by NVIDIA

Olli Etuaho from NVIDIA has made some valuable optimizations:

These are primarily aimed at making SceneJS render faster on mobile, GPU-bound devices, and Olli reports as much as a 45% speedup on Tegra-based devices with some scenes! He’s also done some optimisations to THREE.js as well, so props to Olli on that.

Texture node changes

Besides some plugin renamings (see below), the only breakage in backward compatibility in this release (hence the major version change) is with the texture node, as shown below. Previously, the texture node had a layers property, in which we could specify one or more texture layers. Now in v4.0 we specify layers as individual nested texture nodes, which makes updating properties on the layers much cleaner. When we want to update a layer’s blend factor, for example, we get the texture for the layer and set that property on the node, without having to specify a layer index as we did before.

// Create scene
var myScene = SceneJS.createScene({
    nodes: [

        // Superman color map in layer #1
            type: "texture",
            id: "texture1",
            src: "textures/superman.jpg",
            applyTo: "color",

            nodes: [

                // General Zod color map in layer #2
                    type: "texture",
                    id: "texture2",
                    src: "textures/zod.jpg",
                    applyTo: "color",
                    blendFactor: 0.5,

                    nodes: [

                        // Box primitive
                            type: "geometry/box"

        function(texture2) {

The old texture node with the layers property will hang around for the next couple of versions, and now has type “_texture”. The leading underscore indicates that node is deprecated. To make existing application code work with SceneJS v4.0, just do a search-and-replace, replacing “texture” with “_texture”.

Plugin renamings

I’ve tidied up the names of a few plugins, which define non-core node types:

v3.2   v4.0
prims/box -> geometry/box
prims/cylinder -> geometry/cylinder
prims/grid -> geometry/grid
prims/heightmap -> geometry/heightmap
prims/plane -> geometry/plane
prims/quad -> geometry/quad
prims/sphere -> geometry/sphere
prims/teapot -> geometry/teapot
prims/torus -> geometry/torus
prims/vectorText -> geometry/vectorText
objects/vehicles/tank -> models/vehicles/tank
objects/space/planets/earth -> models/space/planets/earth

New examples browser

And finally - a new examples browser based on the one used over at THREE.js. Hopefully it doesn’t look too similar - I may have to style it a bit more.


A few things didn’t make it into this release, but I’ll be putting them into minor version releases over the next few weeks:

  • Normal mapping
  • Oculus Rift
  • Tutorials on all this stuff!

Anything I missed? Add a comment at the bottom of this page and I’ll fix it up.