Restricting Viewport Size for Mobile

I’ve been making a bunch of performance optimizations and one thing that I noticed made the most significant difference on mobile is simply disabling my phones “high performance mode”. It sounds counterintuitive but doing this changes the devices display from WQHD to FHD.

Doing this takes me from 30-40fps to 50-60fps with basically no noticeable difference in display quality.

Is there an efficient and portable way to kind of force a FHD resolution on mobile devices?

disabling my phones “high performance mode”

I didn’t know phones had this! It sounds more like a “high quality” mode.

Have you checked to see what the render resolution is before and after you disable the mode? Would it be as simple as not changing the renderer’s pixel ratio by not calling “renderer.setPixelRatio”?

1 Like

Ha, not sure. I noticed that on high performance mode the window.devicePixelRatio is 4 and without it the window.devicePixelRatio is 3. This is true for both portrait and landscape orientation.

First thought is to do something like:

renderer.setPixelRatio( isMobile ? Math.min(3, window.devicePixelRatio) : window.devicePixelRatio );

However, I’m not confident that this will work well on all device types.

This is the usual approach here as far as I know. Usually, you’ll set a max pixel ratio of 2 or 3 and clamp to that.

However, I’m not confident that this will work well on all device types.

I’ve never come across any problems here, why do you think this would be an issue?

1 Like

Because there’s always an issue whenever I deal with something I haven’t messed with before =] Glad to hear that this is a common approach. Thank you for confirming.

@looeee

This is the usual approach here as far as I know. Usually, you’ll set a max pixel ratio of 2 or 3 and clamp to that.
I’ve never come across any problems here, why do you think this would be an issue?

My experience is that there’s unfortunately not really a magic max pixel ratio that can be used to guarantee good performance. My laptop has a 1.25 or so pixel ratio but sometimes just bumping it down to 1 improves performance dramatically. It really just depends on the hardware. It would be nice if there were a simple way to get the physical size of a pixel so at least you can try to target a consistent physical resolution but even then I don’t think that would suffice in a lot of cases.

@titansoftime
4 is the biggest pixel ratio I’ve heard of! What kind of phone do you have? My solution to the scalable performance problem has been to track the webpages framerate and modify the scene or renderer to improve performance or quality until the target framerate is hit. So you could decrease the pixel ratio until you hit 55 fps, for example.

As a bit of a self plug (but hopefully a helpful one) I’ve put together a utility called framerate-optimizer, which helps with this type of tweaking in javascript. There’s a demo that shows it in action on a basic three.js scene, too. It’s inspired by Babylon’s SceneOptimizer but is a bit more flexible. It’s not a perfect solution but has worked pretty well for my use cases.

1 Like

Samsung Galaxy s7 Edge. Yea “High Performance Mode” as it’s called is something somewhat new I noticed in an OS update about 6 months ago. Not sure if this is Samsung proprietary or what.

This is interesting!

Definitely checking this out =]

This is great, I was thinking I might have to build something like this just a couple of days ago :grin:
This doesn’t actually perform any optimizations though, right? Aside from the obvious (switching to smaller textures, lower DPR), what kind of optimizations are you performing?

Considering how often fps can swing (especially on mobile) wouldn’t this frequent change of textures be a potentially significant performance hit?

The types of relevant optimizations you might want to perform really are specific to an application so it doesn’t prescribe any type of optimizations out of the box. It’s not even specific to webgl applications or graphics code, either.

For the applications I’ve used it in I might change the pixel ratio of the render, enable / disable EffectComposer passes, change the shaders / materials used, switch to lower resolution geometry, draw less stuff per frame, etc. All the optimizations are worked through in a priority order so you can decrease specific features first before moving on to others.

@titansoftime

Considering how often fps can swing (especially on mobile) wouldn’t this frequent change of textures be a potentially significant performance hit?

Some operations do cause a framerate hiccup (recompiling shaders, uploading textures), so you can add a wait time to the optimizer so it will wait x amount of milliseconds until it starts to measure framerate again in order to avoid that spike getting averaged in to the measured framerate. Once the framerate has “settled” at its target it will stop trying to optimize until you restart it. I will often restart it when something significant happens to the browser that may change the performance needs, such as resizing the browser or full screening the canvas. That way the quality or performance can be improved based on how it was resized.

Let me know if you guys have any suggestions! It’s not an easy problem and I’d love to hear any ideas on how make scaling performance simpler.

1 Like