What I'm doing
I'm working on an algorithm reactive diffusion which requires per pixel manipulation on canvas. Following the coding train instructional video:
A few changes
Instead of following to the letter I am making a few changes such as either to reduce jank or to speed up time to render, after all this canvas will be surrounded by UI eventually.
- Not using P5.js (I want to learn)
- OffscreenCanvas worker
- Disabled transparency in 2D context
- Using Parallel.js for inline workers.
- Creating the image data directly with ImageData constructor
- Convert image data to Unit32Array as described https://hacks.mozilla.org/2011/12/faster-canvas-pixel-manipulation-with-typed-arrays/
My (un?)realistic requirements
As you can see this is an excersize in performance as well as a pretty animation.
I know that I would love the ability to render full size of the screen of up to 27 inches without much of a wait, sub 1 second would be outstanding. Even a little flash would be fine.
The rules
- No fancy ES6 array methods (perf reasons)
- use ye olde for loop
- keep optimizing
- Use workers to take strain off main thread
- post processing may be an option (CSS)
Getting started
So I know I need a multidimensional array representing X and Y axis, each item in the Y axis will likely be an Object literal with contains information on how to transform the px that it represents, 450,255=red
you get the idea.
So I figured, might as well use a Map of Maps instead of arrays, that's probably going to result in understandable code. They are apparently faster than arrays too, so each map is a 0 indexed wrapper containing objects.
This is actually pretty slow to create (WxH)n Maps so I thought, let's get this into a worker and figure out what to do from here... > 10 seconds to run using Parallel.js π±, it seems much faster in the main thread < 2s so I'm a bit stuck, what am I doing wrong, is newing up a map that expensive?!
From here
Your comments will be really helpful!
I'm also going to look into using wasm for this bit as have had some fun before with emscripten.
Also, am I mad doing this in 2D context should I just go webgl, learn it and stop moaning?
Should I tile the canvas somehow or even use CSS box reflect and render just half the size?
Tell me what you think, and share your tips on intensive jobs in JavaScript. π₯³
Top comments (6)
Webgl is your best bet: you can run your program once for every pixel at the same time
Like a shotgun is to a stapler? Both make holes.
I thought somebody might say that. Glsl rewrite it is π₯π.
Still keeping these optimizations, because I want to be off the main thread.
Not 100% related to your issue but take a look at this repo.
There was also a [this](gpu.rocks/
Edit: the first link was wrong so i changed it, maybe open it again.
I notice with the GPU computation library on my mobile that when running benchmarks, it's very slow and janky when scrolling. Perhaps not good on lower end GPUs. Its a cool project though and maybe the future?
there is also this hacks.mozilla.org/2011/12/faster-c...
but yea glsl is ur best bet, have fun ;)
Yep mentioned that in the post, it works well and makes things a bit easier to manage too.