0 Favourites

Layer transparency breaks for particular effects on iOS

  • Please read my reply post after this initial thread post. I have created a simpler test file for exploring the issue and narrowed the bug down further.

    Problem Description

    The blur horizontal and blur vertical WebGL effects have issues with alpha channels in specific situations when appearing on a layer with transparency and only on iOS (via Safari browser or native):

    • Example situation 1: There are no issues while the blur effects are enabled. However, when the blur effects are disabled then a problem occurs. Specifically the transparent areas of the layer become completely black.
    • Example situation 2: Even while the blur effects are enabled, the same type of problem can occur if and only if an additional effect is placed above the ordering of the blur effects (on the same layer). Specifically I have tested with the Brightness layer to cause this issue.

    Attach a Capx

    dropbox.com/s/2jbgwzjxqx68op3/iOSWebGLIssue.capx

    Description of Capx

    This file provides 4 testing layouts:

    • Layout "test1": Specifically tests situation #1 from above by using an "actors" layer with the blur effects. Note that the Brightness effect is also on this layer but doesn't create any issues. While in Layout "test2" the order of the effect sorting with respect to the Brightness effect is instantly causing the discussed problem.
    • Layout "test2": Specifically tests situation #2 from above by keeping the layers and objects the same as Layout "test1" and only altering the situation by the order of the effect sorting with respect to the Brightness effect.
    • Layout "test3": Further tests situation #2 from above by removing all objects except a single sprite.
    • Layout "testX": Please ignore this. This layout was used for debugging.

    Steps to Reproduce Bug

    • Run the various layouts on an iOS device in Safari.
    • Compare the graphics with a PC or Mac (even a Mac running Safari! Which suggests the issue is only for mobile Safari).
    • For "test1" touch the screen to cause the problem. For "test2" and "test3" just load the layout to see the same problem.

    Observed Result

    The transparent areas of the "actors" layer with the blur effects seem to be distorted when this problem occurs. The distortion appears to be that the transparent areas become solid black.

    This image demonstrates layout "test1" running fine:

    This image demonstrates layout "test2" triggering the bug:

    Expected Result

    I expect the iOS experience to match the desktop experience -- i.e. the transparency of the layers shouldn't be distorted.

    I'm especially surprised that iOS Safari doesn't match Mac Safari in this case.

    Affected Browsers

    • Chrome: (NO)
    • Mac Safari: (NO)
    • iOS Safari: (YES)

    Operating System and Service Pack

    iOS 9.3

    Construct 2 Version ID

    Beta release r229

  • I've explored this bug further.

    I believe I've identified the bug is actually related to how alpha is handled by effects such as "replace color". It's not caused by the "blur effects" as I originally believed -- rather the blur effects mask/hide the bug caused by the "replace color" effects when used in tandem.

    I've created a new CAPX that is even simpler for testing and demonstrating the bug:

    dropbox.com/s/o9gqklsf7646jsl/iOSWebGLIssueSimpler.capx

    The bug occurs whenever there is a texture with transparency which is being affected by the "replace color" effect on a mobile device.

    The transparent pixels of the texture will turn black.

    The diamond texture demonstrates that the presence of a "horizontal blur" effect sitting underneath the "replace color" effect actually negates the bug.

    Not touching the screen:

    Touching the screen:

    I'm hoping this is just a bug in the design of the effects system or the effects themselves and not an issue with WebGL on iOS.

    Note: This bug appears in both Mobile Safari and on an iOS app via Cordova.

  • Construct 3

    Buy Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Buy Now Construct 3 users don't see these ads
  • I can reproduce on an iPad Air 2 running iOS 9.3, but I think the signs are pointing to a mobile Safari or graphics driver bug. I also cannot reproduce on Chrome, Firefox, Edge (on Windows 10) or Chrome for Android, or Safari 9 on a Macbook. This suggests the Construct 2 code is correct (since it works across a broad array of browser engines, OSs and graphics hardware) and that it's possibly not a Safari bug (since it works on OS X). It could possibly be a Safari bug that manifests in the mobile variant only, or a graphics driver bug (I think iOS devices same the share similar graphics hardware/drivers, and while iOS is generally good on driver quality, our past experience is all drivers have buggy behavior at some point).

    Your simpler example uses a third-party effect, which we cannot accept in bug reports. (There's a built-in replace color effect anyway?) I think your theory about transparency turning black is probably correct, but to investigate further can you provide the simpler demo with no third-party addons?

  • I can reproduce on an iPad Air 2 running iOS 9.3, but I think the signs are pointing to a mobile Safari or graphics driver bug.

    Interesting. I have 3 devices running iOS 9.3 and they all have the issue (iPhone 6s, iPod 6th gen, iPod 5th gen). So it might specific to iOS 9.3.

    I also cannot reproduce on Chrome, Firefox, Edge (on Windows 10) or Chrome for Android, or Safari 9 on a Macbook. This suggests the Construct 2 code is correct (since it works across a broad array of browser engines, OSs and graphics hardware) and that it's possibly not a Safari bug (since it works on OS X). It could possibly be a Safari bug that manifests in the mobile variant only, or a graphics driver bug (I think iOS devices same the share similar graphics hardware/drivers, and while iOS is generally good on driver quality, our past experience is all drivers have buggy behavior at some point).

    I agree it is an iOS quirk. I don't know if it's software or hardware. My hope is that it's something simple which can be coded around or accounted for in the writing of effects which deal with transparency.

    Your simpler example uses a third-party effect, which we cannot accept in bug reports. (There's a built-in replace color effect anyway?) I think your theory about transparency turning black is probably correct, but to investigate further can you provide the simpler demo with no third-party addons?

    That was really silly of me. I setup the simpler example with the built-in replace colour effect which suffers from this problem but I started working on trying to find a workaround and I was saving the file into Dropbox as I worked.

    I have found a workaround but it required gutting some of the functionality of the built-in effect.

    Here is a clean version of the simpler example -- i.e. using just the built-in replace colour effect:

    dropbox.com/s/a5toytyweaajg7m/iOSWebGLIssueSimpler_clean.capx

    Here is the copy of my simpler colour effect that does the job:

    /////////////////////////////////////////////////////////
    // Replace color effect
    varying mediump vec2 vTex;
    uniform lowp sampler2D samplerFront;
    //uniform mediump sampler2D samplerFront;
    uniform mediump float rsource;
    uniform mediump float gsource;
    uniform mediump float bsource;
    uniform mediump float rdest;
    uniform mediump float gdest;
    uniform mediump float bdest;
    uniform lowp float tolerance;
    
    void main(void)
    {
    	mediump vec4 front = texture2D(samplerFront, vTex);
    	mediump float alpha = front.a;
    
    	if (front.a == 0.0)
    	{
    		gl_FragColor = front;
    		return;
    	}
    	
    	front.rgb /= front.a;
    
    	// Calculate distance from source color
    	lowp float diff = length(front.rgb - vec3(rsource, gsource, bsource) / 255.0);
    	
    	front.rgb = mix(front.rgb, vec3(rdest, gdest, bdest) / 255.0, 1.0);
    	
    	front.rgb *= front.a;
    
    	gl_FragColor = front;
    }
    [/code:392empeu]
    
    The functionality I ended up droping was the concept of a matching threshold -- so this now replaces all colour in a sprite -- although I don't believe it was actually necessary. I think the issue was related to values of zero alpha being used in the rest of the equation, therefore I identified that if I just returned out of the code as soon as I detected an alpha of zero it actually resolved the problem.
  • Thanks, that's a useful demo. I think you just about figured it out with your workaround. Several effects (including replace color) do un-premultiply (divide by alpha), process, then premultiply (multiply by alpha). If the alpha is 0 (transparent space), it does a divide by zero, which is probably undefined behavior. For some reason only iOS handles this differently, but I suppose it is allowed to, since dividing by zero is a weird thing to do.

    My fix is slightly different - it just skips the divide if the alpha is zero. I patched several other effects which had the same issue as well.

    Thanks for the report, should be fixed in the next build.

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)