oframe / ogl

Minimal WebGL Library
https://oframe.github.io/ogl/examples
3.71k stars 211 forks source link

Why not simply use the object's attributes to represent addition in vec3, and instead write a new function to represent mathematical calculations separately? #186

Closed WREQI closed 12 months ago

WREQI commented 1 year ago

image

WREQI commented 1 year ago

Why not directly use object attributes for calculations in vec3, but instead write a new function vec3Func to represent mathematical calculations?

jniac commented 1 year ago

May I try to give an answer?

My opinion is that the author follows a functional approach to programming. From then on, the idea is to implement the basic functions (core) in pure functions (no deps). Classes, instances, objects are then simple wrappers around these functions to simplify writing the code from the user side (creative part).

Edit: For a simple "add" fonction the pattern may look overkill, but for more complex examples (cross/dot product, matrices transformation) it really makes sense to me.

WREQI commented 1 year ago

Performance will be better? @jniac

eXponenta commented 1 year ago

Redundant closure call with un-optimised argument (array of unknown type) is little bit slower that direct call.

Another problem: Array used in prototype chain that prevent "fastArray" implementation on older V8 engine in ignition state. Some engines fully disable any optimisation for dirty prototypes and no-numeric keys of Array.

More optimistic: use a Float32Array as backing storage, remove prototype nesting and move functions to methods implementation.

Which will looks like a more dirty.

But performance impact not so big to rewrite this lib. Regular project won't feels difference between implementations.

jniac commented 1 year ago

Performance will be better? @jniac

No, performance should be a little worse because of the extra call, but the difference may not noticeable in real use cases.

If you need very strong performances, for example computing the dot product of 1M vectors, it should be safer to reproduce the calculations on buffers in a custom method than to manipulate 1M instances. But those cases do not exists for real, are they?

However, could those calls be inlined by engine like V8? Well I don't know, I was only shawn very simple examples like this one where no mutation occurs.

Redundant closure call with un-optimised argument (array of unknown type) is little bit slower that direct call.

What is an array of "known type" in the context of javascript?

I regularly wonder if it is a good idea to extend the Array class in javascript. Generally I prefer to avoid it, but it is true that it is very tempting conceptually in the case of multidimensional numbers.

From a personal point of view, I find it interesting to think of javascript frameworks as resources for learning (so many things learned with Three.js for example). Here the fundamental mathematical concepts are separated from the data structure likely to summon them. I appreciate that.

The implementation of functions in methods also leads to annoying questions like:

Should the "add()" function modify the current instance or return a new instance? Three.js and Babylon.js, for example, made opposite choices. Here too a choice was made, but on the class side only, the mathematical implementation is free from this consideration (by using an "out" reference which we can decide or not to correspond to one of the two other references ("a" or "b")).

Also I know that if one day I have to copy/paste an operation on the matrices somewhere, OGL is likely to provide me with an easy basis to modify.

gordonnl commented 12 months ago

The functions were based on gl-matrix, and can easily be extended and shared between the math classes. They can also be used directly, separately from the math classes for certain high-performance use cases or extensions. Float32Arrays were initially implemented but Arrays proved to (surprisingly) greatly outperform them.