Rendering UI transitions on mobile

I was implementing a kind of defocus blur transition effect between two UI screens and came up with the following shader:

/// viewport resolution (in pixels) in .xy and inverse resolution in .zw
uniform vec4  u_Resolution;       
/// 0...1
uniform float u_TransitionValue;  
/// virtual pixel size
uniform float u_PixelSize;        
uniform sampler2D Texture0;      
uniform sampler2D Texture1;      
out vec4 out_FragColor;
void main(void)
{
	float T = u_TransitionValue;
	float S0 = 1.0;
	float S1 = u_PixelSize;
	float S2 = 1.0;
	// 2 segments, 1/2 each
	float Half = 0.5;
	float PixelSize = ( T < Half ) ? mix( S0, S1, T / Half ) : mix( S1, S2, (T-Half) / Half );
	vec2 D = PixelSize * u_Resolution.zw;
	vec2 UV = (gl_FragCoord.xy * u_Resolution.zw);
	// 12-tap Poisson disk coefficients:
	// https://github.com/spite/Wagner/blob/master/fragment-shaders/poisson-disc-blur-fs.glsl
	const int NumTaps = 12;
	vec2 Disk[NumTaps];
	Disk[0] = vec2(-.326,-.406);
	Disk[1] = vec2(-.840,-.074);
	Disk[2] = vec2(-.696, .457);
	Disk[3] = vec2(-.203, .621);
	Disk[4] = vec2( .962,-.195);
	Disk[5] = vec2( .473,-.480);
	Disk[6] = vec2( .519, .767);
	Disk[7] = vec2( .185,-.893);
	Disk[8] = vec2( .507, .064);
	Disk[9] = vec2( .896, .412);
	Disk[10] = vec2(-.322,-.933);
	Disk[11] = vec2(-.792,-.598);
	vec4 C0 = texture( Texture0, UV );
	vec4 C1 = texture( Texture1, UV );
	for ( int i = 0; i != NumTaps; i++ )
	{
		C0 += texture( Texture0, Disk[i] * D + UV );
		C1 += texture( Texture1, Disk[i] * D + UV );
	}
	C0 /= float(NumTaps+1);
	C1 /= float(NumTaps+1);
	out_FragColor = mix( C0, C1, T );
}

I get wrong results with this fragment shader on some mobile GPUs. For example, Andreno 330 on LG Nexus 5 gives just a series of shifted images instead of blur. Google Nexus 10 runs it just fine. Anyway, I will have to investigate it a bit later.

One thought on “Rendering UI transitions on mobile

  1. Pingback: Rendering UI transitions on mobile: Adreno 330 | Mobile Development

Leave a Reply