WebVR 样板问题 - 管理器未在 VRMode 中呈现,相机看起来垂直向下,全屏仅呈现 window 的一半
WebVR Boilerplate Problems - Manager not rendering in VRMode, Camera looks straight down, fullscreen renders only half of window
我正在尝试将 WebVR 实施到我在 Three.js 中构建的项目中,但我在使其正常运行时遇到了困难。
查看场景时出现了一些问题
当 VRMode 为 false 时,我的场景会渲染,但当切换到 VR 模式时,场景突然停止渲染。我可以看到两个立体windows但没有其他显示。
当我在桌面上加载我的场景时,相机指向正下方。在设备上加载时,场景会颠倒过来。我告诉相机看我图像的中心,但它似乎没有任何效果。在我摆弄控件和渲染以支持 WebVR 管理器和 VRControls 之前,它工作得很好。
camera.position.set(-300, -800, 200);
camera.up = new THREE.Vector3(0, 0, 1);
camera.lookAt(new THREE.Vector3(0, 0, 0));
我可以很好地设置位置。
- 当我单击 GUI 底部的全屏按钮时,屏幕分成两半。上半部分是黑色(我的 body bg 和 clearfix 颜色是蓝色),下半部分渲染我的场景。当我手动调整 window 大小时,我有一个事件监听器可以正常工作,所以这必须与 VR 管理器有关。
知道是什么导致了这些错误吗?
这是我定义渲染器的方式:
var width = window.innerWidth,
height = window.innerHeight;
var renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(width, height);
renderer.setClearColor(0x1D76BB, 1);
// Effect and Controls for VR
effect = new THREE.VREffect(renderer);
controls = new THREE.VRControls(camera);
effect.setSize(width, height);
var manager = new WebVRManager(renderer, effect);
这是我的动画函数:
function animate() {
requestAnimationFrame(animate);
if (controls) {
controls.update();
}
if (manager.isVRMode()) {
renderer.setRenderTarget(null); // add this line
manager.render(scene, camera);
} else {
renderer.render(scene, camera);
}
}
我的图书馆今天早上刚从凉亭回来,所以我知道它们都是最新的。
如果不查看其余代码,很难猜出发生了什么。
我不确定这是否相关,但最新版本的 WebVRManager class 负责为您在 VR 和非 VR 模式之间切换,它会回退到普通的 2D 渲染器模式。因此,您不再需要检查 isVRMode
,也不需要调用 renderer.render
。只需使用 manager.render
,它将为您完成工作。经理现在还为您处理调整大小,因此您可能也不应该这样做。
除此之外,您似乎正确使用了管理器。
VRControls(与 webvr-polyfill 一起使用,如果您正在使用它)会覆盖相机的位置和方向,因此您自己设置它不会有任何效果(除非您在 controls.update
之后覆盖它,在这种情况下,控件将不起作用)。如果你想设置基础相机变换,你可以将相机附加到 "dolly" 并改为设置移动车的变换:
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 10000);
var dolly = new THREE.Object3D();
dolly.add(camera);
dolly.position.z = 200;
dolly.up = new THREE.Vector3(0, 0, 1);
dolly.lookAt(new THREE.Vector3(0, 0, 0));
dolly.rotateOnAxis(new THREE.Vector3(0, 1, 0), Math.PI);
scene.add(dolly);
function animate(timestamp) {
var timer = new Date().getTime() * 0.0002;
dolly.position.x = Math.floor(Math.cos(timer) * 600);
dolly.position.y = Math.floor(Math.sin(timer) * 600);
controls.update();
manager.render(scene, camera, timestamp);
requestAnimationFrame(animate);
}
请注意,您必须将推车添加到场景中,并且必须在将推车设为 lookAt
后沿其 Y 轴旋转推车,因为默认情况下相机会查看负 Z 方向。
将 AxisHelper 添加到场景中也可能会有所帮助,这样您可以在调试时更好地了解方位:
var axisHelper = new THREE.AxisHelper(200);
axisHelper.position.z = 100;
scene.add(axisHelper);
最后,如果您使用的是 webvr-polyfill,它有时会根据您使用的设备渲染自己的桶形失真着色器通道。因此,如果您的项目涉及着色器,它们可能会与此着色器通道冲突并阻止您的场景在 VR 模式下正确渲染或根本无法渲染。如果是这种情况,您可以通过在调用 manager.render
之前渲染着色器来解决此问题,如我在此处所述:
我正在尝试将 WebVR 实施到我在 Three.js 中构建的项目中,但我在使其正常运行时遇到了困难。
查看场景时出现了一些问题
当 VRMode 为 false 时,我的场景会渲染,但当切换到 VR 模式时,场景突然停止渲染。我可以看到两个立体windows但没有其他显示。
当我在桌面上加载我的场景时,相机指向正下方。在设备上加载时,场景会颠倒过来。我告诉相机看我图像的中心,但它似乎没有任何效果。在我摆弄控件和渲染以支持 WebVR 管理器和 VRControls 之前,它工作得很好。
camera.position.set(-300, -800, 200); camera.up = new THREE.Vector3(0, 0, 1); camera.lookAt(new THREE.Vector3(0, 0, 0));
我可以很好地设置位置。
- 当我单击 GUI 底部的全屏按钮时,屏幕分成两半。上半部分是黑色(我的 body bg 和 clearfix 颜色是蓝色),下半部分渲染我的场景。当我手动调整 window 大小时,我有一个事件监听器可以正常工作,所以这必须与 VR 管理器有关。
知道是什么导致了这些错误吗?
这是我定义渲染器的方式:
var width = window.innerWidth,
height = window.innerHeight;
var renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(width, height);
renderer.setClearColor(0x1D76BB, 1);
// Effect and Controls for VR
effect = new THREE.VREffect(renderer);
controls = new THREE.VRControls(camera);
effect.setSize(width, height);
var manager = new WebVRManager(renderer, effect);
这是我的动画函数:
function animate() {
requestAnimationFrame(animate);
if (controls) {
controls.update();
}
if (manager.isVRMode()) {
renderer.setRenderTarget(null); // add this line
manager.render(scene, camera);
} else {
renderer.render(scene, camera);
}
}
我的图书馆今天早上刚从凉亭回来,所以我知道它们都是最新的。
如果不查看其余代码,很难猜出发生了什么。
我不确定这是否相关,但最新版本的 WebVRManager class 负责为您在 VR 和非 VR 模式之间切换,它会回退到普通的 2D 渲染器模式。因此,您不再需要检查 isVRMode
,也不需要调用 renderer.render
。只需使用 manager.render
,它将为您完成工作。经理现在还为您处理调整大小,因此您可能也不应该这样做。
除此之外,您似乎正确使用了管理器。
VRControls(与 webvr-polyfill 一起使用,如果您正在使用它)会覆盖相机的位置和方向,因此您自己设置它不会有任何效果(除非您在 controls.update
之后覆盖它,在这种情况下,控件将不起作用)。如果你想设置基础相机变换,你可以将相机附加到 "dolly" 并改为设置移动车的变换:
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 10000);
var dolly = new THREE.Object3D();
dolly.add(camera);
dolly.position.z = 200;
dolly.up = new THREE.Vector3(0, 0, 1);
dolly.lookAt(new THREE.Vector3(0, 0, 0));
dolly.rotateOnAxis(new THREE.Vector3(0, 1, 0), Math.PI);
scene.add(dolly);
function animate(timestamp) {
var timer = new Date().getTime() * 0.0002;
dolly.position.x = Math.floor(Math.cos(timer) * 600);
dolly.position.y = Math.floor(Math.sin(timer) * 600);
controls.update();
manager.render(scene, camera, timestamp);
requestAnimationFrame(animate);
}
请注意,您必须将推车添加到场景中,并且必须在将推车设为 lookAt
后沿其 Y 轴旋转推车,因为默认情况下相机会查看负 Z 方向。
将 AxisHelper 添加到场景中也可能会有所帮助,这样您可以在调试时更好地了解方位:
var axisHelper = new THREE.AxisHelper(200);
axisHelper.position.z = 100;
scene.add(axisHelper);
最后,如果您使用的是 webvr-polyfill,它有时会根据您使用的设备渲染自己的桶形失真着色器通道。因此,如果您的项目涉及着色器,它们可能会与此着色器通道冲突并阻止您的场景在 VR 模式下正确渲染或根本无法渲染。如果是这种情况,您可以通过在调用 manager.render
之前渲染着色器来解决此问题,如我在此处所述: