I’m sure others have encountered this, so I thought I would ask:
We’re developing a title targeting both iPad 1 2. On iPad 2 we would like to use OpenGL ES2 - it enables us to do some nice stuff and the iPad 2 handles it very well. The iPad 1 on the other hand pretty much requires us to use OpenGL ES1 since the frame rates get pretty poor otherwise (12-14 fps with es2 as compared to 30+ with es1).
Currently we switch modes using appcontroller.mm during development. So, how do you handle this problem in general?
Do you just switch using a check in appcontroller.mm (which I assume is very easy)?
Is it still legal to fall back to ES1 on iPad1 or are/will Apple be enforcing ES2 any time soon?
Any advice would be very much welcome.
Thanks in advance!
If you don’t enforce 1.1 it will be on 2.0 with either of the two ARMV7 targets - perhaps you meant that too?
If there is an upcoming one we won’t know it until apple enforces it. Apple does not preinform iOS developer about upcoming changes, you get the mail with the information on the updated ToS or get the updated ToS presented upon login into the dev account as they happen
Thanks for the replies!
Where would I best look for documentation on how I would implement a check for device type in order to switch between ES1/ES2 at startup? I would like to use ES2 on newer devices (to use more advanced shaders) but fall back to ES1 if I’m loading on an older device.
Using the above info I implemented a new class in the Xcode project and modified AppController.mm (OpenEAGL_UnityCallback) like this:
/* commenting out the standard preprocessor code
int openglesApi =
#if defined(__IPHONE_3_0) USE_OPENGLES20_IF_AVAILABLE
kEAGLRenderingAPIOpenGLES2;
#else
kEAGLRenderingAPIOpenGLES1;
#endif
*/
// new devide type detection -------------
UIDeviceHardware *h=[[UIDeviceHardware alloc] init];
NSString *platform = [h platformString];
[h release];
NSLog(@"platform is= %@",platform);
if ([platform isEqualToString:@"iPad 2 (GSM)"]) {
openglesApi = kEAGLRenderingAPIOpenGLES2;
}
else {
openglesApi = kEAGLRenderingAPIOpenGLES1;
}
// code continues
This does the trick for me, and by calling SystemInfo.graphicsDeviceVersion on the Unity side I can detect which version is running and adjust my asset use based on the info. I can now run the project in OpenGL ES2 on the iPad2 and take advantage of the new functionality while being able to gracefully fall back to OpenGL ES1 on the iPad1.
I would appreciate if you would expand on that statement. As far as I have been able to tell, using OpenGL ES 1.1 increases performance on the iPad1. There are other threads indicating this as well and recommending editing appcontroller.mm to not use ES2.
So…please enlighten me?
Edit:
Well, I read to quickly. The main problem here though that the majority of the Unity shaders (this project uses mainly standard shaders) are not optimized for ES2. So while you are technically correct, in term of Unity it is mostly the opposite? ES2 is slower unless you know how to optimize the shaders?
Or have something changed recently re. Unity standard/mobile shaders?
The recent change is that Unity Tech has provided optimized shaders for you, under the “Mobile” heading. There is not a “mobile” version of every shader available, and none of these shaders are 100% optimized for iOS devices, but they’re so close that it probably makes no noticeable difference. If you don’t use those, then you’re going to be using SubShaders that were not designed with iPad 1 in mind. That’s the way shaders in Unity work; they use the first SubShader that they can, even if it’s not a good idea.
The problem at hand is specifically more advanced shaders. Both the standard water (pro) and the Terrain4mobile shaders (while not advanced) run very differently on both devices - naturally as the GPU is quite different in performance.
The OpenGLES2 shaders (which don’t fall back nicely at all) run poorly on the iPad1, which lead me to consider switching to ES1 for the iPad and use the dedicated ES1 terrain shader.
However, I am realizing that perhaps I am going about this the wrong way, It would perhaps be better to stick with ES2 and make sure all shaders fall back nicely and are optimized.
At this point that is quite the investment in time though. Not sure which path to chose to be honest.
Edit (tired):
What I meant was - perhaps it is better to detect the device version in Unity and switch the shader/asset based on that info rather than falling back to ES1 to force shader fallback.
The right path to take would be to find out what costs your frametime actually, the ipad should not have problems just like that, bad FPS are commonly related to overdoing the number of shaderops or killing the fillrate. The later is especially easy, add a transparent sea or alike thats large and you are done with killing the performance in the blink of an eye
Well, it’s easy in this case to determine the culprit. Having a shader that’s blending 4 textures (Terrain 4 mobile) is killing the FPS on the iPad1. I need to make that fallback to fewer on that device, but the iPad2 handles it combined with reflective water without a hitch. The difference is pretty big.