Sorry for not responding, but I was summing up all my results.
I took @OlexandrC recommendation and decreased the background image’s size to 10000x7000px. I also decided to push it into 1 image. Non-crucial elements were moved as divs below and above the scene. As a result, it gave me ± 5% less of the GPU usage.
Then I tried to separate BG into smaller chunks as @JinDaiCN recommended, but for my scenario (where I need to see everything on max zoom) @samme ideas were much better. On max zoom, combining all chunks resulted in the same, if not worse(1-2%), performance compared to the full image. I don’t have problems with many animated things on the map, so I decided to pick the simpler one, which is making 3 images (10000x7000, 5000x3500, 2500x1750) and scaling them to the correct size, while switching on zoom. It works great, zero complaints. The idea with smaller chunks is great for high-density maps, which I will have to make in the future, so thank you for the hint @JinDaiCN !
What is more, I tried to fix the code with an image on the background set as CSS. I can say “prerender” event was a key that made everything work almost smoothly. If you focus, you will notice jiggling, but it doesn’t break your eyes on mid/high-end devices. It’s a little bit worse on the low-end. The flickering game elements were fixed by setting ‘clearBeforeRender’ inside the config. The only problem was FPS drop, which was noticeable on one of the laptops (3050 Ti).
I did tests.
Settings: roundPixels false, antialias: true, pixelArt: false, clearBeforeRender: false, premultipliedAlpha: true, fps limit 60/165, disabled all FX, imageLoadType set to HTMLImageElemenet, resolution: 1920x911. Tests were made on the Ryzen 6800H iGPU(680m), Phaser 3.88.2
Base:
60fps: No BG - 14% GPU Usage
60fps: BG - 32%
165fps: No BG - 24%
165fps: BG - 60-62%
Problems: none
IMG inside the div
60fps: No BG - 14%
60fps: BG - 17%
165fps: No BG - 23%
165fps: BG - 30%
Problems: image flickering(clearBeforeRender: true fixes it), on one laptop frame drops while moving the camera
LOD
60fps: No BG - 14%
60fps: BG - 17%
165fps: No BG - 23%
165fps: BG - 27%
Problems: none
IMG + LOD
60fps: No BG - 14%
60fps: BG - 14%
165fps: No BG - 23%
165fps: BG - 24%
Problems: image-flickering(clearBeforeRender: true fixes it), frame drops on all laptops, BG flickers while switching the image(preload doesn’t help, requesting animation as well)
So I decided to pick LOD as a good balance between optimization and deep tinkering. Combined with powerPreference “low” in config, I can’t hear a fan, so it’s perfect. I thought about further optimization (huge VRAM usage) with .pvr/.ktx textures and, oh man…
The support which comes from the browser/os sucks. On Win11 Chrome I have only s3tc/s3tc_srgb/bptc(fallback), on Linux Chrome I have astc, etc, etc1, s3tc, s3tc_srgb and bptc(fallback). Each of them makes huge files on the drive (4-8x more than normal .webp/.avif file), there are a lot of problems with the tools (.pvr + s3tcrgb looks great in texture packer, but in phaser it’s dark, like it was without brightness). PVRTexTool hasn’t had tools for encoding the stuff since 2020, and NVCompress creates files that make Phaser crash. After fixing everything(in Texture Packer), I managed to get ± 3% of performance on S3TCSRGB, but I decided to resign; it takes too much effort, and the gains are almost negligible.
I’m not sure what else I can do to optimize it. I believe WebGL itself is a bottleneck right now, so I probably have to wait for WebGPU implementation.
TLDR:
- LOD + IMG BG > LOD > IMG
- LOD + IMG BG requires a lot of tinkering
- IMG BG generates a jiggling effect on camera move, which is more visible on low-end devices
- img via phaser dom is terrible, “transform-origin” switching inside inline styles consumes all gains on performance
- don’t waste your time on GPU textures if you want to optimize it on devices other than a Windows
Thank you @samme @OlexandrC @JinDaiCn