Performance Problems with LightmapOnly Shader (On the iPad).

Our iPad game was running really slowly, dipping down to 20 fps, even though there was not much going on. I finally found out that the reason for the slowdown was the lightmap shader assigned to the ground (which covers most of the screen).

When I changed to the supplied fast diffuse shader I got framerates from 40 to 55 depending on amount of critters on screen.

So, I tested the LightmapOnly shader that comes with penelope demo, as well as some others, but performance was rather poor. So, is it simply not possible to use lightmaps on an iPad? I know its fillrate perfomance is not great, but surely multiplying 2 pixels together should not cause such issues?

Here's the profiling output with the fast diffuse assigned (on ground only):

iPhone Unity internal profiler stats: cpu-player> min: 13.1 max: 29.6 avg: 20.3 cpu-ogles-drv> min: 2.8 max: 3.9 avg: 3.1 cpu-waits-gpu> min: 0.2 max: 15.6 avg: 5.3 cpu-present> min: 0.3 max: 0.6 avg: 0.4 frametime> min: 17.2 max: 37.5 avg: 25.0 draw-call #> min: 50 max: 53 avg: 50 | batched: 1 tris #> min: 9528 max: 10284 avg: 9583 | batched: 6 verts #> min: 5721 max: 6033 avg: 5743 | batched: 6 player-detail> physx: 1.0 animation: 3.3 culling 0.0 skinning: 4.2 batching: 0.0 render: 3.0 fixed-update-count: 1 .. 2 mono-scripts> update: 2.5 fixedUpdate: 0.4 coroutines: 0.0 mono-memory> used heap: 380928 allocated heap: 479232 max number of collections: 0 collection total duration: 0.0

this works ok.

And here is the same with the lightmapped shader, in roughly the same situation.

iPhone Unity internal profiler stats: cpu-player> min: 25.7 max: 47.2 avg: 36.7 cpu-ogles-drv> min: 2.0 max: 3.7 avg: 2.6 cpu-waits-gpu> min: 11.2 max: 33.9 avg: 23.9 cpu-present> min: 0.3 max: 3.3 avg: 0.7 frametime> min: 31.2 max: 52.0 avg: 42.3 draw-call #> min: 28 max: 42 avg: 33 | batched: 1 tris #> min: 7248 max: 8558 avg: 7600 | batched: 4 verts #> min: 4501 max: 5213 avg: 4711 | batched: 4 player-detail> physx: 1.3 animation: 2.6 culling 0.0 skinning: 2.4 batching: 0.0 render: 2.5 fixed-update-count: 1 .. 3 mono-scripts> update: 3.2 fixedUpdate: 0.5 coroutines: 0.1 mono-memory> used heap: 368640 allocated heap: 479232 max number of collections: 0 collection total duration: 0.0

So, the obvious change is cpu-waits-gpu, which I assume is from the more costly shader on the ground object.

What's going on here? I see recommendations all over that we should use lightmapped surfaces instead of using regular lighting, but it simply doesn't seem possible here...

Thanks a lot for any input!

Kjetil

You need a GLSL shader to get the best performance, under OpenGL ES 2.0. (Are you using GLES 2.0?) Try this and let us know how it works.

Shader "Mobile/Lightmap Only" {
	
Properties {
	_MainTex ("Base (RGB)", 2D) = ""
	_LightMap ("Lightmap (RGB)", 2D) = "" 
}

SubShader {Pass {
	GLSLPROGRAM
	varying mediump vec2 uv;
	varying lowp vec2 uv2;
	
	#ifdef VERTEX
	void main() {
		gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
		uv = gl_MultiTexCoord0.xy;
		uv2 = gl_MultiTexCoord1.xy;
	}
	#endif
	
	#ifdef FRAGMENT
	uniform lowp sampler2D _MainTex, _LightMap;
	void main() {
		gl_FragColor = texture2D(_MainTex, uv) * texture2D(_LightMap, uv);
	}
	#endif		
	ENDGLSL
}}


SubShader {Pass {
	BindChannels {
		Bind "vertex", vertex
		Bind "texcoord", texcoord0
		Bind "texcoord1", texcoord1
	}
	SetTexture[_MainTex]
	SetTexture[_LightMap] {Combine texture * previous}
}}

}