-
What code is better: implicit (+) or explicit (-)? E. g. create unfolded object for each structure instance or provide type constructor?
-
- implicit is able to be unfolded - closurecompiler or ast-eval
-
- implicit is sometimes senseless like var a = bool();
-
- same time it may provide different implementation of bool.
-
- implicit is sometimes senseless like var a = bool();
-
- implicit way avoids unfolding matrices multiplication:
mat2d['*'](a, b)
- implicit way avoids unfolding matrices multiplication:
-
- explicit is easier to read
-
- explicit corresponds to swizzles
-
- implicit may be slower in simple cases like
var a = false
-
- but times faster in multiple use like
var a = mat4(3)
- but times faster in multiple use like
-
- implicit may be slower in simple cases like
-
- in some cases implicits are N times slower:
xy.xy *= uv.yx;
. Expanding to explicit almost take no time to calculatexy[0] *= uv[0]; xy[1] *= uv[1];
, and also concise. But dealing with types is cumbersome:vec2.mult(vec2.xy(xy), vec2.yx(uv), xy);
-
- at the same way, explicits are over-calculative, eg
a.xy *= b.x / b.y
— for each component ofa
we calculateb.x/b.y
, and if it is a call for some troublesome method, it will be called up to 16 times (mat4 = meth()
). Whereas with implicit call it will calculateb.x/b.y
once and do assignment.-
- still opened version is loads of time (3 times) faster.
-
- at the same way, explicits are over-calculative, eg
-
- in some cases implicits are N times slower:
-
- From the other POV, who on earth cares about the beauty of compiled code?
- ✔ The good compromise is found in extending objects returned from types with swizzles etc. Takes more time on object constructs, but resulting code is pretty:
m = m.mult(n);
- Unfortunately, we have to extend native arrays prototype to keep execution fast enough.
-
-
Why on earth we need to wrap floats/ints/bools? Need we?
-
- things like
vec4 a = 2.0 * vec4()
-
- but they are better unwrapper as
var a = vec4().mult(1.0)
rather thanvar a = float(1.0).mult(vec4())
- but they are better unwrapper as
-
- things like
-
- implicit types are difficult to guess:
int a = 1, b = 2, c; c = a + b;
- which plus operator should we use?-
- not that difficult, actually. Result of assignment is always typed. Same as each operand. We just have to track map of variables
-
- implicit types are difficult to guess:
-
- we have to mind swizzle types as well then:
a.x = b.y
- we have to mind swizzle types as well then:
- ✔ No wrapping, it is faster and easier to read.
-
-
How to speed up code?
-
- Expand swizzles. Anyways you have to do multiplications manually in methods.
-
- Do not use vector types. FloatArrays are proved being 10 times faster, so fast that js shaders code is only 10 times slower than gl shaders one.
-
xy.xy *= uv.yx;
via fns is$(xy, 'xy', mult($(xy, 'xy'), $(xy, 'yx')));
— not really faster than swizzle getters.- The optimal way:
{let xyxy = vec2.mult(xy, vec2(uv[1], uv[0])); xy = vec2(xyxy[0], xyxy[1])}
. Deswizzling is slow, as any kind of function call, like getter etc, the optimal way is straight literal access.
- The optimal way:
-
- Use plain arrays instead of Float32Arrays to construct vectors - that saves time on creating.
-
- Unwrap multiplication operations eg m1 * m2 → m1[0] * m2[0]; m1[1] * m2[1]; ...
-
- Using function calls is not that bad, 2% loose. Some things are impossible without functions, like
fn(x) * vec4()
.- We can polyfill methods for each type of operation like
floatMultVec3
, but that would force us passing lib as a param, which is the same slow as using gl-matrix. - We cannot really provide functions init code in a shader call, so we basically need to.
- We possibly could’ve modified fake-gl processFragment so that it does not take lib as a param... But that seems to be difficult due to need to provide clean context for each call.
- So there is nothing but to pass gl-matrix as a lib and provide transforms so to use it’s methods. Because polyfilling the same isn’t faster really, but prone to difficulties and errors.
- We can polyfill methods for each type of operation like
- Using function calls is not that bad, 2% loose. Some things are impossible without functions, like
-