SceneJS 3.0 is an open-source 3D engine on WebGL that's geared towards rendering large numbers of individually articulated and pickable objects as required for high-detail visualisation applications.
Hotlink to these binaries and they will dynamically load SceneJS plugins on-demand from this repository as required (see Plugins System below for more info on plugins).
Also hotlinkable are a bunch of helper utilities:
- OrbitControl - Mouse camera orbit helper
- PickControl - Scene picking helper
- Declarative JSON API - Build scenes quickly on a declarative JSON-based API that plays well with the rest of the application stack. JSON is nice to export, database, transmit, transform and read.
- Sensible Defaults - SceneJS now provides defaults for all scene state, such as camera, lights and material, in a configuration that's ready to render whatever geometry you drop into the scene. That means you can create a more minimal scene definition, which turned out to be handy for creating clearer examples.
- Multiple Scenes - Run multiple scenes simultaneously in the same page
- Automatic Lost WebGL Context Recovery - SceneJS seamlessly recovers from Lost WebGL Context errors, which occur when the OS or browser resets WebGL to regain control after a mishap. When a new context becomes available, SceneJS instanly rebuilds all its WebGL resources from state held in the scene graph without reloading anything off the server.
- Color, Alpha, Specular, Glow and Bump Maps
- Multitexturing - Layer multiple textures onto the same geometry
- Texture Animation - Animate textures by rotating, scaling, translating and blending them.
- Video Streaming to Color, Alpha, Specular, Glow and Bump Maps - Stream a video into a texture in real time.
- Geometry Morphing - Animate geometry by interpolating its positions, normals, colors and UVs within keyframes.
- Transform Hierachies - Articulate your scenes using hierarchies of modelling transform nodes, a staple feature in scene graph APIs.
- Layers - Control rendering order of scene nodes by prioritizing them in layers, which is useful for transparency sorting.
- Plugins - Extend texture and geometry functionality through plugins, eg. to create primitives, load compressed texture formats, and so on. All the geometry primitives, such as 'teapot' and 'sphere', are now plugins. Plugins are unobtrusive, and are kept in a directory from where SceneJS loads them as required. Read more in the plugins section below.
- Vertex and Fragment Shader Customization - Although SceneJS generates shaders automatically, you can modify the shaders by injecting custom functions into them
- Texture Atlasses - Define a large texture containing an "atlas" of sub-textures to use individually on many geometries, each of which have UV coordinates that map to a different region of the texture. In a scene where there are many small textures, this has the benefit of reducing state changes on the graphics hardware by binding once, instead of for each individual texture..
- Geometry Vertex Sharing - Animate geometry by interpolating its positions, normals, colors and UVs within keyframes.
- 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 process multiple parent paths, so SceneJS takes an alternative approach with "node cores", a concept borrowed from OpenSG.
- GPU Optimisation - to reduce work done by the CPU within the render loop, SceneJS dynamically recompiles the scene graph to a lean internal draw list, which is state-sorted to minimise the work done by the GPU. By ordering the objects by shader, texture, VBOs etc. it can avoid redundantly re-binding state to the GPU. Though SceneJS does a pretty good job of sorting, if you program your scene to share plenty of state between your objects then you can achieve some very fast results.
As mentioned above, SceneJS now uses plugins for things like primitives (box, teapot, text etc.) and fancy texture loading (video etc).
Plugins are used from within node definitions, as shown in this example for geometry:
var myGeometry = myNode.addNode({
type:"geometry",
id: "myGeometry",
source:{
type:"sphere",
latitudeBands : 30,
longitudeBands : 30,
radius : 2
}
});
This geometry node will create its sphere geometry with the help of the "sphere" plugin.
Essentially, the plugin's code looks like the listing below. The plugin provides geometry factory objects, each with
a configure
method to configure the sphere shape and a subscribe
method to collect created geometry data.
SceneJS.Plugins.addPlugin(
"geometry", // Node type
"sphere", // Plugin type
new (function () {
this.getSource = function () {
var publish;
return {
subscribe:function (fn) {
publish = fn;
},
configure:function (cfg) {
publish(build(cfg));
}
};
};
function build(cfg) {
var latitudeBands = cfg.latitudeBands || 30;
var longitudeBands = cfg.longitudeBands || 30;
var radius = cfg.radius || 2;
var positions = [/*...*/];
var normals = [/*...*/];
var uv = [/*...*/];
var indices = [/*...*/];
return {
primitive:"triangles",
positions:new Float32Array(positions),
normals:new Float32Array(normals),
uv:new Float32Array(uv),
indices:new Uint16Array(indices)
};
}
})());
Then you can reconfigure the geometry at any time using setter methods on the node as shown below. Note however that we can't reconfigure the plugin type we're using for our node.
// Reconfigure our sphere like this - make it bigger and smoother:
myGeometry.setSource({ latitudeBands : 60, longitudeBands : 60, radius : 3 });
// ..or do the same using the generic attribute setter:
myGeometry.set({ source:{ latitudeBands : 60, longitudeBands : 60, radius : 3 } });
myGeometry.set("source", { latitudeBands : 60, longitudeBands : 60, radius : 3 });
By default, SceneJS is hardwired to automatically download plugins from a directory in this repository. This means you can just hotlink to the SceneJS core library downloads and they will download the plugins automatically as you need them. That's nice for putting SceneJS examples on code sharing sites like jsFiddle.
If you'd rather serve the plugins yourself, instead of relying on the avialability of this repo, then grab a copy of the plugins and configure SceneJS to load them from your location:
SceneJS.configure({
pluginPath: "./foo/myPluginsDir"
});
SceneJS requires nodejs. To build, simply:
node build.js
Then the binaries will appear in ./build
.