Resizing renderer with resolution greater than one
See original GitHub issueI am currently facing an issue regarding scaling the renderer or canvas on a high DPI device (or more specifically, with devicePixelRatio > 1
).
Expected behavior
From my understanding, setting resolution: devicePixelRatio
together with autoDensity: true
should allow the canvas to adjust seamlessly to the size of the renderer (resized using renderer.resize()
).
Current behavior
Check out this fiddle for an example where this fails on my device with windows scaling set to 125%, (i.e. devicePixelRatio = 1.25
). As you resize the viewport you can see pixels stretching into odd shapes.
Note Resizing works just fine if I turn windows scaling to 100% (i.e. devicePixelRatio = 1
).
The long way around
In the jsfiddle there’s a block of code commented out at line 40 that does what (from my understanding) the renderer does internally to adjust for the DPI, i.e. multiply the canvas and renderer sizes by the scaling factor and then use CSS style to scale the canvas back down.
This does seem to improve things, oddly enough (perhaps someone could explain exactly why) but there is still some stretching going on (in both my application and the fiddle, there is exactly one “stretch” line, as opposed to many in the previous case, and none with no scaling).
Edit 2: This workaround actually fixes the issue entirely. At the time of writing, I had mistakenly left in the settings for autoDensity = true
which introduces this single “stretch” (which, arguably, is worth looking into all on its own). For posterity, that bit of code requires autoDensity = false
and resolution = 1
, i.e. default settings.
Environment
pixi.js
version: 5.2.1- Browser & Version: Vivaldi - Chromium 80.0.3987.158 (64-bit) (also on the latest stable versions of Chrome, Edge and Firefox as of writing this)
- OS & Version: Windows 10 v1903
- Running Example: https://jsfiddle.net/zjo5xpsh/44/
Apologies if this is just me being a knob, been fighting this one for a couple days now.
Edit: Here are some gifs to illustrate the issue. Note the “squishing” and “stretching” of the pixels in the first example.
devicePixelRatio = 1.25
devicePixelRatio = 1
Issue Analytics
- State:
- Created 3 years ago
- Reactions:1
- Comments:9
Top GitHub Comments
OK, then its probably canvas size is something like 643 when css corresponds to 640 real pixels. Need a way to calculate and debug it.
Hey Ivan, big fan here, your insightful answers help us noobies everywhere!
My wording there may have been a little confusing there. It is not an issue of changing the resolution while the renderer is running. I was just pointing out that the setup presented in the fiddle works as expected when scaling is off, but does not when scaling is > 1. I have augmented the initial post with a couple gifs showing these artifacts.
!!!
As I was writing this comment, browser scaling came to mind. It seems that browser scaling does factor in to the
devicePixelRatio
and such may of interest here. For exampleIf I set Windows Scaling to 125% (getting a
devicePixelRatio = 1.25
) the artifacts appear when resizing the viewport (by dragging the sides with the mouse). If, however, I also set the the browser zoom to 80%, achieving a detecteddevicePixelRatio
of 1, the artifacts disappear almost entirely*. If I set the Windows Scaling to 150% (getting adevicePixelRatio = 1.50
) and set browser scaling to 66% , once again, the issue disappears (well, in this case not quite because of the resultingdevicePixelRatio
of but it is much much better than before), so this seems to be consistent.If, on the other hand, I have my Windows Scaling to 100% but set the browser
This again tells me that I might be doing something wrong, because it kind of feels like I’m fighting the system here. Check out the fiddle and play around with the browser scaling and you should be able to reproduce this.
As I didn’t quite make clear in the initial post, I seem to have found a solution to this: instead of using
autoDensity
andrenderer.resolution
, I can do those computations manually in theresize()
function and it works pretty well. However, it’s not the expected behaviour here so if this was the intended behaviour, we should update some documentation to better illustrate the function of these settings.*Note: I say almost, because in fact, there is still one “stretch” line occurring on my main application where I am using a larger sprite as a base, and looks exactly like the result from “the long way around” method, but this is not visible on this smaller sprite, and is possibly an unrelated issue. Note to note: This was in fact an error on my side, the single “stretch” line occurs when the long way round method is used in conjunction with setting
autoDensity: true
andresolution: 1
. I edited the initial post to reflect this.