Posterous theme by Cory Watilo

SceneJS 2.0 Release

The SceneJS 2.0 release is finally out the door, focusing on high rendering speed for complex scenes containing many individually articulated and pickable objects, which is characteristic of model viewing applications for engineering, architecture and medical visualisation.

While most WebGL frameworks support multi-pass effects such as shadows and reflections, SceneJS 2.0 has evolved to specialise in optimised single-pass rendering of large amounts of detail. That's not to say, however, that we can't create some catchy effects using some of its new features, as shown in the live examples.

Human-xray

BioDigital Human (in development), with 1886 meshes and 126 textures visible, rendering at around 13-15 FPS in Chrome 14.0.835.202 on an i7 CPU and an NVIDIAGeForce GTX 260M GPU

 

What's New

New Wiki at GitHub

V2.0 has a new wiki over at GitHub, which I'm still in the process of building up. We'll keep the old V0.9 wiki around for a few more months to help people port to the new SceneJS release, then we'll archive it and make it available for download.

 

Custom Shaders

SceneJS normally generates shaders for us, but when special effects are required we can now inject custom functions into them to intercept and modify colours, matrices, coordinates etc, all parameterised via the JSON API. 

With custom shaders, we can intercept coordinate positions to do things like displace them for wobbling effects, or discard fragments for clipping effects.

In the fog shader example, we intercept the view-space position and fragment colour in the fragment shader, then fog the colour in proportion to the coordinate Z-depth.

The fancy transparency example creates the glass effect shown in the snapshot above by intercepting the view-space normal and fragment colour, then setting the colour's alpha to a value that is proportional to how directly the normal faces the view point.

We can also modify matrices, like in the sky sphere shader example, in which we zero out the translation elements to keep the sky sphere centered at the viewpoint.

The Tron Tank program even got a custom shader - note the blurred horizon line.

The colorTrans node from SceneJS V0.9 has been deprecated, since we can now do the same effect with something like this pixel colour shader.

Read more in the wiki page on shaders.

 

More Scene Graph Compilation 

SceneJS dynamically (re)compiles the scene graph to a draw list of optimised WebGL state changes, which in V2.0 is now further (re)compiled to a list of fast WebGL calls. SceneJS caches these lists to minimise JavaScript re-execution per frame, rebuilding only the affected portions of them whenever scene state updates occur.

The WebGL calls are higher order functions which memoize things like shader variable locations in closures. After adding this, I observed a ~30-40% speedup for some applications - expect the next version of BioDigital Human to be noticeable faster.

 

Shared Node Cores

Traditionally, re-use within a scene graph is done by attaching nodes to multiple parents. For dynamically updated scenes this can have a performance impact when the engine must traverse multiple parent paths in the scene graph, so SceneJS now takes an alternative approach with ”node cores”, a concept borrowed from OpenSG.

Shared node cores replace the instance nodes found in earlier versions of SceneJS.

A node core is the scene node’s state. Having multiple nodes share a core means that they share the same state. This can have two significant performance benefits: an update to a shared node core can write through to multiple draw list elements simultaneously, and there is increased chance of runs of same state objects in the draw list after state sorting, which SceneJS capitalises on by avoiding repeated execution of them.

Many of the examples (such as the custom shaders) demonstrate shared node cores. Read more on the wiki page on node cores or check out this rather plain example.

 

Video Textures

Movie files can be applied as textures - useful for complex animated textures, animated bump maps, moving backgrounds etc. Read the wiki page on video textures or try this this example.

 

Multiple Scenes

 Multiple scene graphs can now be created within the same JavaScript runtime environment, allowing us to update them concurrently and share JSON content between them. Here's a multi-scene example.

 

Mutable Geometry

Geometry VBOs and IBOs can now be dynamically updated. Try this very plain example.

 

Ray Picking

SceneJS ray picking finds the logical pick name of the picked object, plus the point in world-space at which a ray cast from the eye position intersects with object's surface. It's ridiculously fast because the Z-coordinate is found with the help of the GPU, while the X & Y are found by unprojecting the canvas mouse coordinates.

Ray-pick can therefore be done almost as fast as a normal frame render and scales up to large amounts of detail, with no ray intersection testing against millions of triangles using JavaScript math. Read the blog post or try out the ray pick example.

 

Picking Changes 

Subgraphs are now wrapped in name nodes which assign geometries to logical pick names. Pick listeners are no longer bound to nodes. Instead a pick operation is made on the scene, which returns a name if a hit occurs. Read more in the wiki page on name nodes or check out the basic picking example.

 

Simpler Node State Inheritance 

Many scene nodes (such as material, flags and texture) now completely override state defined by parents instead of augmenting it. This simplifies reprocessing of the scene graph after updates, giving a huge speed increase. I'll highlight this more in the wiki.