# 编程问题

# 您说Verge3D基于Three.js,它与Three.js API兼容吗?

为了创建Verge3D,我们大量修改了Three.js代码库,因此我们决定对API使用“v3d”前缀。但是,我们将尝试维护与Three.js的源代码兼容性。大多数基于Three.js的应用程序和示例都可以在Verge3D中运行,无需进行任何修改。

# 如何计算纹理内存使用量?

要将常规(非HDR)纹理存储在GPU内存中,您至少需要

width x height x 4 x 1.333 bytes

其中width、height是纹理尺寸(以像素为单位),4是每个像素的字节数,而1.333表示纹理映射所需的额外内存。例如,大小为2048x2048的纹理将占用大约22.4 Mb的GPU内存。如果需要存储HDR纹理,则将该值乘以2。

同样,根据WebGL的实现,浏览器可以在常规(系统)内存中存储纹理的至少一个副本。

# 如何在调整大小时保持场景比例?

我们希望所有物体,无论它们与摄像机的距离如何,都显示相同的大小,即使调整了窗口的大小。解决此问题的关键公式是该公式针对给定距离的可见高度:

visible_height = 2 * Math.tan((Math.PI / 180) * camera.fov / 2) * distance_from_camera;
1

如果我们将窗口高度增加一定百分比,那么我们想要的是在所有距离处的可见高度都以相同百分比增加。不能通过更改相机位置来做到这一点。相反,您必须更改相机的视野。例子

# 我的应用程序窗口在iOS设备上不断拉长。如何解决?

如果将Verge3D应用程序嵌入iframe元素中,则可能会遇到iOS设备上的特定问题,这会导致iframe的大小不断增加,超出浏览器窗口的范围。反过来,这可能导致WebGL崩溃。

要解决此问题,您可以使用以下代码段,该代码段将iframe调整为页面主体的尺寸,以防止该iframe超出页面范围。

<script>
if (/(iPad|iPhone|iPod)/g.test(navigator.userAgent)) {
    var iframe = document.getElementById('myIframe');
    function resize() {
        iframe.style.width = getComputedStyle(document.body).width;
        iframe.style.height = getComputedStyle(document.body).height;
        iframe.setAttribute('scrolling', 'no');
    }
    iframe.addEventListener('resize', function(e) {
        resize();
    });

    resize();
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 键盘控件不适用于内嵌在iframe中的应用。

当页面上的其他HTML获得焦点时,就会发生这种情况。要解决此问题,请尝试以下代码:

document.getElementById("my_iframe_id").focus();
1

其中my_iframe_id是iframe元素的ID。

译注

可以为iframe绑定点击事件,当点击iframe时获取焦点,这会避免和其它元素的焦点冲突。代码如下:

var my_iframe = document.getElementById("my_iframe_id");
// 点击iframe时获取焦点
my_iframe.contentDocument.onclick = function(){
    my_iframe.focus();
}
1
2
3
4
5
上次更新: 2020-7-10 17:29:36