WebGL绘图缓冲区大小不等于画布大小

Cha*_* L. 0 canvas webgl three.js

我有一个使用three.js绘制多个webgl图层的webapp,我有时会(在Chrome中)使用drawingBufferHeight和drawingBufferWidth(不等于画布高度和宽度)获取图层.

每层都可以打开和关闭.我有一堆它们,所以它们被重用:

Layers.GLRendererPool = new (function() {
    this.renderers = [];
    this.getRenderer = function() {
        if(this.renderers.length == 0) {
            var r = new THREE.WebGLRenderer({ alpha: true });
            r.setClearColor(0x000000, 0);
            return r;
        } else {
            var r = this.renderers.shift();
            return r;
        }
    };
    this.saveRenderer = function(r) {
        r.setSize(0, 0); //EXPERIMENTAL
        this.renderers.push(r);
    };
    return this;
})();
Run Code Online (Sandbox Code Playgroud)

使用THREE.WebGLRenderer.setSize()获取它们后调整大小.在调用setSize()之后,canvas.width == renderer.context.drawingBufferWidth和canvas.height == renderer.context.drawingBufferHeight,但并非总是如此.即使我目前只使用1个渲染器,它们也不相同.

任何想法为什么会这样?我假设视频卡内存有一些限制,我尝试在每个没有使用的渲染器上调用setSize(0,0),但没有运气.这是Chrome + WebGL错误吗?

gma*_*man 5

有很多问题.

  1. 根据three.js的版本,它可能会神奇地增加你的宽度和高度,window.devicePixelRatio这意味着如果设备像素比率不是1,你的画布尺寸将不同于你要求的尺寸.它几乎不会是任何智能手机的1过去的2 - 3年.

  2. 你的记忆力不足(就chrome而言).WebGL规范允许drawingBuffer小于请求.这正是为什么drawingBufferWidthdrawingBufferHeight存在,因此你可以查阅一下它的大小作出drawingBuffer.

最初的动机是因为GPU仅支持一定大小的画布(由纹理制成).如果你有多个显示器,并且你可以在它们之间拉伸一个窗口,那么就可以很容易地创建比这个限制更大的显示器.所以WebGL有一些选择(1)崩溃/抛出异常.这可能会破坏大多数程序,用户会丢失数据(2)不会使drawingBuffer大于最大大小,而是让它被拉伸以适应所请求的大小.

除了这种动机,虽然WebGL实现也可以使用规范的相同部分为您提供比您要求的任何原因更小的画布.最常见的原因是你内存不足,所以它会尝试制作你要求的大小,失败,并尝试逐渐减小尺寸直到成功

嗯,这是很长的解释.

我在crbug.com上提交了一个错误,因为看起来Chrome最近为每个网页添加了任意512meg限制,这对许多用户造成了问题.