I’m rendering circles in a 2D project using Quad+MeshRenderer objects with a custom shader that takes care of producing the circle shape and fill color. The circles are relatively large (~500px diameter) and may partially overlap each other. There’s usually less than 10 of them on screen at a time.
My initial plan was to fill them with some fancy procedural effect, but I’m finding that I can’t even do very simple shading without running into performance issues on an iPhone 4s. I’m wondering if I’m doing something obvious wrong or if it’s expected that this class of hardware can’t render this type of workload at 60Hz. I’m estimating that it’s shading somewhere between 0.5M - 1.0M pixels per frame. They’re all alpha blended and Z writes are turned off.
Here’s the most simplified version of the shader that still produces stutter – it attempts to darken the circles toward the centers, taking into account two neighbor (overlapping) circles. FWIW, I’ve tried putting “lowp” pretty much everywhere, without much success, perf was still bad.
uniform float _Radius;
uniform vec4 _Center;
uniform vec4 _Color;
uniform vec4 _Left;
uniform vec4 _Right;
varying vec4 world_pos;
#ifdef VERTEX
void main()
{
world_pos = _Object2World * gl_Vertex;
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
#endif
#ifdef FRAGMENT
// compute squared length
float sql( vec2 v )
{
return v.x * v.x + v.y * v.y;
}
void main()
{
vec2 p = vec2( world_pos.x, world_pos.y );
vec2 c = vec2( _Center.x, _Center.y );
vec2 d = c - p;
gl_FragColor.rgb = _Color.rgb;
float sqld = sql( d );
float rsquared = _Radius * _Radius;
// compute minimum squared dist to relevant circle centers
float mind = min( min( sql(_Left.xy-p) , sql(_Right.xy-p) ), sqld );
// darken based on dist
gl_FragColor.rgb *= 0.3 + 0.7 * mind / rsquared;
// produce shape by setting alpha to 0 outside circle radius
gl_FragColor.a = 3.0 * (rsquared - sqld );
}
#endif
Thanks for any tips!