Log In  


Cart #mcg_qndpg_1-0 | 2024-12-13 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
6

Hello, everyone! I'm back with another Quick 'N' Dirty cart!

This time, I've put together a little planet generation and rendering system I'm looking to use in a bigger project. From the cart's intro comments:

This is a very very work-in progress planet generator. I'm not (yet) going for huge 
amounts of complexity or variation in my texture generator. Rather, right now, I'm
working to make as *performant* a planet generator and renderer as I reasonably can.

To generate terrain, I'm using the diamond-square algorithm to rende a 64x128 pixel
heightmap on the bottom half of the sprite sheet, which is mapped to the bottom half
of the PICO-8 map. To help ensure that we're not impacting performance, I've added some
break logic to the rendering routine that lets us stop processing once we hit a
certain CPU threshold, spreading the work across a few frames. This is fast enough that
planets render in well under a second, even with the added overhead of the break
logic.

Of note here is that planet generation is entirely deterministic and stems from a
single seed value. If you want to build a galaxy of planets, all you need to do is
store a number per planet and re-render them on the fly.

To render, I'm relying on tline to draw a linearly-banded UV map that reads from the
bottom half of PICO-8's map and draws a series of horizontal tlines across the unit
circle. At higher rotation rates, this is very obviously not an accurate way to draw
a sphere, but it *is* a blazingly *fast* way to do it, and at slow enough rotation
rates, it's good enough to fool the casual observer. Rendering times increase as the
planet grows, but even when the planet takes up most of the screen it only eats about
30% of the standard update cycle's CPU time.

Future improvements will be focused on adding some good variety to the planets being 
generated, along with features like polar regions and wind/precipitation-based biome
coloring.

Arrow keys to zoom and control the speed of rotation; O/Z to generate a new planet.

Have fun!

6


This is really cool, I would recommend implementing into some sort of planet simulator, If Pico-8 has enough tokens.


Thank you! Right now the core routines aren't too heavy, token-wise, so I've got high hopes of being able to use this with a lot more functionality built into the cart. It's really the speed with which this works that's of value to me: I can afford to be doing some fairly heavy lifting quickly in the background without impacting the user experience. Instead of having to store tons of data about each planet, I can regenerate it all from a single seed number in the time it takes to do a small transition animation.

(I'll probably still end up in a multi-cart scenario for what I'm thinking of doing, but that's ok!)


1

Impressive trade-off.
Pixels have a constant speed on each line, so they are going too fast on the extremities and too slow in the middle, but overall pretty convincing and done with just one tline per screen line ! nice trick.
There's still one thing that seems off : the back of the planet feels like a stretched flat surface rather than a half sphere : mountains take much less time to travel the back side of the sphere than they take to travel the front.
Maybe try displaying both sides at the same time to see where the scaling is off ?

About the visible rotation, I'm wondering, with map or spr, the call overhead is relatively small : if you for example implement a toric map and the real map corner is onscreen, the overhead of calling 4 times map to cover the screen is minimal, it's the number of pixels written to that is the biggest factor.(this is 4 map calls with smaller surface instead of one full screen map. Overhead is significant if you fill the screen with pset calls)
If the same applies for tline, you could maybe replace each tline with three tline segments so the pixels would have slower speed on the sides and a higher speed in the middle , three speeds in total instead of one for each line.


Thank you, @RealShadowCaster!

Yeah, the size of the map is definitely off; I'm going to do some digging into that to see if I can't make some adjustments there. (There's got to be a simple explanation for this, most likely a bit of a forehead-smack somewhere.) I might do a flat mapping with a moving bounding-box to try and figure this out...

I've been toying with multiple calls to tline() for each line on the sphere, too. I might dive into that next–especially if the cost, as you note, is in the pixels themselves (TIL!). That would give me a much-gooder-enough approximation than a single tline() pass per line.



[Please log in to post a comment]