nannou-org / nannou

A Creative Coding Framework for Rust.
https://nannou.cc/
6.03k stars 304 forks source link

Pixel-level API? #200

Open ghost opened 6 years ago

ghost commented 6 years ago

I can't find anything like this, so decided to create a feature suggestion. Would be nice to have something like get_pixel and set_pixel to support incremental/multipass scenarios when during drawing you sample what is already drawn to choose what to draw next.

mitchmindtree commented 6 years ago

Yeah agreed this would be quite handy!

Ideally I'd love for us to be able to leverage something like RLSL to allow us to achieve this with trivial rust on the GPU, however it would be nice to have simple CPU based methods like this too. From memory, one thing that both Processing and OF do is kind of "hide" the distinction between CPU and GPU memory representations of their image types. This is kind of convenient at first so that user's don't have to think about GPUs, shading languages, etc, but can quickly lead to massive performance penalties as a result. E.g. in Processing and OF it's often more intuitive for a new user to keep writing CPU code where you edit each pixel individually in a big loop using get_pixel/set_pixel, rather than doing the processing using a fragment shader where every pixel is processed in parallel on the GPU (as an example).

It would be really nice if we could do something like this in the near future:

my_image.map_pixels(|pixel| /* do something with pixel and return the new pixel */);

Where the given closure is compiled to SPIR-V and called for every pixel in parallel on the GPU, falling back to the CPU automatically if no GPU is available. RLSL seems like the most promising, pure-rust approach to this at the moment, but is admittedly a while a way from approaching a state suitable enough for use within nannou. Perhaps we could add functions like this with CPU-only support for now and then add in support for GPU parallelism behind the scenes once it becomes possible with something like RLSL?