Layer transparency breaks for particular effects on iOS

Bugs will be moved here once resolved.

Post » Tue Jun 21, 2016 12:19 pm

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
https://www.dropbox.com/s/2jbgwzjxqx68op3/iOSWebGLIssue.capx?dl=0

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:

Image

This image demonstrates layout "test2" triggering the bug:

Image

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
Last edited by bounty on Mon Jun 27, 2016 3:16 am, edited 3 times in total.
B
10
S
1
Posts: 13
Reputation: 472

Post » Mon Jun 27, 2016 3:11 am

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:

https://www.dropbox.com/s/o9gqklsf7646jsl/iOSWebGLIssueSimpler.capx?dl=1

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:
Image

Touching the screen:
Image

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.
B
10
S
1
Posts: 13
Reputation: 472

Post » Mon Jul 11, 2016 1:46 pm

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?
Scirra Founder
B
403
S
238
G
89
Posts: 24,648
Reputation: 196,133

Post » Sun Jul 17, 2016 12:41 pm

Ashley wrote: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.

Ashley wrote: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.

Ashley wrote: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:

https://www.dropbox.com/s/a5toytyweaajg7m/iOSWebGLIssueSimpler_clean.capx?dl=1

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

Code: Select all
/////////////////////////////////////////////////////////
// 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;
}


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.
B
10
S
1
Posts: 13
Reputation: 472

Post » Tue Aug 02, 2016 10:48 am

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.
Scirra Founder
B
403
S
238
G
89
Posts: 24,648
Reputation: 196,133


Return to Closed bugs

Who is online

Users browsing this forum: No registered users and 1 guest