As suspected, this was caused by incorrect shader state management when switching between multiple shaders (thanks Firefox for verbose warnings).
Also, testing WebGL performance is very tricky. You can get different performance depending on the state of browsers / system (messed up state can be 10-66% slower):
1. freshly started Chrome can be much faster than Chrome that already ran few WebGL demos (which are now closed)
2. demo opened in new Chrome tab can be faster than demo reloaded in the same tab
3. even demos opened and closed in Firefox can slow down Chrome demos
This suggests that browsers do not clean GPU state properly :(
MeshShaderMaterial is still work in progress, expect changes.
Nice side effect of WebGLRenderer refactoring: optimized one significant bottleneck (with noticeable effect on framerate in some demos), typed arrays corresponding to matrix uniforms are now set (instead of being created anew in each frame).
Also created fully full build, with all extras included. This helps with deployment, especially when multiple versions of Three have to coexist in the same folder structure (got burned on this few times already).
2d texture encapsulates bitmap, wrapping and minifying/magnification parameters.
Which reminds me, maybe also minifying/magnification options should be parameters in Texture object.
Though as defaults are "best" (LINEAR / LINEAR_MIPMAP_LINEAR = trilinear filtering), this would make sense just for special use cases like when trying to achieve "retro" look (like in Minecraft, http://gregs-blog.com/2008/01/14/how-to-turn-off-bilinear-filtering-in-opengl/ ;).
Turns out it is working better over the real web than on localhost (where it seems loading is too fast for Chrome to pick up UI changes, so it queues them and shows them all just after loading is already finished).
Still not working properly - getting length of full content, this seems to be unreliable across browser / server combination.
Instead passing to callback JSON object with both total and loaded bytes, so this can be handled in the application layer:
{ total: bytes_total, loaded: bytes_loaded }
To be used e.g. like this:
loader.loadBinary( url, function( geometry ) { createScene( geometry ) }, path, updateProgress );
function updateProgress( progress ) {
var message = "Loaded ";
if ( progress.total ) {
message += ( 100 * progress.loaded / progress.total ).toFixed(0) + "%";
} else {
message += ( progress.loaded / 1000 ).toFixed(2) + " KB";
}
$( "status" ).innerHTML = message;
}
Not anymore automatic, but also much less wasteful.
Has to be called in tandem with scene object removal:
scene.removeObject( object );
webglRenderer.removeObject( scene, object );