Now it works fine for me. I am very glad I should not have gone to GL.

I basically draw the first (red - at 12 o’clock) gem with a mask, allowing me to see only the right half.
Then I draw the remaining 11.
Then I draw the first again, this time setting the mask only to display the left half.
for( int i = 0; i <= 12; i++ ) { for ( int dullGlow = 0; dullGlow <= 1; dullGlow++ ) { BOOL isDull = ( dullGlow == 0 ) ? YES : NO; CALayer* L = [CALayer layer]; CGImageRef dullImage = [ButtonImages dullImage: i % 12]; CGImageRef glowImage = [ButtonImages glowImage: i % 12]; L.contents = (id) ( isDull ? dullImage : glowImage ); L.bounds = CGRectMake( 0, 0, buttonSize, buttonSize ); L.opacity = ( isDull ? 1.0 : 0.0 ); if( i == 0 || i == 12 ) { CGFloat halfSize = buttonSize / 2.0; CGRect keepLeftHalf = CGRectMake( 0, 0, halfSize, buttonSize ); CGRect keepRightHalf = CGRectMake( halfSize, 0, halfSize, buttonSize ); CALayer* maskLayer = [CALayer layer]; maskLayer.frame = ( i == 0 ) ? keepRightHalf : keepLeftHalf; maskLayer.backgroundColor = [UIColor greenColor].CGColor; maskLayer.edgeAntialiasingMask = 0x0; [L setMask: maskLayer]; } [self.layer addSublayer: L]; layers[ dullGlow ] [ i ] = L; }
Setting edgeAntialiasingMask of the 4 least significant bits to 0 smoothing members on all 4 edges - without this line I would get a seam.
I would be very grateful if someone could explain the mechanics of the masking process - although I got the right result, I did it with trial and error.
Note that the mask is set to (opaque) green, and this is the visible masking area - that is, for the first pass, the green rectangle covers the right half of the image, and it is this love that gets displayed.
I assume that for each pixel it multiplies the layer-level RGBA by the alpha value on the mask-pixel
source share