Adapting to a change in screen size and device pixel ratio

I have a scene with a full screen GUI that displays strangely if I move the window from my retina laptop screen (devicePixelRatio: 2) to my standard monitor (devicePixelRatio: 1).

To address this, I’m resizing the canvas & engine if the devicePixelRatio changes. (For unrelated reasons, I want the canvas to match the screen size so resizing the window causes it to crop instead of scaling)

  function resizeCanvas() {
    canvas.style.width = `${screen.width}px`
    canvas.style.height = `${screen.height}px`
    canvas.style.aspectRatio = `${screen.width} / ${screen.height}`
    engine.resize()
  }

  // If dpr changes, resize
  window.matchMedia('screen and (min-resolution: 2dppx)').addEventListener('change', resizeCanvas, false)

This works fairly well for everything except the GUI. When moving from the high res screen to the lower res, the GUI renders ~2X as large and the other meshes (images) seem to render just a bit larger. Refreshing the page fixes this and it acts as expected.

Screen recording of normal behavior on retina screen (DPR 2):

Screen recording after dragging to monitor (DPR 1). After refreshing the page it works correctly:

Any ideas what might be going on here? Any thoughts would really be appreciated

You may try to tune GUI resolution according to the changes in canvas size.
As example:

advancedTexture.renderScale = 1;  // default
1 Like

cc @DarraghBurke

Thanks for the suggestion! I’ve played around with a bit and I can adjust the size of the GUI elements this way, but it still doesn’t line up with the underlaying layers like it should.

Just like before, refreshing the page fixes it so it might be something in the GUI not responding to the resize.

Thanks for the report! Quick question: have you tried calling scaleTo(screen.width,screen.height) on the ADT? This is probably necessary.

If not, I will definitely look into this. Is there any way you could provide a minimal playground repro for me to test against?

Thanks for the reply! I already have adaptiveScaling set to true which seems to produce similar results as this.gui.scaleTo(screen.width * devicePixelRatio, screen.height * devicePixelRatio)

I did notice that after changing monitors (which resizes the engine), getBaseSize() returns 0, 0. Refreshing the page will update the base size to the correct screen dimensions.

Not sure if that’s relevant, I’ll put together a simplified playground in the meantime

1 Like

Well, I tried to make a playground and wasn’t able to replicate the issue.

I eventually got it to work properly on my end. Turns out that adaptiveScaling was actually causing sizing issues. I turned that to false and then had to make adjustments to account for devicePixelRatio in a couple of places.

So, problem solved! If anyone else stumbles on this and needs more info, I can share the solution I found in more detail.

2 Likes