This cart is just to provoke @zep (or any other true Pico-8 genius) into releasing a fast anti-aliasing demo cart!
The code is a LUA port of that paper:
Note: I don't get how an incremental line drawing routine (a la Bresenham) can be that slow (compared to the native version). 270% cpu usage for 16 lines sigh...
I think it was slow because the code you ported was doing a lot of work per step, a lot of which isn't needed on PICO-8.
Anyway, I took the challenge. I'm lazy, though, so I just tweaked your app instead of writing one from scratch. It's less of a port of a PC app now, making more use of PICO-8 and Lua. I optimized a few things and improved the palette usage. It's still the same algorithm, just taking advantage of some implicit knowledge to avoid some work, e.g. rendering only two pixels instead of three per step. I did change the coverage blend operation to work better in areas of high previous coverage. Also, I got it under half CPU, so I upped it to 60fps too.
Edit: BTW, use ⬆️/⬇️ to change the number of spokes, ⬅️/➡️ to change the spin speed, 🅾️ to toggle AA, and ❎ to pause.
By the way, I was playing with it a bit and you could probably simulate the effects of the electron beam slowing and speeding up in a vectrex-like game by putting a multiplier on the distance that's higher in the middle of the line.
Not sure what math would be simplest to accomplish that. Maybe a parabolic arc centered at the middle of the line segment, or maybe just two ramps that meet in the middle (abs() is handy for that).
I decided to try writing my own routine. I still used your shell, but this is a different algorithm. I'm taking advantage of the fact that PICO-8 has some nice (albeit unrealistic) things like 1-cycle divides. It's a fair bit faster.
(It can be about 15% faster still, if you take out the adjustment that makes diagonal lines appropriately darker. Look for
Not sure if the results are technically correct. I was just winging it, using really basic linear algebra. I did make an effort to get subpixel positioning correct, but I'm not 100% sure it's perfect.
I think this is the fastest I can make it.
Woow - that level of dedication!!
Minor improvement (~-0.1%/line): replace the sqrt by an approximate (given we already calculate w/h majors):
-- no longer needed -- local d=sqrt(w*w+h*h) local k=h/(h*0.9609+w*0.3984) ... local k=w/(w*0.9609+h*0.3984)
Oh, nice! I wasn't aware of that trick. I think sqrt() is about 28 cycles, so that's definitely a win. I put it in.
I also fixed a typo that was culling perfect diagonals, and a precision issue with the angle calculation in the outer loop that was messing with symmetry and creating a dark spoke that traveled around the edge of a very dense fan. You can also step when paused with P2's 🅾️/❎ (tab and Q on my keyboard).
To complete the thread, circ and circfill have their anti-aliased counter parts!
Note: yeah, 10% cpu for a single circle @ 60hz...
left/right: decrease/increase radius
x: turn on/off anti-aliasing
[Please log in to post a comment]