As expected, performance of one-to-one conversion from CanvasRenderer was horrible, so I had to change a bit how lines are handled.
Line object now has "type" property:
- default type is "THREE.LineContinuous" which should behave as before: geometry represents one continuous line (v0 ... vn)
- new option is "THREE.LinePieces" which tells renderer that geometry represents collection of individual line segments (v0,v1) ... (vn-1, vn)
(one Line object corresponds to one VBO)
(same limitations as with meshes - once VBO is baked, no changes are possible except object transforms - scale / rotation / position)
loader.loadAscii and loader.loadBinary now take just one parameter with following properties:
- model (required)
- callback (required)
- texture_path (optional: if not specified, textures will be assumed to be in the same folder as JS model file)
- bin_path (optional: if not specified, binary file will be assumed to be in the same folder as JS model file)
Example use:
loader.loadBinary( { model: "model.js", bin_path: "path/bin", texture_path: "path/img",
callback: function( geometry ) { createScene( geometry ) } } );
Code is still rough around edges (it can be made nicer), though it should already produce one-to-one results with ubershader.
Side-effect is that scene is no longer required as WebGLRenderer constructor parameter. Shader programs are now constructed upon first frame render and only then scene lights are examined.
None of the demos seem to be slower, some are noticeably faster (especially terrain).
I suspect biggest performance gain comes from conditional include of environment mapping: if it's not used, it doesn't go into shader at all.
Also changed MeshShaderMaterial demos to show how to use cloning. For these particular demos uniforms cloning is not really necessary as they use only one instance of shader material, but for example, if there were two normal mapped models in one scene, each model would need separate material with own uniforms.
For the moment, only one type of fog is baked into shader, depending on scene.fog initial value.
If use case arise for dynamic fog type switching, this could be changed, though than both fogs would need to be computed all the time :S.
Diffuse map and ambient occlusion maps are now optional in normal map shader.
By default, both are disabled, so they need to be enabled explicitly like this:
uniforms[ "enableAO" ].value = true;
uniforms[ "enableDiffuse" ].value = true;
This allows to work around ANGLE antialiasing issue appearing when compositing WebGL framebuffer with transparent background color with HTML canvas element background (while keeping antialiasing on).
WebGLRenderer constructor now takes JSON object with few optional parameters:
renderer = new THREE.WebGLRenderer { scene: scene,
antialias: true,
clearColor: 0x000000,
clearAlpha: 0 };
Here is how to change clear color in runtime:
renderer.setClearColor( 0xff0000, 1 );
Eventually I'll have to continue in the experimental branch. Want to give it a go to the ColorPass/TexturePass material API. The color + map + env_map setup feels too limiting...
Now that I have more knowledge of WebGL and shaders, this is how the ColorPass/TexturePass API looks like:
var material = [
new THREE.MeshLambertMaterial( [
new THREE.ColorPass( 0xff0000, 1, THREE.NormalBlending ),
new THREE.TexturePass( new Texture( <image>, new THREE.UVMapping() ), 0.5, THREE.NormalBlending ),
new THREE.TexturePass( new Texture( [ <image>, <image>, <image>, <image>, <image>, <image> ], new THREE.CubeRefractionMapping() ), 1, THREE.SubtractiveBlending ),
new THREE.ColorPass( 0x0000ff, 1, THREE.AdditiveBlending )
], { blending: THREE.NormalBlending } ),
new THREE.MeshBasicMaterial( [
new THREE.ColorPass( 0xff0000, 1 ),
], { blending: THREE.AdditiveBlending, wireframe: true } ),
new THREE.MeshPhongMaterial( [
new THREE.ColorPass( 0xff0000, 1 ),
], { ambient: 0x000000, specular: 0xbbaa99, shininess: 50, blending: THREE.NormalBlending } );
];
Makes things a bit longer but I think it's more intuitive this way (and pretty powerful). However, the simplest material would be like this:
var material = new THREE.MeshBasicMaterial( new THREE.ColorPass( 0xff0000 ) );
Mhh... Now I don't know whether they should called `*Pass`, or `*Layer`...