Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to use SpriteGPULayer on mobile device #7022

Open
dominikhalvonik opened this issue Jan 31, 2025 · 3 comments
Open

Unable to use SpriteGPULayer on mobile device #7022

dominikhalvonik opened this issue Jan 31, 2025 · 3 comments
Assignees
Labels

Comments

@dominikhalvonik
Copy link

dominikhalvonik commented Jan 31, 2025

Version

  • Phaser Version: Phaser 4 Beta 5
  • Operating system: Android 14 and iOS 17
  • Browser: WebView / WKWebView

Description

When I enter Scene which should create SpriteGPULayer I can see only black screen with the following output in console

#define SHADER_NAME SpriteGPULayer__TexCoordOut_GetTexRes_1TexCount_GetTexture_Tint__FRAGMENT

#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif
#define TEXTURE_COUNT 1
uniform vec2 uResolution;
varying vec2 outTexCoord;
varying float outTintEffect;
varying vec4 outTint;
uniform vec2 uMainResolution[TEXTURE_COUNT];
vec2 getTexRes ()
{
#if TEXTURE_COUNT == 1
float texId = 0.0;
#else
float texId = outTexDatum;
#endif
vec2 texRes = vec2(0.0);
for (int i = 0; i < TEXTURE_COUNT; i++)
{
if (texId == float(i))
{
texRes = uMainResolution[i];
break;
}
}
return texRes;
}
uniform sampler2D uMainSampler[TEXTURE_COUNT];
vec4 getTexture (vec2 texCoord)
{
#if TEXTURE_COUNT == 1
float texId = 0.0;
#else
float texId = outTexDatum;
#endif
vec4 texture = vec4(0.0);
for (int i = 0; i < TEXTURE_COUNT; i++)
{
if (texId == float(i))
{
texture = texture2D(uMainSampler[i], texCoord);
break;
}
}
return texture;
}
vec4 applyTint(vec4 texture)
{
vec4 texel = vec4(outTint.bgr * outTint.a, outTint.a);
vec4 color = texture * texel;
if (outTintEffect == 1.0)
{
color.rgb = mix(texture.rgb, outTint.bgr * outTint.a, texture.a);
}
else if (outTintEffect == 2.0)
{
color = texel;
}
return color;
}
void main ()
{
vec2 texCoord = outTexCoord;
vec4 fragColor = getTexture(texCoord);
fragColor = applyTint(fragColor);
gl_FragColor = fragColor;
}

Uncaught Error: Fragment Shader failed:
0:2(12): warning: extension GL_ARB_gpu_shader5' unsupported in fragment shader 0:3(12): warning: extension GL_EXT_gpu_shader5' unsupported in fragment shader
0:18(36): error: sampler arrays indexed with non-constant expressions are forbidden in GLSL 1.30 and later
_completeProgram phaser.js:191425
createResource phaser.js:191369
WebGLProgramWrapper2 phaser.js:191304
createProgram phaser.js:175499
createShaderProgram phaser.js:173519
getShaderProgram phaser.js:173389
getCurrentProgramSuite phaser.js:173030
run phaser.js:184838
SpriteGPULayerWebGLRenderer phaser.js:78745
renderWebGLStep phaser.js:44069
run phaser.js:180631
run phaser.js:179370
render phaser.js:175698
render phaser.js:11713
render phaser.js:199275
render phaser.js:196518
step phaser.js:17163
step phaser.js:18183
step phaser.js:30454
step phaser.js:30458
step phaser.js:30458
step phaser.js:30458
step phaser.js:30458
step phaser.js:30458
step phaser.js:30458
step phaser.js:30458
step phaser.js:30458
step phaser.js:30458
step phaser.js:30458
step phaser.js:30458
step phaser.js:30458
step phaser.js:30458
step phaser.js:30458
step phaser.js:30458
step phaser.js:30458
start phaser.js:30508
start phaser.js:17992
start phaser.js:17087
texturesReady phaser.js:17067
emit phaser.js:218
updatePending phaser.js:213607
emit phaser.js:199
onload phaser.js:213753
addBase64 phaser.js:213740
boot phaser.js:213573
emit phaser.js:218
boot phaser.js:17047
DOMContentLoaded phaser.js:30060
Game2 phaser.js:17007
createPhaserGame PhaserGame.ts:43
setup PhaserGame.vue:20
createHook runtime-core.esm-bundler.js:2815
callWithErrorHandling runtime-core.esm-bundler.js:199
callWithAsyncErrorHandling runtime-core.esm-bundler.js:206
__weh runtime-core.esm-bundler.js:2795
flushPostFlushCbs runtime-core.esm-bundler.js:385
render2 runtime-core.esm-bundler.js:5993
mount runtime-core.esm-bundler.js:3941
mount runtime-dom.esm-bundler.js:1767
main.ts:27

WebGL warning: linkProgram: Must have a compiled fragment shader attached:
SHADER_INFO_LOG:
0:2(12): warning: extension GL_ARB_gpu_shader5' unsupported in fragment shader 0:3(12): warning: extension GL_EXT_gpu_shader5' unsupported in fragment shader
0:18(36): error: sampler arrays indexed with non-constant expressions are forbidden in GLSL 1.30 and later

Example Test Code

Image

Additional Information

The atlas is in KTX / ASTC8x8 format and it is loaded in preload method via this.load.texture() with object:
ASTC: {
type: 'KTX',
multiAtlasURL: atlasData.data.astc.multiAtlasURL,
},
.
Atlas URL: https://appspowerplaymanager.vshcdn.net/images/lost-kingdom/spritesheet/light-astc8x8.ktx

JSON:

light-astc8x8.json

@dominikhalvonik
Copy link
Author

dominikhalvonik commented Jan 31, 2025

Update:

I tired to execute the code with PNG atlas insted of KTX and I received the same error on mobile device. I checked network tab in devtools just to be sure and I can see that the PNG atlas is loaded:

Image

URL: https://appspowerplaymanager.vshcdn.net/images/lost-kingdom/spritesheet/light-png.png

JSON:

light-png.json

@BenjaminDRichards
Copy link
Collaborator

Some quick notes:

  • GL_EXT_gpu_shader5 is written against OpenGL ES 3.0, which is the basis for WebGL 2. We don't use WebGL 2, just WebGL original flavor.
  • The specific objection is against "sampler arrays indexed with non-constant expressions". Which is always illegal in WebGL, so we're using constant expressions to access the textures.
  • This makes me wonder if the platform is compiling against the wrong version of GLSL. We don't have an explicit #version 100 directive in the shader, but GLSL versions are extremely different and it shouldn't even compile if it thinks it should be using 300 es.
  • Our standard sprite shader uses the same texture code in shaders, for the most part, so if that works then this should work. Unless there's a weird edge case.
  • I should test this on a variety of devices to narrow down how common the issue is, and where the differences lie. Worst case, it's an idiosyncratic behavior by a device that's not compliant with specifications. But if it's more common, then it should be easier to fix.

@dominikhalvonik
Copy link
Author

Hi @BenjaminDRichards ,

I checked several mobile phones—Pixel 6, 7, 8, Samsung Galaxy S22, etc. (I will check iPhones tomorrow). It is partially working. There are no console log errors, but the problem is that the rendered layer's visual on mobile is upside down, and the tiles are overlapping:

Image

This is the same code on PC(PNG atlas is loaded not KTX):

Image

And this is the same code on mobile(PNG atlas is loaded not KTX):

Image

Hope this will help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants