I'm developing a webgl application (a simple solar system) and everything looks fine on Chrome and Firefox on ONE monitor
But if I start eyefinity (three monitors each full hd + bezel compensation) the solarsystem is distorted in chrome.
In Firefox it looks correct and really nice:
http://kritten.org/pictures/firefox.jpg
In Chrome it looks like this:
http://kritten.org/pictures/chrome.jpg
It seems that the principal point (is this the right name?) is in the wrong location.
If I move forward in Firefox I actually move forward, but in Chrome I move to the right. So it keeps this distortion any time.
Are there any ideas what could be wrong?
The issue with Chrome is it's got a limit on the size a canvas can be. This is part of the WebGL spec although arguably Chrome should fix it. You can try to encourage them to fix it here.
The specific issue is that the WebGL spec says that even though you may ask for a canvas of a certain size WebGL might give you a smaller drawingbuffer. This was specifically because graphics cards have a size limit. Some are as low as 1024. Let's say some card has a limit of 2048. You've got one monitor that's 1280x1024. No problem.
You now add a second monitor for a total desktop space of 2560x1024. You now stretch a window across both monitors. You ask for a canvas of size 2560x1024. What should happen? WebGL can't make one that big, the GPU says it has a limit of 2048. So there were 3 option
Crash. That's no go
Force the canvas to stay under 2048
Let the canvas be stretched to 2560 but make the drawingbuffer the limit which is 2048 in this example
The WebGL committee picked #3 because it's the one least likely to cause problems. The worst that happens is you get a distorted image but the user can scale the window back down until things are normal so your webpage doesn't die.
Unfortunately 99.99% of WebGL programs ignore this feature of WebGL and so you get this distorted image when you run into that part of the spec.
In this particular case though the limit isn't in your GPU it's in Chrome. The proof is that it works in Firefox. Again you can try to encourage them to fix it here.
If you'd like to make your program work around it you need to look up what size the canvas's drawing buffer was actually made and use that in the correct places. You can find out but checking gl.drawingBufferWidth and gl.drawingBufferHeight
That means first set the camera aspect to the size the canvas is actually displayed. You really should always do this
aspect = gl.canvas.clientWidth / gl.canvas.clientHeight;
perspective = yourPerspectiveFunction(fov, aspect, zNear, zFar);
In three.js that would be
camera.aspect = renderer.domElement.clientWidth /
renderer.domElement.clientHeight;
camera.updateProjectionMatrix();
You should set your viewport to the size of the drawingbuffer
gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawBufferHeight);
In three.js that would be
renderer.setViewport(0, 0, renderer.context.drawingBufferWidth,
renderer.context.drawingBufferHeight);
That should also always work.
If you're doing anything else related to the width and height of the canvas (picking, scissor, etc..) you'll need to do the appropriate math to convert from the size the canvas is being displayed to the size of its drawingbuffer
That will get rid of the distortion, of course since Chrome will actually only be creating a smaller drawingBuffer you'll get some scaling.
Related
I have website which is having layout issues on certain devices which I believe I've tracked down to high res displays which also have the display scaling in windows 10 set to 200%. (not 200% in the browser, but in the display settings in the Windows Control Panel)
The problem is I don't have a device which can duplicate the resolution of these devices, which is 2736 x 1824 (it's a MS Surface Pro). Oh yeah, this only happen with Edge...
I know of sites which have VMs which will run different browsers for testing purposes, but I don't know of any which allow you to choose your resolution. Without going out and getting a hold of this specific machine, how else can I debug this issue?
You could create a custom device in the developer console, and simply display it at whatever scale actually fits on your screen. For instance, create a custom device with that particular resolution, then in the developer console on Chrome you can view it scaled down 50% (if your own resolution is 1920x1080) so that the whole thing is visible.
Turned out none of the emulation/scaling options in the dev console would emulate what was really happening. I ended up remoting into the customer's computer so I could do my own debugging on there and resolved the issue.
Seems like Edge v 44 was computing some CSS calc function for a div height incorrectly (off by 1 or 2 pixels) which was making some divs push out and mess up the layout.
The fix was to tweak the CSS so the calculation wasn't required.
My app draws same figure on the canvas multiple times. We figured out that we could draw it once on the hidden canvas and them just copy it to the target canvas. I am doing some perf comparison. And I am facing some weirdness that I can't explain.
Here it is in a nutshell: I have a test with two canvases of the same size. In the first canvas I draw figures multiple times. On the second: I draw on the hidden canvas first, then I copy it into visible canvas. The result should be the same.
Here is the fun part: Approach with hidden canvas works fine with size of the canvas 400x164. It is 60% faster that drawing each figure separately.
But once I increase size by once pixel to 400x165 - bam! Stamping is 60% slower in Chrome. In IE it is still faster (ask me how I found out that 164-165 threshold).
Here are the links to JsPerf tests:
size 400x165: http://jsperf.com/draw-vs-stamping/7
size 400x164: http://jsperf.com/draw-vs-stamping/8
Chrome 46.0.2490.80 32-bit on Windows Server 2008 R2 / 7 64-bit
Any help is appreciated.
The answer is this and it is unfortunately stupid. I've been baffled by this for years. Your question helped me find the answer.
If and only if a canvas contains >= 60,000 pixels, will Chrome allow hardware acceleration.
I had a 200x200 mini-map sitting ontop of a webgl app. The webgl app would be rendering 150,000 polygons no problem at 60fps. Once the player began moving, the framerate would drop to ~30fps. Disabling the minimap would keep things at a smooth 60fps. I was surprised my tiny little super basic minimap would cause such a massive hit.
After searching on SO for a solution (and not really finding one), I began playing with the posted jsfiddles. Canvas size seemed to make all the difference. In one particular fiddle (from HTML5 drawImage slow on Chrome), I tried a size of 256x256 (area of 65,536), ran terribly. Tried 257x257 (area of 66,049) ran roughly 6x faster...
So I tried my minimap at 257x257 (used CSS zoom to shrink it down to the appearance of original size). Ran great, almost 0 performance hit when moving.
So there it is. Google chose a threshold of 60,000 pixels in order for hardware acceleration to kick in.
Annoying.
Version 63.0.3239.84 (Official Build) (64-bit)
I am using ExecWB() to zoom in/out my WebBrowser control like this:
m_lpBrowser->ExecWB(OLECMDID_OPTICAL_ZOOM, OLECMDEXECOPT_DONTPROMPTUSER, &(CComVariant)zoomFactor, NULL);
This works just fine when my OS dpi is 100% (96 dpi). However, under OS dpi 150% (144 dpi), setting zoom factor as 100 makes the web page in the browser look much smaller.(I was expecting to get exactly the same layout as the one under OS dpi 100%)
Then I found an old IE8 document.
In this document, OLECMDID_OPTICAL_ZOOM is said to be setting the ZOOM FACTOR of the browser
( ZOOM FACTOR = System DPI / Layout DPI)
But I just can't figure out the meaning of Layout DPI. Is this the root cause that I get smaller web pages?
This MSDN document mentioned there is a flag DOCHOSTUIFLAG_DPI_AWARE controlling the High DPI behaviour of the web control.
When the flag is set during initialization, the web control uses IE8 High DPI behavior; otherwise, it uses IE7 High DPI behaviour by default.
Under IE8 High DPI behaviour, the parameter zoom factor means exactly the scaling percentage of the web page, just like what you see in the IE zoom UI.
However, under IE7 High DPI behaviour, it's a little bit more complicated. Based on my experiment result,
the actual scaling factor = zoom factor / system dpi(%)
For example, under system 120dpi(125%), setting zoom factor 125 result in 1.0x scaling of web pages.
However, there is still something I can't explain: under system 120dpi(125%), I was expecting to get 80% scaling of web pages when I set zoom factor of 100. It turns out that words are 80% of their original size, but the pictures still 100%. Perhaps it is a bug in IE7 zooming.
I don't know if this is a bug or if it just needs to be called a rendering issue, but it's annoying.
If you have a 3d translated object, within that you have a scaled object, if that scaled object exceeds a certain size it just disappears. This is what I mean: http://dabblet.com/gist/4563584 (hover the a and wait to see it disappear)
I googled and searched a lot, but to no avail.
You might think: why? Because I am making an impress.js slideshow, and it needs to zoom a lot, but when using 3d transforms to hardware accelerate, object are cached as an images to save memory or something, I get that, but the big one is still visible when completely zoomed in, and it gets blurry (because it's cached at a small size), scaling and zooming out fixes that problem, but then it disappears...
I haven't found any other way to fix the blurry text issues without the scale, any help on that is also welcome.
Using google chrome 24.0.1312.52
Firefox 16.0.2 is working fine
Yeah it's a Chrome bug, doesn't happen in Firefox/IE/Safari. Been around for a while.
The issue has been reported to Chromium several times, here's the most recent one:
https://code.google.com/p/chromium/issues/detail?id=337493
I have an HTML5 page using CSS3 and SVG graphics in development. I tried using media queries to enlarge the SVG graphics when the device pixel ratio is 1.5 or 2. This works fine. Now I view my page on a small device like the Motorolla Xoom. The reported ratio is 1. This means the Xoom displays everything quite small as compared to a regular monitor. The most annoying part is that it looks great in landscape mode, but in portrait mode the full page is resized to fit in the same width. The ratio number does not change at this point.
I did try using something like 'width: 3in;' but again, it was only the correct size in landscape.
Ultimately, I'd like to use some ratio of device size vs pixel size, and scale everything this way. Is this possible?
My issue was that my graphics were never rendered again when orientation was changed. When I hit refresh again, all is coming up as expected. This was an issue that existed somewhere between my keyboard and my chair. The media queries are in fact working, I just need to rerender some stuff upon orientation change.