Author Topic: Parallax scrolling  (Read 15152 times)

annikk.exe

  • Achiever
  • Ent
  • ****
  • Thank You
  • -Given: 0
  • -Receive: 4
  • Posts: 1,809
Parallax scrolling
« on: November 03, 2010, 09:28:33 PM »
I had this idea that it would be really cool to create a backdrop for Eufloria levels.  Perhaps a high-tech looking green grid.  What I wanted is to create a sort of parallax scrolling effect.

Here is an example of one-dimensional Parallax Scrolling:




As well as the foreground, there are a few different layered backgrounds, and as you travel through the level, they move with the terrain - but at slower speeds, as if they were far away.


Any parallax scrolling system for Eufloria would necessarily need to be 2D because you can scroll up and down, as well as left and right.
Also, you would need some way of deciding what to do when the user zooms in and out.

My feeling is that the backdrop should zoom in with the rest of the game field, but to a lesser degree...governed by that particular backdrop layer's depth value.  That means if the screen is really zoomed in, the zoom value will be something like 0.05 and the X and Y values will end up being extremely high - resulting in a slightly closer look at the backdrop when zoomed in, and a slightly further away view when we're zoomed all the way out.



I propose the system be split into 2 parts; the Paralax engine itself, and a section that contains the code for the backdrop artwork.  The parallax engine's job would be to shift each point that is drawn on the backdrop by an amount proportional to the various offsets and zoom levels that we are monitoring.  By splitting it in this way, you could create an artwork "template" and that would allow others to create their own artwork to use as parallax layers.




1) PARALLAX ENGINE

Read the parameters for the current view; how many layers have been defined?  What are their depths?  How zoomed in are we?  Where is the screen centred?.  Use these to calculate vertical and horizontal offsets for each layer as follows:

Left or Right by an amount equal to the horizontal screen offset from the center divided by the amount we are zoomed in or out.
Up or Down by an amount equal to the vertical screen offset from the center divided by the amount we are zoomed in or out.

Then, for each point that we wish to draw, divide both X and Y values by the SHIFT VALUE.  The SHIFT VALUE is calculated by taking the zoom value and dividing it by the layer depth value for that particular layer.  This is necessary so that we shift far away (ie deep) layers less than layers close to the foreground.


2) BACKDROP ARTWORK

Render each backdrop layer by creating a standardised vector image with all the drawing points as parallax-engine-approved variables, declaring a layer depth for each parallax layer, and shifting each "draw point" by the Shift Value calculated by the engine.






It would be possible to add multiple layers with different depths, I think.  For example, for the deepest layer, you could have a starfield, and for an intermediate layer you could have a green Tron-style grid.  This would look really awesome when scrolling around the map, hopefully.


To pad this idea out some more, I'm going to attempt to list the variables you would need to keep track of.

First of all, you would need a complicated data structure to store the information about the artwork of the parallax layer..
You could create a couple of matrices for this - lets call them matrix X and matrix Y.  Lets take Matrix X as our example, each column in this would represent a whole parallax layer, and each cell within a particular column would contain sequential drawing point coordinate pairs.

For example, if I have a parallax layer containing a single line drawn from coordinates 50,50 to coordinates 100,100, and a second parallax layer containing two lines - one from 125,500 to 15,-400 and the other line -100,350 to -75,175, this is what the matrices would look like:

Code: [Select]
Matrix X
| 50 | 125|
| 100| 15 |
| nil|-100|
| nil| 175|

Matrix Y
| 50 | 500|
| 100|-400|
| nil| 350|
| nil| 175|

Then we know that to draw the line, we just work down the column and use odd numbers as the draw start point, and even numbers as the draw end point.

Columns = parallax layers
Pairs of values going down each column = the coordinates of the lines.


Ok, so what other variables are there?  Well, we need to know how zoomed in we are.  GetCameraZoom() I believe returns a value for that.
We need to know where the screen is centred - we need to know for both X and Y.
We need to know the depth of each layer because this is needed in order to calculate the Shift Value.

Ultimately, we divide each draw point by the Shift Value, and this is what causes what is drawn onscreen to move about realistically like something very far in the distance might do.


Please let me know whether you think this would work the way I am proposing, or if you can spot any flaws in my pseudo-maths.  :>

Sniped50

  • Sapling
  • **
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 97
Re: Parallax scrolling
« Reply #1 on: November 04, 2010, 01:35:57 AM »
Wow... The room's spinning...

Seriously though, I can't see any flaws - mostly because I couldn't be bothered to read most of the text. I'd prefer numbers and equations where possible, if you'd be so kind. 8)

On a side note, you said the artwork requires vector coordinates that the engine could read? Does that mean that simply having some asteroids in the background won't work, or would their coords work fine? Plus, how many layers do you think might be possible; 5, 10, 25, or more?

annikk.exe

  • Achiever
  • Ent
  • ****
  • Thank You
  • -Given: 0
  • -Receive: 4
  • Posts: 1,809
Re: Parallax scrolling
« Reply #2 on: November 04, 2010, 02:05:57 AM »
I tend to conceptualise and generalise first, and fill in numbers later.  I mean... I don't yet know what sort of scale of layer depth would look good.  Maybe 0.1... maybe 0.01.... who knows.  I'll have to play around with the engine and see.  :>  The layer depth affects how far away that particular layer will look when you're scrolling around/zooming in and out.  Is there some specific numbers you were after?

I did fill in some pseudo-equations, though.  Just that they are kind of in sentence form.. :p

Regarding using asteroids as parallax layers.  This WOULD work, but the asteroids would still be selectable by the player while they are moving around, which would look kind of wrong.  So after a lot of thought about this I figured it's probably best to keep asteroids as foreground-only, interactive objects like they normally are.
It would mess with your head though.  You would be able to change the layout and scale of the level simply by scrolling and zooming around it....  It would be like some kind of crazy Escher thing :p

I am not sure how many layers would be possible, it depends on how efficiently drawings are rendered by the game on each game cycle, and also on the complexity of the layers.  If you only had 1-2 lines in each layer, it would handle that rather easily, I imagine.. :>  But if you have complciated vector art, EG 400+ lines, it might not manage so many layers without slowing down a lot.

Pilchard123

  • Tester
  • Old Oak
  • ****
  • Thank You
  • -Given: 4
  • -Receive: 24
  • Posts: 932
  • Eufloria: Yes
Re: Parallax scrolling
« Reply #3 on: November 04, 2010, 02:39:41 AM »
Would a MASSIVE LevelDraw() work? I can't work on it right now - college is being...well, college, so this is only guesswork. You could draw something a bit like the rally button with a few tweaks, though it would be on top of the asteroids.

Sniped50

  • Sapling
  • **
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 97
Re: Parallax scrolling
« Reply #4 on: November 04, 2010, 06:33:52 AM »
I'm not looking for specific numbers, annikk. I just prefer maths over english as school subjects. It's much easier to understand... :P

As for the background asteroids, I thought you could make them non-selectable. Or did I fall asleep at the computer that time... ? Anyways, even if you can't do that, you could actually make your own(admittedly crude) 3D levels. Oh, how cool would THAT be? Hmm?!? :D

The resulting levels might make my head spin even more though...

Terrial

  • Sapling
  • **
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 66
Re: Parallax scrolling
« Reply #5 on: November 04, 2010, 10:31:51 AM »
HA! annikk!!! you never cease to amaze! 

bryseron

  • Seed
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 6
Re: Parallax scrolling
« Reply #6 on: November 04, 2010, 04:23:07 PM »
Sounds incredibly cool.

annikk.exe

  • Achiever
  • Ent
  • ****
  • Thank You
  • -Given: 0
  • -Receive: 4
  • Posts: 1,809
Re: Parallax scrolling
« Reply #7 on: December 31, 2010, 11:39:38 AM »
I made a start on this tonight.  :>

It looks freaking awesome.

Main problem right now is that it doesn't look right when you zoom in and out.  For panning around it looks sick though :D


UPDATE: Oh god...Why can't I just pick something easy...
« Last Edit: December 31, 2010, 12:23:50 PM by annikk.exe »

annikk.exe

  • Achiever
  • Ent
  • ****
  • Thank You
  • -Given: 0
  • -Receive: 4
  • Posts: 1,809
Re: Parallax scrolling
« Reply #8 on: January 01, 2011, 02:02:00 AM »
Got it working :>

This is something really quite special.  I am super-excited to show it to you guys, but I'm going to tweak the artwork a bit first to make it look as nice as possible.  :>

Widget

  • Sapling
  • **
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 97
Re: Parallax scrolling
« Reply #9 on: January 01, 2011, 03:40:57 AM »
Wow! Can't wait to see what you've managed to make of it. You never cease to amaze me  ;)

Pilchard123

  • Tester
  • Old Oak
  • ****
  • Thank You
  • -Given: 4
  • -Receive: 24
  • Posts: 932
  • Eufloria: Yes
Re: Parallax scrolling
« Reply #10 on: January 01, 2011, 05:11:26 AM »
You don't go around under "omnicoder" anywhere do you? He's sickeningly good at scripting/programming (though he doesn't use use your chevron-smiley, so I'm guessing the answer's 'no').

annikk.exe

  • Achiever
  • Ent
  • ****
  • Thank You
  • -Given: 0
  • -Receive: 4
  • Posts: 1,809
Re: Parallax scrolling
« Reply #11 on: January 01, 2011, 05:40:46 AM »
That's a negatory.  annikk.exe is my main screen name, though there are a few others I use for certain things.  Omnicoder is not one of them.


The stars disappear when they go behind an asteroid now.  However, doing that is extremely computationally expensive so I've had to scale back the number of stars as well as fade them out when the user has zoomed out a lot (because too many are displayed at once and the FPS drops to 1)

It's looking pretty fluid and nice at the moment.  The alpha fades out just before they disappear from teh zoom level which looks really sweet.


There's still something not _quite_ right with the zooming.  My pro 1337 hax coder cousin Joel is coming over tomorrow so maybe I can persuade him to have a look at it.  :>

AWS

  • Achiever
  • Arboreal Being
  • ****
  • Thank You
  • -Given: 0
  • -Receive: 2
  • Posts: 275
Re: Parallax scrolling
« Reply #12 on: January 02, 2011, 01:05:02 AM »
so... any sneak peeks at your progress so far? just a still image or 3 will suffice?!

 ;D

annikk.exe

  • Achiever
  • Ent
  • ****
  • Thank You
  • -Given: 0
  • -Receive: 4
  • Posts: 1,809
Re: Parallax scrolling
« Reply #13 on: January 02, 2011, 12:08:07 PM »
No previews yet I'm afraid.  It's getting better by the hour right now so I don't want to show you the shabby version when the final one is going to be epix.  :>

Cousin Joel came over today and we had a good look at the engine.  We've managed to improve it radically.  What was once 200 lines of code and comments is now about 40.  The engine is the most performance-oriented thing I have ever written.  With Joel's considerable help, we've been able to make it extremely efficient.  Whereas before, trying to display 500 stars would actually crash the game upon trying to load, now I can display 1000 stars and still get around 5fps.

The appearance of the stars has drastically improved too, as I discovered I could draw a single sprite that looks _exactly_ like a star.  It's a lot more star-like than the crosses I was using before, and has a nice soft glow around it.  :>

The next change will be to add variable numbers of parallax layers - currently it does only 4 layers, and I want 100 layers for a 1000 star map.  It's quite an undertaking because each layer has a number of attributes associated with it, namely Red channel, Green channel, Blue channel, Alpha, z-depth, and Fade-Out threshold.

Due to the number of layers involved, I may also then need to find some mathematical way of specifying the z-depth and fade-out threshold so that I don't have to write out 200 individual values, try them, discover it's a bit off, and have to redo them all.  :>

pigpenguin

  • Seedling
  • **
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 37
Re: Parallax scrolling
« Reply #14 on: January 02, 2011, 12:36:17 PM »
*cough* *cough* 100 layers?!?!?! you my friend aim high... may i ask why you would need that many layers?

annikk.exe

  • Achiever
  • Ent
  • ****
  • Thank You
  • -Given: 0
  • -Receive: 4
  • Posts: 1,809
Re: Parallax scrolling
« Reply #15 on: January 02, 2011, 01:02:08 PM »
Quote
may i ask why you would need that many layers?

Good question - it's a little complicated, so lets take some time.

At the moment, when you zoom out such that you pass the 4th layer's threshold, the engine goes from rendering 250 stars onscreen at once, to 0.  Suddenly the FPS goes from 5, to 60.  Zoom in again 1 step, and it goes back to 5 fps.  This feels incredibly clunky.

Having 100 layers means I can fade the layers in and out in much smaller intervals.  So instead of stars fading in and out in chunks of 250, they would fade in and out in groups of 10, for a far more aesthetically pleasing parallax effect.

The effect is already quite cool because stars don't instantly wink out when they pass the threshold, instead their alpha starts fading away and the rendering stops when the alpha is less than 0.2.
Imagine how fluid and beautiful this would be with 100 layers instead of 4!

It also means that I could have much finer control over how many stars are onscreen at any given level of zoom.  The half a dozen of the layers at the far foreground (lowest z-depth) might even be able to stay rendering even when you zoom all the way out - so there would always be at least some stars no matter what the camera is doing.  :>

I don't think adding 100 layers would increase the CPU burden at all because either way you do it, it's still a total of 1000 stars.  In fact I have a strong suspicion it might afford much better performance because it will be possible to fine-tune how many stars are onscreen at up to 100 different zoom levels.

annikk.exe

  • Achiever
  • Ent
  • ****
  • Thank You
  • -Given: 0
  • -Receive: 4
  • Posts: 1,809
Re: Parallax scrolling
« Reply #16 on: January 02, 2011, 01:15:30 PM »
The code to check if an asteroid is covering a star is probably the most insane bit, by the way.

First we make arrays of all visible asteroids and all visible stars.

Then we carry out a 1dimensional check (for the X axis) for each visible star against each visible asteroid.  This is computationally less expensive than doing a proper 2D check and rules out 90% of stars.

The X dimension is checked first to see if an overlap can be ruled out.  For example, consider an asteroid at coordinates (0,0) with a radius of of 100.  Now consider a star that may - or may not - be overlapping (or "behind") the asteroid.
We find that the star has an X-coordinate of -573.
Is it overlapping with the asteroid?

We can say for sure that it isn't, because even if the Asteroid Y was equal to the star's Y, the radius of the asteroid is still smaller than the distance between the centre of the asteroid and the star (which is effectively a geometric point, and has no radius).  Thus we exit the loop without having to perform additional expensive calculations on this cycle.

But suppose it was a (0,0) asteroid with radius 100, and the star's X coordinate turned out to be 30.
Now there's a possibility that they are overlapping, so next we check the Y coordinate using the same method.  This lets us rule out another 8% of stars leaving only 2% that require the more expensive 2D check.
At this point we have established a "bounding box" around the asteroid.  The only thing left to check is if the star might be hiding in the corners of the box, but not actually inside the circular asteroid.

At this point, we no longer have a choice and we have to carry out the expensive 2D check to see if they are overlapping.  The 2D check basically amounts to some simple pythagoras, but we've avoided using the dreaded math.sqrt entirely due to the relatively heavy processor cost.  However, the 2D check contains 3 exponentials which are slightly costly, and these are the reason why we try to not use this type of check unless we absolutely have to.



For comparison, the engine I had this morning always used the expensive check.
« Last Edit: January 02, 2011, 01:18:45 PM by annikk.exe »

annikk.exe

  • Achiever
  • Ent
  • ****
  • Thank You
  • -Given: 0
  • -Receive: 4
  • Posts: 1,809
Re: Parallax scrolling
« Reply #17 on: January 02, 2011, 03:24:33 PM »
I've implemented variable layers now.  Works great, and looks stunning.  :>
Currently running 1000 stars on 100 different layers.  I am also specifying colours and z-depth on a per-star basis, so the whole thing looks beautifully organic now.


I've been able to mathmatically generate some suitable values for all of the arrays except for one - the fade threshold.
After toying with different formulas for a while, I've decided that the best and only way to do it is to tune it manually.

That means hand-tuning 100 variables.

Think I'll leave that till the morning... uh.... or whenever it is that I wake up.

pigpenguin

  • Seedling
  • **
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 37
Re: Parallax scrolling
« Reply #18 on: January 02, 2011, 04:14:49 PM »
Think I'll leave that till the morning... uh.... or whenever it is that I wake up.

I think that is called the afternoon (assuming your on a winter break :P)

And now your killing me I want to see this soooo bad now :/

annikk.exe

  • Achiever
  • Ent
  • ****
  • Thank You
  • -Given: 0
  • -Receive: 4
  • Posts: 1,809
Re: Parallax scrolling
« Reply #19 on: January 03, 2011, 02:48:42 AM »
Just give me a day or two... :>  I promise it'll be worth the wait.

AWS

  • Achiever
  • Arboreal Being
  • ****
  • Thank You
  • -Given: 0
  • -Receive: 2
  • Posts: 275
Re: Parallax scrolling
« Reply #20 on: January 03, 2011, 03:54:59 AM »
tick....


.....tock....


.....tick......


......tock.......

;D

pigpenguin

  • Seedling
  • **
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 37
Re: Parallax scrolling
« Reply #21 on: January 03, 2011, 04:09:23 AM »
[Insert jeopardy music here] :P
(I tried typing it out in du dah du's but it just made me look retarded :P)

AWS

  • Achiever
  • Arboreal Being
  • ****
  • Thank You
  • -Given: 0
  • -Receive: 2
  • Posts: 275
Re: Parallax scrolling
« Reply #22 on: January 03, 2011, 04:11:30 AM »
[Insert jeopardy music here] :P
(I tried typing it out in du dah du's but it just made me look retarded :P)
lol.
when i see the tick tock's i hear the countdown music!

Bonobo

  • Achiever
  • Old Oak
  • ****
  • Thank You
  • -Given: 139
  • -Receive: 12
  • Posts: 670
  • Eufloria: Yes
Re: Parallax scrolling
« Reply #23 on: January 03, 2011, 06:31:11 AM »
Funny, when I read this I heard the music of Twilight Zone in my inner ear :D

Alex

  • Administrator
  • Ent
  • *****
  • Thank You
  • -Given: 3
  • -Receive: 14
  • Posts: 1,035
Re: Parallax scrolling
« Reply #24 on: January 03, 2011, 09:54:44 AM »
I don't think you need to be doing exponentials for the check to see if the star is occluded. Get the position of the star at the asteroid layer and do a point in circle check (dx*dx + dy*dy < radius*radius).

annikk.exe

  • Achiever
  • Ent
  • ****
  • Thank You
  • -Given: 0
  • -Receive: 4
  • Posts: 1,809
Re: Parallax scrolling
« Reply #25 on: January 03, 2011, 10:06:48 AM »
Instead of:

Code: [Select]
(dx*dx) + (dy*dy) < (radius*radius)
I have:

Code: [Select]
(dx^2 + dy^2) < radius^2(that's what I mean when I say "exponentials")


It's the same calculation, but is one more efficient that than the other?

Alex

  • Administrator
  • Ent
  • *****
  • Thank You
  • -Given: 3
  • -Receive: 14
  • Posts: 1,035
Re: Parallax scrolling
« Reply #26 on: January 03, 2011, 08:11:59 PM »
Ah, I see. No, that should be fine.

Would be good to give access to the quad tree, then you could test only localised asteroids to where your star is. Maybe there is already access to the quad tree actually. Will look into that later.


annikk.exe

  • Achiever
  • Ent
  • ****
  • Thank You
  • -Given: 0
  • -Receive: 4
  • Posts: 1,809
Re: Parallax scrolling
« Reply #27 on: January 04, 2011, 05:24:08 AM »
Not a big priority now as I've managed to make the engine efficient enough to work alongside everything else, and still look good.  Thankyou though :>

I have to say, tweaking code to optimise it for performance is incredibly satisfying.  I can't believe how much more efficient the engine is now than when it started..

pigpenguin

  • Seedling
  • **
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 37
Re: Parallax scrolling
« Reply #28 on: January 05, 2011, 02:27:45 PM »
Well i played frontier (well i guess you could say play i kinda kept zooming in and out :P)
It looks awesome dude if i manage to figure out what part of the code it is may I use it in my level (Giving credit of course :D)

annikk.exe

  • Achiever
  • Ent
  • ****
  • Thank You
  • -Given: 0
  • -Receive: 4
  • Posts: 1,809
Re: Parallax scrolling
« Reply #29 on: January 05, 2011, 02:39:16 PM »
If you wait a couple of weeks I'll be releasing a template for it, along with a nice implementation guide with lots of formatting/bbcode.  :>

annikk.exe

  • Achiever
  • Ent
  • ****
  • Thank You
  • -Given: 0
  • -Receive: 4
  • Posts: 1,809
Re: Parallax scrolling
« Reply #30 on: January 05, 2011, 09:44:54 PM »
Note for myself later on:

Zooming in and out should slightly affect the z-depth of the stars.  Maybe need a "currentZdepth" variable that is adjusted according to the "set" z-depth.