Page 1 of 1
Z-buffer in Love2D?
Posted: Wed May 14, 2014 11:59 pm
by hyouko
I've been working on extending my Ludum Dare
entry to support some more complex objects, and I'm bumping up against the limits of what I can do with my z-ordering algorithm. Right now, aforementioned algorithm is a simple mergesort that operates on a single z-coordinate per object. This works fine for small objects (like the voxel-y blobs of snow) but starts to fall apart for larger objects that spread out a bit on the z-axis.
Is z-buffer support something that could either be hacked in or added to a future love2D release?
Re: Z-buffer in Love2D?
Posted: Thu May 15, 2014 12:06 am
by slime
Hardware z-buffers on GPUs doesn't care/know about image transparency - if you draw a 512x512 image with every pixel except 1 completely transparent, the z-buffer won't behave any differently than if all 512x512 pixels were completely opaque. Plus, alpha blending only works correctly if the actual draw order of objects are sorted back-to-front (and then you can still get into trouble if things intersect on the z-plane.)
These issues make z-buffer support not really worth much for 2D games.
Re: Z-buffer in Love2D?
Posted: Thu May 15, 2014 11:00 pm
by hyouko
I'm definitely an edge case here - my game isn't actually 2D, and (at least for now) I'm only rendering solid objects (no alpha transparency).
Re: Z-buffer in Love2D?
Posted: Thu May 15, 2014 11:30 pm
by slime
Yeah, there are a few niche cases that work with it. If a really good API for it can be figured out, then it might make it into a future version - but its incompatibilities with most traditional 2D stuff makes that challenging.
You can hack it in right now using LuaJIT's FFI with raw OpenGL, maybe I'll make some example code for that later.
Re: Z-buffer in Love2D?
Posted: Fri May 16, 2014 9:32 am
by T-Bone
I'm not sure of exactly what you're doing, but doing a mergesort every frame sounds expensive. What I've found in projects where I've wanted to set the drawing order is to do lazy sorting. I do an O(n) "sort" that goes through the list a single time and looks for neighbours in the list that are in the wrong order (and swap their positions if that's the case). This is then done every frame. It's way faster for many objects, and while you cannot guarantee that for every frame the list will be sorted perfectly, it converges really fast if you can keep 60 FPS and have a few hundred objects.
I'm not sure if this approach fits your application (I'm a bit confused on what Z-buffering is) but maybe this will help anyway
Re: Z-buffer in Love2D?
Posted: Tue May 20, 2014 3:05 am
by hyouko
Wikipedia has a fairly good explanation of z-buffering here:
http://en.wikipedia.org/wiki/Z-buffering . The TL;DR version: as you render to the screen, in addition to R/G/B, each pixel gets assigned a depth value for how far away from the camera that pixel is. This way, you can tell when something you're trying to render is obscured by something in front of it and not draw over it (or, if it *is* on top of of whatever was there before, you update the depth values to match the new object).
Your method is pretty close to what I've used in the past for this - basically one pass of a bubble sort. In this particular case, I am potentially adding or removing hundreds of objects per frame (as more of the voxels scroll in / out of view), so there's a good chance the player might notice the out-of-order objects. That said, there's a lot that I could still do to optimize here! One in particular would be to avoid creating and destroying so many objects and re-use from a set pool instead - I'm sure that I'm giving the Lua garbage collector a hernia with my current methodology.