Hi Roll20 dev folks, I’ve been using your service on my retina 1 mac for a while now and I’ve noticed that image assets displayed on the virtual tabletop are always blurry. This is mostly an issue with tokens such as cards that include text where they become harder to read, but does affect the clarity of all assets. I’ve had a dig around in the DOM of the app, and it appears that the canvas being used to render the virtual tabletop is not including the window.devicePixelRatio when calculating height and width for the canvas. Here's MDN's explaination of devicePixelRatio : “The devicePixelRatio of Window interface returns the ratio of the resolution in physical pixels to the resolution in CSS pixels for&nbsp;the current display device. This value could also be interpreted as the ratio of pixel sizes:&nbsp;the size&nbsp;of one CSS pixel&nbsp;to the size of one physical pixel. In simpler terms, this tells the browser how many of the screen's actual pixels should be used to draw a single CSS pixel.” — <a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio" rel="nofollow">https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio</a> Below I’ve included two methods to reproduce my findings, along with the assets you’ll need, and a minimal demo. Confirming that devicePixelRatio is not being respected: I’ve tested this with the following script in the browser console: c = document.querySelector("canvas#finalcanvas"); console.log("%d (width) === %d (clientWidth) * %d (devicePixelRatio) =&gt; %o", c.width, c.clientWidth, devicePixelRatio, c.width === c.clientWidth * devicePixelRatio ); console.log("%d (height) === %d (clientHeight) * %d (devicePixelRatio) =&gt; %o", c.height, c.clientHeight, devicePixelRatio, c.height === c.height * devicePixelRatio ); On a device with a devicePixelRatio of greater than 1, you will get something like: 1152 (width) === 1152 (clientWidth) * 2 (devicePixelRatio) =&gt; false 835 (height) === 835 (clientHeight) * 2 (devicePixelRatio) =&gt; false That false at the end is telling you that the expected dimensions don‘t match the actual dimensions. Expected results: These expressions should always be true . Actual results: On any device with devicePixelRatio greater than 1 they produce false . Observing the issue using visual inspection I’ve created a simple test case to demonstrate the problem. I’m on a 5k iMac with a devicePixelRatio of 2. The assets im using are scaled to the grid to ensure that they render precisely. I've drawn these by hand so that when inspected with an image editor you can see clear diagonal lines of pixels and any blurring from resampling or resizing should be very obvious. 1x grid size 2x grid size <a href="https://brehaut.net/media/roll20-device-pixel-issue/device-pixel-ratio-test.png" rel="nofollow">https://brehaut.net/media/roll20-device-pixel-issue/device-pixel-ratio-test.png</a> <a href="https://brehaut.net/media/roll20-device-pixel-issue/device-pixel-ratio-test-2x.png" rel="nofollow">https://brehaut.net/media/roll20-device-pixel-issue/device-pixel-ratio-test-2x.png</a> Here i have two a screenshot of two tokens that ive created, one is 70✕70px (the grid size for the page), and the second is 140✕140px (ie a 2✕ pixel ratio). You can see here that the content rendered by the browser to the screen are blurry.&nbsp; In comparison here is what Roll20 has rendered to its canvas I just used the following script in the console to extract the data directly to an image i could copy and paste into my image editor: c = document.querySelector("canvas#finalcanvas"); img = document.createElement("img") img.src = c.toDataURL() document.body.appendChild(img); img.style.position = “absolute”; img.style.top = 0 img.style.left = 0 img.style.zIndex = 10000 Expected results : One of the two asset sizes should be rendered crisply with the exact pixels of the asset files presented as they are in the asset. You can see in the canvas content that the first asset is rendered correctly. In the screenshot however, neither are because the canvas content is being scaled up 2x. Minimal test case I have created a minimal test case that demonstrates the differences in rendering In this demo, You'll see the same two assets I've used in my tests of roll20 rendered to show the differences in using not devicePixelRatio and using it. If you use a retina screen and take a screenshot of the different canvases, and zoom in in your image editor of choice, you should see that: In the first canvas none of the assets render crisply. In the second canvas the first and third render clearly: they are now drawn at 1:1 scale with the canvas. The third canvas (with the drawing scaled along with the canvas),&nbsp; the first and third assets are being scaled up, but the second one is now rendering correctly. Resolving the issue: The easy part of resolving this is to set a CSS width and height on the canvas, as well as computing width and height for the canvas itself. Pseudocode for this would be something like: c = document.querySelector("canvas#finalcanvas"); const cssWidth = c.innerWidth; const cssHeight = c.innerHeight; &nbsp;&nbsp;&nbsp; c.style.width = `${cssWidth}px`; c.style.height = `${cssHeight}px`; c.width = cssWidth * devicePixelRatio; c.height = cssHeight * devicePixelRatio; Note that the css width and height are set before width and height, to prevent changing the width or height from changing the client width or height and messing up the second calculation. The hard part of resolving this issue is that devicePixelRatio needs to be propagated to all the content rendered within the canvas, including for example the font sizes for text.. Please note that MDN has a lot of examples and documentation about this exact issue. Footnotes: “retina” is apple’s terminology for high DPI screens.