我正在开发一个webgl应用程序(一个简单的太阳能系统),在ONE监视器上的Chrome和Firefox上一切正常 但是,如果我开始使用eyefinity(三个显示器,每个全高清+边框补偿),那么solarsystem会在chrome中失真。
在Firefox中它看起来正确且非常好: http://kritten.org/pictures/firefox.jpg
在Chrome中,它看起来像这样: http://kritten.org/pictures/chrome.jpg
似乎主要点(这是正确的名称吗?)位于错误的位置。 如果我在Firefox中前进,我实际上是向前推进,但在Chrome中,我向右移动。所以它随时都能保持这种失真。
有什么想法可能有什么不对吗?
答案 0 :(得分:1)
Chrome的问题在于它对画布的大小有限制。这是WebGL规范的一部分,尽管可以说Chrome应该修复它。您可以尝试encourage them to fix it here。
具体问题是WebGL规范说即使你可能要求一个特定大小的画布,WebGL可能会给你一个较小的绘图缓冲区。这是因为显卡有尺寸限制。有些卡低至1024.让我们说一些卡的限制为2048.你有一台显示器的1280x1024。没问题。
您现在添加第二台显示器,总桌面空间为2560x1024。现在,您可以在两个监视器上拉伸窗口。你要的是尺寸为2560x1024的帆布。应该怎么办? WebGL不能做出那么大的,GPU说它有2048的限制。所以有3个选项
崩溃。那不行了
强制画布保持在2048
让画布拉伸至2560,但在此示例中使绘图缓冲区限制为2048
WebGL委员会选择#3因为它是最不可能导致问题的人。最糟糕的情况是你得到一个扭曲的图像,但用户可以缩小窗口,直到事情正常,所以你的网页不会死。
不幸的是,99.99%的WebGL程序忽略了WebGL的这一特性,因此当您遇到规范的那一部分时,您会得到这个扭曲的图像。
在这种特殊情况下,虽然GPU中的限制不在Chrome中。证据是它适用于Firefox。您可以再次尝试encourage them to fix it here。
如果您想让您的程序在其中运行,您需要查看画布的绘图缓冲区实际制作的大小,并在正确的位置使用它。您可以查看gl.drawingBufferWidth
和gl.drawingBufferHeight
这意味着首先将相机方面设置为画布实际显示的大小。你真的应该总是这样做
aspect = gl.canvas.clientWidth / gl.canvas.clientHeight;
perspective = yourPerspectiveFunction(fov, aspect, zNear, zFar);
在three.js中
camera.aspect = renderer.domElement.clientWidth /
renderer.domElement.clientHeight;
camera.updateProjectionMatrix();
您应将视口设置为绘图缓冲区的大小
gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawBufferHeight);
在three.js中
renderer.setViewport(0, 0, renderer.context.drawingBufferWidth,
renderer.context.drawingBufferHeight);
这也应该始终有效。
如果您正在做与画布的宽度和高度相关的任何其他事情(拾取,剪刀等等),您需要进行适当的数学运算才能从画布的大小进行转换显示为其绘图缓冲区的大小
这将消除失真,当然因为Chrome实际上只会创建一个较小的drawingBuffer,你会得到一些缩放。