thi-ng / geom

2D/3D geometry toolkit for Clojure/Clojurescript
Apache License 2.0
961 stars 79 forks source link

pluggable element-wise matrix operations #24

Open kovasb opened 9 years ago

kovasb commented 9 years ago

This is maybe too specific to my use case but I'll try anyway.

I'm tied of manually constructing matrices in GLSL code. I'd rather symbolically compute some matrix and use gamma to emit the code. I especially don't want to rewrite the logic for various eg rotation or perspective transformations. Too easy to get it wrong unless you've done it before.

Although geom supports pluggable *,+ etc, that only applies at the matrix level. Operations on elements bottom out at macromath, which in principle is pluggable but the geom matrix types have been hardwired to specific operations.

So: can we have matrix types where the user supplies the elementwise arithmetic operations? If its an easy thing to do I think it would be quite cool.

postspectacular commented 9 years ago

Hi Kovas, just to make sure I understand that correctly.. are you're asking if the matrix types could be used like this:

(let [a (matrix44 ...)
      b (matrix44 ...)]
  ;; produce new matrix via elementwise combination
  (combine a b +))

Indeed that would be quite nice to have and not hard to implement... Also happy about other naming proposals instead of combine or combine-with.

kovasb commented 9 years ago

My specific use case is for generating matrix transformations for use inside of gamma shaders.

I'd like to do something like (geom/rotate-around-axis [gamma-x-coord gamma-y-coord ...] [0 1 0] rad)

where gamma-x-coord etc are datastructures representing GLSL fragments. I would supply my own functions for +, -, *, / which would take the args and generate a new GLSL frag. Then I would take the resulting structure and transform it into actual GLSL.

This is basically symbolic manipulation. In general it could also be used without gamma to symbolically generate clojure code that just computes the desired end structure with no intermediate allocations.

There is https://github.com/clojure-numerics/expresso, but it doesn't have the builtins that I need, and probably doesn't follow the same graphics-friendly conventions as thi-ng.

As a side note, there is a different approach to removing allocations from geometry generation pipeline (not applicable to the shader-side stuff I'm talking about above) in the newly-released mathbox2

gitgud.io/unconed/mathbox
http://acko.net/blog/mathbox2/

based on transducer-like idea of calling a supplied "emit" function with every step of the transformation. Pretty interesting.