Log In  

Cart #31654 | 2016-10-24 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
13

Wanted to see if I could make a post-processing effect to distort previously-drawn screen pixels.

It works, but it's probably too slow to be practical - the much, much cooler thing here is a serendipitous glitch-art effect that happens when the screen isn't cleared between frames. Hit the Z/O key to toggle that.

The distortion effect works like this: It copies the frame buffer into the sprite sheet, then redraws a portion of the screen, pixel by pixel, by reading the sprite sheet - but it modifies the sprite lookup position for each pget() call, so you get the spherical bump when it's done.

Can anybody give me some optimization tips? I feel like there's some kinda trickery out there to make it more powerful (the demo here uses radius=26, but if I put it above 28, it drops to half-fps, at least on my laptop). If you've dealt with lots (thousands) of individual pixel draws per frame, let me know what you learned!

I tried using peek() and poke(), but it seemed like it ended up being slower than pset() for drawing pixels one-at-a-time, since the image data is packed with two pixels per byte - so they had to be separated and joined a bunch of times. Maybe there's some super-lean way to do that, which I didn't think of?

P#31656 2016-10-24 08:25 ( Edited 2016-10-25 19:49)

Really quite lovely. 2D ! I remember Commodore Amiga's original Bouncing Ball - it has nothing compared to this ! :)

https://www.youtube.com/watch?v=8EpOq5H8wUI

P#31662 2016-10-24 12:11 ( Edited 2016-10-24 16:11)

Very cool effect. I have been thinking of doing a post-processing pixel thing ever since seeing the screen transitions on Wallflower. Nice job!

P#31667 2016-10-24 13:53 ( Edited 2016-10-24 17:53)

Just now realized the SPHERE is picking up colors from the left and depositing them to the right ! I thought it was just random colors in the sphere - until I looked more closely.

Really an incredible animation, 2D !

P#31669 2016-10-24 14:52 ( Edited 2016-10-24 18:52)

Thanks, y'all!

@kids3ns4t10n: Yeeep, me too - that wobble in Wallflower is great.

@dw817: Hahaha, I never used an Amiga so I never saw Boing Ball, but it's reminding me of some old computer demos I saw as a kid. One of them was this ASCII animation where a turkey stepped into an oven and got cooked - my dad had it on one of the computers at his work.

P#31672 2016-10-24 15:51 ( Edited 2016-10-24 19:52)

Just checked Youtube, can't find it, 2D. Would like to see that. Been years since I've seen ASCII animations.

Did find this though which is thoroughly entertaining ! :D

http://www.incredibleart.org/links/ascii/funnies.html

P#31682 2016-10-24 17:03 ( Edited 2016-10-24 21:03)

Nice effect! There's good roundup of general optimization tips here

edit: after looking at your distortion routine it's fairly tight already, but for easy wins you could:

  • move the dy=y-cy calculation out of the x loop
  • cache dy*dy outside the x loop
  • cache (1-dist) for token + cpu savings
  • use shr() instead of a division by 2

(I'm assuming you care more about cpu perf than token count - some of these will use more tokens.)

  • you could also inline the function directly within draw() to save a teensy bit of cpu, but it depends on how you intend to use the routine. This makes most sense if you're calling it once or in a loop, less so if you need to call it from where-ever.

more time consuming improvements, in order of decreasing likelihood to work:

  • precalculate the start points of dx & dy, and increment them by a constant (haven't fully grokked the code yet but I guess by 1 here?) within the inner loop so you end up doing fewer math operations overall.

  • use lookup tables for.. stuff (table[dist] instead of dist/size2 perhaps), I haven't really thought that one through.

  • there's not much you can do to improve physically pushing pixels to the screen, although if you're drawing a bunch of the same colour pixels at once it may be possible to do use color() before drawing those pixels, so you don't have to pass that as part of the pset call - generally the more parameters you pass to a function, the higher the cpu cost. It's a miniscule amount per call but it adds up if you do it enough.

You'd need to give it far more thought than I've done, and it may not be possible in this particular case, but the basic idea would be

color(sget(x-(1-dist)dx.5,y-(1-dist)dy.5))
loop -- for all the pixels of the same colour
pset(x,y)
end

P#31697 2016-10-24 21:24 ( Edited 2016-10-26 00:40)

Catatafish. If I'm understanding this code you linked to, that will help me.

function foo(argument)
 argument=argument or 5
 --do a thing
end
foo()
foo()
foo()
foo()
foo()
foo()

Let's see if it works:

function fruitme(t)
  if (t==null) t="apple"
  print("*"..t)
end

function fruitme2(t)
  t=t or "apple"
  print("*"..t)
end

cls()
fruitme("banana")
fruitme()

fruitme2("pear")
fruitme2()

Hm ! It works !
Usually I make a comparison for "==null" to determine if a variable is not entered as an argument for a function. This method of, "= or ..." is a unique and smaller one I must admit !

I'm bookmarking your link for further reading and reference.

Thanks !

P#31701 2016-10-24 21:37 ( Edited 2016-10-25 01:37)

That's a really cool effect

P#31757 2016-10-25 15:49 ( Edited 2016-10-25 19:49)

[Please log in to post a comment]

Follow Lexaloffle:          
Generated 2024-03-29 01:53:22 | 0.046s | Q:25