needing a decoration for halloween i decided to port my old fire skull flash experiment to the iPad. since i’ve been doing a lot of iOS coding recently it was just a couple hours to get it up an running nicely. then i wanted to spice it up a bit!
the first thing was a fancy new skull mesh. in the old flash experiment the skull was software rendered in ActionScript (doing vertex projection to 2d in script then using polygon bitmap fill to rasterize) so the mesh had to be pretty simple and was only 1,321 triangles. since the iOS version renders with 3d hardware it can handle something much more complicated so i dropped a 46,960 triangle mesh in for the skull.
the flash version had a glow effect (using BitmapData with ColorTransform and BlurFilter) so i added post processing for the iOS version as well, but also included some desaturation and added contrast in the shader.
after the app was running super smooth on iPad 2 and i was happy with the result i kicked it over to Apple for approval and went to bed. unfortunately the next day i remembered i hadn’t even run it on the iPad 1 so i tried that… and it ran at 12 fps… ouch!
to optimize i ran with the OpenGL ES Performance Detective which looked really cool and gave some good though rather generic advice. i thought it was actually being pretty smart but later realized as i shifted the bottleneck around to different stages while testing that it was just always giving me the same generic advice… kinda weak.
anyhow, i did experiments like rendering without the skull, rendering with 1k tri version of the skull, using 16×16 render targets, short circuiting postproc, changing texture sizes and the like to find out which things were most tripping up the iPad 1.
the biggest thing was post processing effects. a fullscreen shader pass is quite expensive for the iPad 1′s SGX 535. i was able to filter the fire and skull textures offline to get the look i was going for and then just killed the runtime post processing entirely.
the other big thing was the expense of the fire shader. i added a runtime check with glGetString(GL_RENDERER) to detect if the app is running on a SGX 535 and if so use a 256×256 render target for the fire instead of 512×512 to cut down more on shader processing and memory bandwidth.
there were some smaller changes as well like optimizing the mesh more by nuking some tris that would never be visible. in the end i got the iPad 1 up from the 12 fps to 35 fps, the iPhone 4 at 37 fps, and the iPad 2 still running nicely over 60 fps.
so if you need a flaming skull decoration or just a fiery buddy to keep in your pocket you can grab him for free from the app store! be sure to leave a review about how it changed your life and brought you incredible good fortune haha