In this article, I want to look at what options you have for rendering characters and texts in Actionscript projects using Stage3D.
I’m trying to use the current Flash Player’s 3D abilities as much as possible to implement higher quality and more fluent graphics in my games.
However, there are certain cases where Stage3D is not on par yet with the classic software rendering features of Flash.
In Satellite, I simply used Flex components rendered on top of the 3D context to display my UI and any texts in the game. This gets the job done, but knowing how this case is handled internally leaves a bad taste in my mouth.
If the Flash Player is supposed to show display list content on top of 3D graphics, it will
While I don’t have definitive numbers on this case, I’m sure that the frequent texture uploads and the fillrate of a screen-filling textured quad are not beneficial for the render performance. Also, you are still stuck with rendering portions of your content the old-fasioned way via the CPU.
In Rubberband Racing, all dynamic texts are using the classic
TextField object to render their contents into a Texture, which I then render on separate quads.
This is similar to how the first case is handled internally, but gives you more control over when, and what, is put into textures and how big the quads rendering the images actually are.
Still, Flash will use the CPU to draw the characters. Also, this method is troublesome insofar as you have to implement logic that positions and scales the text properly within the boundaries of the bitmap you are rendering into.
This sounds like it shouldn’t be a big deal, but since the measurements returned by TextField can be inaccurate, getting this right can be annoying.
Another drawback of this method is that scaling the quads containing the text will make it appear blurry, depending on the resolution of the texture.
In my opinion, all content in a Stage3D project should actually be rendered via the graphics card, instead of splitting the rendering between GPU and CPU.
In triple-A titles like Gears Of War or Crysis, the menus and the characters are rendered in 3D with a middleware called Scaleform. Scaleform reads SWF files, converts the contained vector data into polygons and then renders those.
To my knowledge, there was no library available for Flash with a comparable functionality. This is why I decided to implement my own library which, for now, focuses on rendering texts in Flash on the 3D hardware.
firetype reads and parses TrueType fonts using the OpenType file format, converts the characters into polygon objects and renders them via the GPU. (As far as I can tell basically all current TrueType fonts use the OpenType format).
You can check out a live demo of firetype here:
firetype live demo
You can find the source code, firetype tutorials and the current version of the firetype SWC here:
firetype on GitHub
One major advantage of using firetype is that it makes it easier to handle the resolutions of different versions of your Flash or AIR application.
You can arbitrarily scale the texts without worrying about texture resolutions or the performance impact of software rendering on mobile devices.
Each character handled by firetype is rendered entirely on the graphics hardware. This makes it several magnitudes faster than classic software rendered text objects in Flash.
This can be especially interesting for mobile devices, where rendering via the CPU can noticeably slow down performance.
When rendering texts with the help of textures, there are usually significant amounts of transparent space between lines and characters which still cause calls to the pixel shader and texture lookups for each pixel.
This is not an issue with firetype. Since characters are polygon objects, only pixels actually covered by the triangles are rendered.
While rendering does not cause any calculations on the processor, moving any text in firetype requires the transformation matrices of each character to be recalculated.
In my experience, this still takes up only a fraction of your CPU budget in a frame. However, due to this firetype is basically on par with software rendered texts which have been cached as bitmaps.
firetype still wins if you scale or rotate said texts.
firetype caches the polygon data of any character that has been already used.
The first text that you render with a certain font and level of detail will cause firetype to cache each character it encounters for the first time.
This can cause a short lag, which should be below a second in duration, but is still noticeable.
Every subsequent text using the same font and level of detail should cause no lag at all.