Been busy lately working on a card game. The display relies heavily on postcards-in-space 2.5D effect, so early on I had to make a choice of what libraries to use. Starling is my go-to framework, but it did not have any 3D display classes (only a few weeks ago 1.6 was released with a some 3D support) so I decided to use a layered Starling + Away3D display.
I ended up with 2D display list in screen space, and a 3D display list containing flat plane geometry – the cards – in 3D space. While the usual placement worked great, I soon realized there are a few unexpected limitations. Maybe I got spoiled with Starling, it’s flexibility and the strong community support, so I half expected Away3D to offer the same level of support. I was wrong.
The Away3D forums suffer from very low traffic, to say the least. Searching in them is slow and sluggish, and then most results are outdated (3 years and older). Trivial issues soon became real problems when there is almost no one to answer you. At one point I was considering switching to a different engine, but that was too risky. Really, it’s a shame – the Away3D engine could become so much better with some minimal maintenance and adding convenience features, only instead it’s left to decay.
Z-Order, depth and the TextureMaterial
Dealing only with flat object on a flat plane (e.g. cards on a table), I wanted to have the same control over the display objects as I have in Starling. The card objects are plane meshes that display a face image and a back image using Away3D texture material (away3d.materials.TextureMaterial) – and these images typically are rounded rectangle shape. I mention that since we need to use the alpha channel, a trivial feature in Starling.
So TextureMaterial offers a blend mode and renders the image as expected. Now stack up a few of these flat object and place them on the plane in overlapping positions – this will produce an artifact known to every OpenGL coder as co-planar geometry.
To overcome that, assign each object a different Z value, expecting trivial Z-ordering on the plane. This works, but there is a catch: since the plane is viewed from a perspective camera, the renderer will place lower cards on top of upper ones if they are closer to the camera, regardless of the Z value. There is a way around that, if you turn off alpha blending, but then transparent pixels show as black.
To overcome that, TextureMaterial has an alpha threshold feature. Any pixel with alpha value below that threshold will no get drawn. This comes close to what I needed.
Problem solved? not so fast. The resulting images clearly indicate render quality suffered. All edges show noticeable aliasing. Getting rid of the aliasing proved close to impossible. Turning on FSAA? check. Turning on mipmaps? check. Different padding of the card image with transparent pixels did not do much either.
In summary, the versatile TextureMaterial proved inadequate and unhelpful. You basically stuck between two bad choices: either give up z-order control for alpha blending, or give up blending and make do with jagged edges.
Please let me know if anyone knows a solution for this. Any comments are appreciated.
I will talk about possible workarounds in a future post.