Darryl_Lehmann
Darryl_Lehmann

Reputation: 2198

devicePixelRatio on Chrome for Android affecting WebGLRenderer.setSize function

I've been testing mobile support for Three.js and have discovered a quirk when it comes to the setSize function and multiple views. Here's the scenario.

While loading the webgl_multiple_views example on my Nexus 7 (Android OS 4.3) in the Chrome for Android (29.0.1547.59) the entire rendered window is mis-aligned as can be seen in this screenshot.

screenshot_2013-09-03-11-43-40

At first I suspected a setViewport related issue but after further inspection determined that the WebGLRenderer.js function setSize was attempting to correct the WebGL canvas context size by multiplying by the devicePixelRatio like so:

_canvas.width = width * this.devicePixelRatio;
_canvas.height = height * this.devicePixelRatio;

This to me, seems a perfectly reasonable approach, but the problem here is that with some Android devices the calculation is seemingly already implied by the system, causing a skewed scene.

I've found that by implying a default pixel ratio of 1 I can correct the issue, but I'm anticipating it will likely break a lot of properly behaving mobile devices. Here's the "fix" if you will:

renderer = new THREE.WebGLRenderer( { antialias: true, alpha: false, devicePixelRatio: 1 } );

My question is, has anyone else encountered this? Does anyone have a more consistent fix for generally scaling a canvas context so it respects device pixel ratio, but doesn't break some android devices?

Thank-you kindly for any advice/assistance.

Upvotes: 0

Views: 2392

Answers (1)

TJS101
TJS101

Reputation: 500

Try this function. I have tested it extensively and it reports the correct device width, height and a computedPixelRatio for every device I have tried...

function getDeviceDimensions()                  // get the width and height ofthe viewing device based on its OS
{
    screenWidth = window.screen.width;                                                  // get the width
    screenHeight = window.screen.height;                                                // get the height 
    var computedPixelRatio =  (window.screen.availWidth / document.documentElement.clientWidth);                        // a more reliable measure of device pixel ratio due to android firefox bugs...
    computedPixelRatio = window.devicePixelRatio >= computedPixelRatio ? window.devicePixelRatio : computedPixelRatio;  // select whichever value is larger between pixel ratio methods
    if (navigator.userAgent.indexOf('Android') != -1)                                   // if the client is on an android system
    {
        screenWidth = screenWidth / computedPixelRatio;                                 // divide the reported width by the pixel ratio
        screenHeight = screenHeight / computedPixelRatio;                               // divide the reported height by the pixel ratio
    }
    //alert(screenWidth + " " + screenHeight + " " + window.devicePixelRatio + " " + computedPixelRatio);
}

Upvotes: 4

Related Questions