Comments (46)
I don't think moving the whole library to Arrays is a good idea. I still prefer having object.position.x
instead of object.position[0]
. Matrix4, in the other hand, is mostly used internally.
from three.js.
object.position.x can still be supported via properties
var vector = [];
vector.__defineGetter__('x', function() { return this[0]; });
vector.__defineGetter__('y', function() { return this[1]; });
vector.__defineGetter__('z', function() { return this[2]; });
vector.__defineSetter__('x', function(value) { this[0] = value; });
vector.__defineSetter__('y', function(value) { this[1] = value; });
vector.__defineSetter__('z', function(value) { this[2] = value; });
vector.x = 0;
vector.y = 1;
vector.z = 2;
console.log(vector.x, vector.y, vector.z);
from three.js.
Hmmm, last time I checked that didn't work on IE9...
I'm testing Matrix4 using Arrays locally and I'm not seeing much change... The graphics API probably being such a bottleneck isn't helping there :) Will continue testing...
from three.js.
jump in irc if you're around
from three.js.
https://gist.github.com/721717
Am I missing anything? This seems to be 20% slower than using Objects...
from three.js.
you need to cache the array lookups when they are used more than once. for instance in multiply you are accessing a.array[ 1 ] a few times.
this is how glMatrix does it...
mat4.multiply = function(mat, mat2, dest) {
if(!dest) { dest = mat }
// Cache the matrix values (makes for huge speed increases!)
var a00 = mat[0], a01 = mat[1], a02 = mat[2], a03 = mat[3];
var a10 = mat[4], a11 = mat[5], a12 = mat[6], a13 = mat[7];
var a20 = mat[8], a21 = mat[9], a22 = mat[10], a23 = mat[11];
var a30 = mat[12], a31 = mat[13], a32 = mat[14], a33 = mat[15];
var b00 = mat2[0], b01 = mat2[1], b02 = mat2[2], b03 = mat2[3];
var b10 = mat2[4], b11 = mat2[5], b12 = mat2[6], b13 = mat2[7];
var b20 = mat2[8], b21 = mat2[9], b22 = mat2[10], b23 = mat2[11];
var b30 = mat2[12], b31 = mat2[13], b32 = mat2[14], b33 = mat2[15];
dest[0] = b00*a00 + b01*a10 + b02*a20 + b03*a30;
dest[1] = b00*a01 + b01*a11 + b02*a21 + b03*a31;
dest[2] = b00*a02 + b01*a12 + b02*a22 + b03*a32;
dest[3] = b00*a03 + b01*a13 + b02*a23 + b03*a33;
dest[4] = b10*a00 + b11*a10 + b12*a20 + b13*a30;
dest[5] = b10*a01 + b11*a11 + b12*a21 + b13*a31;
dest[6] = b10*a02 + b11*a12 + b12*a22 + b13*a32;
dest[7] = b10*a03 + b11*a13 + b12*a23 + b13*a33;
dest[8] = b20*a00 + b21*a10 + b22*a20 + b23*a30;
dest[9] = b20*a01 + b21*a11 + b22*a21 + b23*a31;
dest[10] = b20*a02 + b21*a12 + b22*a22 + b23*a32;
dest[11] = b20*a03 + b21*a13 + b22*a23 + b23*a33;
dest[12] = b30*a00 + b31*a10 + b32*a20 + b33*a30;
dest[13] = b30*a01 + b31*a11 + b32*a21 + b33*a31;
dest[14] = b30*a02 + b31*a12 + b32*a22 + b33*a32;
dest[15] = b30*a03 + b31*a13 + b32*a23 + b33*a33;
return dest;
};
from three.js.
Just tried that. Didn't seem to improve much... :/
from three.js.
Also, how are you utilising that code?
It kind of looks like they're still objects...
It's not enough to go from an object with properties to an object with an array instead of the properties. You need to drop all "new THREE.Matrix4()" altogether and go with instantiating arrays.
from three.js.
Why? glMatrix.js also uses objects:
var mat4 = {};
from three.js.
Some performance increasing:
http://jsperf.com/array-vs-object-matrix-inversion/5
from three.js.
I'm aware of these things, just I didn't get to test / optimize it yet.
This is a bit black magic, you need not to rub JS implementation in a bad way.
Biggest point for fast math in JS is not creating / destroying objects / arrays all the time and cache access.
WebGL folks have been doing a lot of experiments, there is nice page with live tests of several math libraries by Tojiro:
http://glmatrix.googlecode.com/hg/benchmark/matrix_benchmark.html
Also, to be taken into account, using WebGL-only types may limit reach of CanvasRenderer. Should use fallback to normal JS types.
from three.js.
actually I made a mistake seems like there is still a huge difference
from three.js.
Why? glMatrix.js also uses objects:
var mat4 = {};
I'm afraid you might be missing the entire point of my benchmark. In glMatrix objects are only used as container objects for the methods.
With glMatrix and others, when you instantiate a new Vector/Matrix/Quaternion you are only instantiating an array...
mat4.create = function(mat) {
var dest = new glMatrixArrayType(16);
if (mat) {
dest[0] = mat[0];
dest[1] = mat[1];
dest[2] = mat[2];
dest[3] = mat[3];
dest[4] = mat[4];
dest[5] = mat[5];
dest[6] = mat[6];
dest[7] = mat[7];
dest[8] = mat[8];
dest[9] = mat[9];
dest[10] = mat[10];
dest[11] = mat[11];
dest[12] = mat[12];
dest[13] = mat[13];
dest[14] = mat[14];
dest[15] = mat[15];
}
return dest;
};
With three.js you are instantiating a new object...
THREE.Matrix4 = function () {};
THREE.Matrix4.prototype = {
n11: 1, n12: 0, n13: 0, n14: 0,
n21: 0, n22: 1, n23: 0, n24: 0,
n31: 0, n32: 0, n33: 1, n34: 0,
n41: 0, n42: 0, n43: 0, n44: 1
}
Apparently in JS there's a vast difference between creating an object and creating an array.
"mjs is designed around speed and simplicity. For example, it doesn’t attempt to stuff vectors and matrices into JavaScript objects. Because the language offers no operator overloading, there’s very little benefit in treating these types as discrete objects, and lots of performance and memory usage downsides. Instead, it provides a set of functions for performing operations on vectors and matrices, which can be any array-like object. For any function that returns a vector or matrix, an existing array can be passed in to take the result, or the function can create a new one. Array reuse ends up being important because of the potential for expensive garbage collection churn eating away at performance."
gero3 18 minutes ago | link
Some performance increasing:
http://jsperf.com/array-vs-object-matrix-inversion/5
That's a nice improvement but you can optimise the OO version all you like and never approach the speed of using simpler arrays.
from three.js.
hehe actually, that is not completely true as EWGL-matrixes(which uses a OO version) is actually quite comparable with glmatrix and mjs.
PS: I 'm quite biased in this matter as I'm the developer of EWGL-matrixes and active developer in glmatrix .
from three.js.
True? I did not realise. I'm actually quite impressed you managed to get it going with objects that fast.
I'm sort of torn between whether or not the OO is worth the slowdown (even if it is only a few ms here and there, matters to me) or if I even prefer it over a functional API.
gero3 - you obviously prefer the OO API over the functional API right? That's the reason EWGL exists?
from three.js.
I see I see. I'll play around with this.
Anyway, a couple of things... As I mention, the bottleneck is not matrices but the graphics API. With WebGL this could easily become a bottleneck but, is the shader the one taking care of matrices multiplications (as far as I'm aware of).
Also, for benchmarking... I think it's better to benchmark transformVector3 / transformVector4 as these are the methods called thousands of times (per polygon) rather than multiply which is called just a bunch of times (per object).
from three.js.
I just find that going back and forth from the "WebGL/canvas" native-typed arrays to the standard arrays is all that much easier with a math library backed by arrays.
When it comes down to choosing, if you disregard the minor differences in speed between glMatrix and EWGL, I think for sake of interoperability between normal and typed arrays I'm inclined to go with the functional API of glMatrix.
from three.js.
Also, for benchmarking... I think it's better to benchmark transformVector3 / transformVector4 as these are the methods called thousands of times (per polygon) rather than multiply which is called just a bunch of times (per object).
Good point. I'll bust that out...
from three.js.
well actually, I use only glmatrix anymore. I think it is easier to use and is easier for crossbrowser development.
EWGL-matrices is actually quite a bit older. That is also why it isn't up to date anymore.
from three.js.
http://jsperf.com/array-vs-object-vector-transformation
http://jsperf.com/array-vs-object-matrix-inversion
At first I had the allocations in the loop and I think it was screwing with the results.
from three.js.
With WebGL this could easily become a bottleneck but, is the shader the one taking care of matrices multiplications (as far as I'm aware of).
Unfortunately not completely, even with WebGL still quite a lot of math is done in JS.
Shaders do per-vertex and per-fragment math inside objects. Per-object math (modelview and normal matrix) is computed in JS.
So this can indeed become a bottleneck when you have many objects.
That's why all WebGL folks try to come up with own optimized math libraries.
Other option would be to move really everything into shaders, but this is wasteful, as what otherwise would need to be done once per object would have to be repeated for every vertex.
from three.js.
Thanks for chiming in alteredq.
mrdoob you might might be interested in the vector transformation results for firefox 4 - ~1/3 increase in speed.
from three.js.
Nice to see this discussion going on. While I don't have the knowledge to completely understand the internals of Three.js, I'm building a very cool demo that mimicks Minecraft (minecraft.net) in a simple way, which will profit very much from any speed increase since it's quite heavy. I'll post an issue here when it's done!
from three.js.
@fabricasapiens - we're doing the exact same thing ^w^
http://www.youtube.com/watch?v=14A3hw4RGSI
http://dev.dekz.net:8001/ - it's online ATM if you guys want to check it out ;)
from three.js.
BTW it's multiplayer, me and @dekz are on ATM
from three.js.
You'll need WebGL/websockets and a creative mind ^w^
from three.js.
:D
I'm there and I see the whole structure, but I don't see any of you add blocks... Do you see mine? Maybe a websockets issue? I'm on Ubuntu 10.04 / Chrome 7 with WebGL.
from three.js.
I just added a whole bunch. The fact you can see the world is proof the sockets (or a compatible mechanism; we're using socket.io which can fallback) are working.
We're adding chat ATM...
from three.js.
I'm in the three.js IRC if you want to come and tell me a bit about your game...
from three.js.
Ok, I'll wait for the chat, then join in again :)
I'm off doing some other work right now!
edit: what IRC channel?
from three.js.
#three.js
from three.js.
Coding a minecraft-like system is quite an ambitious thing to do. I doubt forking my voxel editor would get someone too far...
from three.js.
from three.js.
i have some infrastructure in place for facilitating "chunk" based worlds
http://www.youtube.com/watch?v=yUxKq1sm0xc
from three.js.
People like ambitious things ;-)
from three.js.
Yes, I tried it already. That's not minecraft :P That's a Multiused Voxel editor ;)
For me, minecraft is about walking endlessly in a procedurally generated world that you can also modify. The voxel editor can handle a lot of extension, with some bugs I didn't care to fix yet.
Minecraft world seems to be 64M * 64M * 128 = 524288 Million blocks. Unless what you send across websockets it's a perlin noise seed and all the data of blocks modified I doubt you can send that much information ;)
from three.js.
I would very much like to be proven wrong, of course ^^
from three.js.
I indeed guess that there should be an ID for every random world, so that the clients can generate the world on their own, and then apply the changes. This takes some time initially, but the next time, only the changes from previous time need to be synced...
I guess it is possible, even when it might become a Megabyte or two. Minecraft savefiles are only 2Mb as well...!
from three.js.
http://jsperf.com/diff-in-speed-for-three-js
some enhancements
from three.js.
just benchmarked a few times with Chrome 7. Some 22% speed improvement!
from three.js.
http://jsperf.com/diff-in-speed-for-three-js/3
another improvement by taking the assumption that d normally never is different then 1
from three.js.
Any idea how this improvement would impact real FPS usage?
from three.js.
quite largely actually I think altough it still depends on application to application
from three.js.
Implemented :)
Thanks gero3!
from three.js.
Thanks everyone for all the comments and feedback. I think it's best to leave it to another time. Unfortunately such a change would considerably affect the API.
However, some level of performance inprovement has been achieved here. Thanks again gero3!
from three.js.
Check out my project featuring one of the first well-developed boilerplates for 3D rendering (ThreeJS) and server-side physics in NodeJS. Using binary data with the NodeJS WebSocket library, it is extremely optimized, but feedback is much wanted. It is meant to act as a platform for IO games, but is arbitrarily built to be used for almost anything.
from three.js.
Related Issues (20)
- WebGPURenderer: Camera nodes are broken in compute shaders HOT 1
- SSAARenderPass(TAA) make PerspectiveCamera aspect invalid HOT 3
- rotate a cube using cubeB.rotateX(1) 40 times and then cubeB.rotateX(-1) 40 times can not turn to initial rotation HOT 1
- Feature Requested: Need Three Js Editor HOT 1
- Raycaster not detecting objects when using object.layers.set(1) and camera.enable(1) HOT 2
- Transmission rendering doesn't respect viewport HOT 2
- can i use external WebGLBuffer as attribute buffer when I use InstancedBufferGeometry ? HOT 1
- UVNode WebGL / WebGPU Evaluate Discrepancy
- skinned mesh lost webgl1 support HOT 2
- Layers can directly set the layers of all child nodes HOT 1
- 【TransformControls】Unable to select after setting the layer HOT 1
- Large time delta values using Timer when page is not visible (in Firefox) HOT 10
- Add an API to disable TransformControls's XYZ, XY, YZ, XZ and the extra 'x', 'y' and 'z' in the visual controls. HOT 5
- Only render the last viewport normally when setting scene.background HOT 3
- Google Chrome Autoplay policy changes affecting the usage of AudioListener and AudioLoader class HOT 4
- GTAO/SSAO alter transparent materials appearence HOT 4
- Provide an iterative version of Object3D.traverse() HOT 2
- WebGLBackend: Support for Accessing External Elements in StorageBuffer HOT 4
- Raytracing material & lighting HOT 3
- move addons out of the examples folder HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from three.js.