Fabien Sanglard's non-blog
All about the fillrate
Dec 11, 2010.Introduction
I bought "Infinity Blade" yesterday. The game is a lot of fun and has the ability to satisfy both people looking for instant fun and people wishing for a long game while collecting powerful items. At $5.99 it is a bargain, a must have not only for the gameplay but also for its graphical breakthrough, just like Rage HD.
The game programmer in me really wanted to understand the engine and I was especially interested to see the game being released as a universal binary running on iPhone 3GS, iPhone4 and iPad. Those three devices have different capabilities but down the line it is often about managing the fillrate.
Differences
If you don't own the game, here is an animated gif so you can see by yourself:
The resolution difference really shows from iPhone 3GS to iPhone 4, not so much between iPhone 4 and iPad:
| iPhone 3GS | 480x320 |
| iPhone 4 | 960x640 |
| iPad | 1024x768 |
It seems that for all iOS devices the game is rendering all static environment with a single (gorgeous) texture where all lightings effects (shadows, ambient occlusion, specular, diffuse) are prebaked ; possibly using a mega-texture technique. The difference is really in the way the enemies and player are rendered: On iPhone 3GS and iPhone4 we can see bumpmapping and probably specular mapping but no such things on iPad. I may be wrong but it also seems the player's model doesn't get dynamic lighting at all (enemies still do). Overall, the bigger screen gets the less eye candies and I think it is very representative of the difficulty to have a game running well on all major iOS platforms.
In terms of pixels to draw and ratio:
| Machine | Number of pixels on screen | Num_pixels ratio vs previous line |
|---|---|---|
| iPhone 3GS | 153,600 | 1 |
| iPhone 4 | 614,400 | 4 |
| iPad | 786,432 | 1.28 |
An iPhone 4 must draw 4 times more pixels than a 3GS. And an iPad must draw 1.28 times more pixels than an iPhone 4. This is all summarized in the following drawing:
Problem ?
The fillrate is the number of pixels the GPU can generate per second. On iOS it is mostly determined by the velocity of the GPU, the speed of the RAM bus and of course the shaders you execute. The problem while developing a game on iOS is that the GPU raw power/screensize ratio varies a lot from a device to an other: As an example: an iPhone4 and a iPad use the same A2 ship and have the same raw fillrate....but the iPad must draw 28% more pixels.
Most of the time it means the iPad version will miss eye candies compared to an iPhone4. This is the case in "Infinity Blade" where it seems they had to remove bumpmapping, specular mapping and even lighting on the player (the game still looks amazing though). I had the same issue while working on SHMUP engine, fog was sacrified to remain at 60fps.
Feedback
As usual, if you disagree or know better do not hesitate to email me. I see those entries as an opportunity to exchange and learn more. Happy learning, happy coding guys...
Add a comment
Comments (7)
Si l'on se base sur ces chiffres, l'iPad aurait donc un fillrate 1,25x plus important que l'iPhone 4 et une résolution 1,28x plus grande, l'écart devrait donc être compensé par la fréquence. L'explication serait donc à chercher ailleurs qu'au niveau du fill rate (problème de RAM ? l'iPad n'a que 256 contre 512Mo pour l'iPhone 4 et vu la taille plus importante du frame buffer peut être que les développeurs ont manqué d'espace pour les normal et specular maps ?).
Nice blog you are doing,
thanks,
Anael.
void main() {
vec4 vPosNew;
vPosNew.xy = att_vPos.xy;
vPosNew.z = PAGE_CURLED_Z_FLAT;
if (!u_leftPage) {
vPosNew = deform(vPosNew);
}
else {
vPosNew = deformLeftPage(vPosNew);
}
vPosNew.w = 1.0;
gl_Position = mLightPMVMatrix * vPosNew;
var_vDepth = gl_Position.z;
var_vDepth = (var_vDepth + 0.003) / gl_Position.w;
var_vDepth = ((var_vDepth + 1.0) / 2.0);
}
[...]
).
I also moved to the vertex shader some computation which would determine if the pixel was supposed to be even tested for shadowing or not.
On the iPad it was a huge win not to do many divides at the pixel level and doing them at the vertex level, save the result in a varying (which gets interpolated), and use it as is in the fragment stage. The geometry was high enough not to show issues with non perspective correct projection for texture coordinates (the artifact is directly proportional with the size of triangles on screen more or less), but also low enough not to bother the vertex stage too much.
In my case, shifting more work on the vertex stage meant quite more than a 2x performance win.
BTW, your articles are awesome and a very interesting read.
I can't agree more with your post.
Your site's overall value is GREAT.
It's very kind of you to share your research. :)
Keep up the good work.
Applying it to iPhone 4 and iPad example means that the game would display itself on iPad in a viewport matching the same size as it would on iPhone4 (or some other size that yields same overall number of pixels), with the rest of the screen filled with options buttons, hud items moved onto the border and so on.
Also, while this technique does make the actual screen smaller, people have been more forgiving of a smaller screen than of worse graphics, especially since iPad's screen is physically considerably larger than iPhone 4's so the worse graphics is even more obviously worse.
P.S. I stumbled on this site only a few days ago, and I've found it very useful. Thank you for sharing all the information.