Issue 1:
I have some spare time.

@mrdoob is it something you want in three.js ?

On CPU:

http://cgit.freedesktop.org/mesa/mesa/tree/src/glu/sgi/libnurbs/interface/glinterface.cc?h=8.0 ( restrictive license )

https://svn.blender.org/svnroot/bf-blender/trunk/blender/source/blender/blenkernel/intern/curve.c ( GPL )

http://www.nar-associates.com/nurbs/c_code.html ( copyright, non commercial reuse ok )

On GPU:

http://kingkong.me.berkeley.edu/~adarsh/Papers/CAD09.pdf

10 X faster

but high setup cost

Issue 2:
This is something I have been struggling with for a while. Three.js doesn't manage your assets very well. It creates duplicates, specifically my problem is with duplication of textures and materials.

When you load a texture - you get a brand new Texture object, the TextureLoader under the hood uses Cache, which is a global singleton, meaning that everything that you ever load will be in Cache. There is no eviction, meaning that it's very possible to leak memory here if you're loading dynamic things, like say, if you created a model viewer or an editor of some kind, user loads different models over and over again, and Cache just retains all of that. As a user you have just 2 options here:

Hunt down specific object and use Cache.remove(key), or

Use Cache.clear() which is a nuclear option that results in removal of everything in cache

The Cache is a key-value store, which is not so much of an issue, but it gets used with URL of an asset being loaded as the key - this means that given a URL - you can only ever have 1 representation of the data under that URL. Imagine following scenario:

You loaded a texture "happy-cat.png" using TextureLoader, then, down the road, you want to access binary data of the PNG specifically to parse it using some PNG library, suppose you want to access metadata stored in there, such as user name, palette, creation date, creation software etc. So, you use FileLoader. FileLoader uses same Cache, and it will also use the same url ("happy-cat.png") to access the Cache, so it will return you, not a "bytearray" like you asked, but, in fact, a DOM Image. There are more scenarios where this can happen and be an issue. As a minimum, an Asset Cache needs to be able to distinguish typed of Assets and store data from the same source in multiple representations, such as Image and ByteArray.

Suppose you are Ms Smarty-Pants and you decided to take all the models in your scene and pack textures for those into a single image, this way you can reduce texture switching to 0! That's crazy good, right? Well... When you load your models, say "Tree", "House" and "Cat" - each of these models will get a new Material, even if that said Material will be identical in your case. Each of these Materials will get its own new Texture, and that means that there will be 3 unique copies of that carefully packed image loaded to the GPU for your scene. Here's the relevant piece of code:

three.js/src/renderers/webgl/WebGLTextures.js

Lines 294 to 324
in
733eb1d

function setTexture2D( texture, slot ) {

var textureProperties = properties.get( texture );

if ( texture.isVideoTexture ) updateVideoTexture( texture );

if ( texture.version > 0 && textureProperties.__version !== texture.version ) {

var image = texture.image;

if ( image === undefined ) {

console.warn( 'THREE.WebGLRenderer: Texture marked for update but image is undefined' );

} else if ( image.complete === false ) {

console.warn( 'THREE.WebGLRenderer: Texture marked for update but image is incomplete' );

} else {

uploadTexture( textureProperties, texture, slot );

return;

}

}

state.activeTexture( _gl.TEXTURE0 + slot );

state.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );

}

As you can see, "uploadTexture" happens based on texture.version, it doesn't care that this texture is exactly the same as another texture that we already have in memory.

I am ashamed to admit that I was that Mr Smarty-Pants, and only caught this when doing performance profiling today. I found out that my image is being decoded multiple times and is being uploaded to the GPU multiple times, here's a helpful piece of code to identify such cases that you can put around the "uloadTexture":

if (!texture.isDataTexture && texture.image !== undefined && texture.image.src) {
console.time("Loading Texture " + texture.image.src);
}

uploadTexture(textureProperties, texture, slot);

if (!texture.isDataTexture && texture.image !== undefined && texture.image.src) {
console.timeEnd("Loading Texture " + texture.image.src);
console.log(textureProperties, texture, slot);
}

I propose that there should be a way to reuse static textures, one way to do that would be to de-couple the Texture Data from Texture Settings and use equality checks (with hashing to make things faster). Similar approach could be applied for Materials too, we'd be able to clean up some of the code that does something functionally similar for materials currently (when compiling shaders).