ThreeJS:使用带有OculusRiftEffect的Sprite

时间:2014-05-22 21:48:54

标签: javascript three.js oculus webvr

我正在使用来自https://github.com/mrdoob/three.js/blob/master/examples/js/effects/OculusRiftEffect.js的OculusRiftEffect为OculusRift开发并使用Sprites。问题是精灵没有像每个眼睛一样出现在每只眼睛的正确位置。screenshot你可以看到房子精灵在每只眼睛的不同位置,并在眼睛中产生“双重视觉”效果。在玩代码时(有一个演示探测器here),您可以注意到在屏幕边缘附近定位更准确但我需要它更靠近屏幕中心,定位关闭。我认为这与OculusRiftEffect中的着色/渲染有关,但是对它的分析不足以分解它,任何方向都会受到赞赏,谢谢!

示例代码:

var _scene, _camera, _renderer, _effect, _sprite;

function init() {
  _scene = new THREE.Scene();
  _camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, .1, 100000);
  _camera.lookAt(new THREE.Vector3());
  _renderer = new THREE.WebGLRenderer({
        antialias: true,
      canvas: document.getElementById('legit')
    });

  _renderer.setSize(window.innerWidth, window.innerHeight);

  _effect = new THREE.OculusRiftEffect(_renderer, {
    worldScale: 1000
  });
  _effect.setSize(window.innerWidth, window.innerHeight);

  THREE.ImageUtils.crossOrigin = 'anonymous';

  _sprite = new THREE.Sprite(
    new THREE.SpriteMaterial({
        map: new THREE.Texture(document.getElementById('icon')),
        color: 0xff0000
    })
  );

  _sprite.scale.set(200, 200, 1);
  _sprite.position.set(500, 800, 1);
  _scene.add(_sprite);

  _scene.add(new THREE.Mesh(
    new THREE.SphereGeometry(3000, 64, 32),
    new THREE.MeshBasicMaterial({
      color: 0xffffff,
      wireframe: true,
      side: THREE.DoubleSide
    })
  ));

  animate();
}

function animate() {
  requestAnimationFrame(animate);
  render();
}

function render() {
    _renderer.render(_scene, _camera);
    _effect.render(_scene, _camera);
}

document.addEventListener('DOMContentLoaded', init);

3 个答案:

答案 0 :(得分:0)

我对Oculus插件并不熟悉,但我认为你对精灵如何工作的理解是错误的。

Sprite是一种渲染技术 - 可渲染的栅格化表面......它仍然可以在空间的任何地方,而空间是一个相对的术语。

你的房子是否意识到它是HUD的一部分而不是远处某处的粒子系统的一部分?

实现目标的一种方法是在距离代表每只眼睛中心的两个点相等的距离处覆盖副本,所有这些都在屏幕空间中。我认为这会产生你正在寻找的效果。

就定位而言。取向明智,我不确定它们是否真的在你的图像中正确对齐,但是鱼眼效应正在发挥作用。

答案 1 :(得分:0)

我对Three.js精灵的阅读表明它们使用的是屏幕坐标,而不是场景中的几何图形。因此,他们忽略了施加在场景上的每眼投影矩阵偏移。因此,我不相信它们会与Oculus Rift失真效果结合使用。

答案 2 :(得分:0)

正如pailhead和Jherico所说,使用Oculus插件是不可能的。我发现有效的解决方法是简单地使用PlaneGeometry并将其设置为相机的子级。将其设置为查看相机的位置,它将像精灵一样,并为OculusRiftEffect正确渲染。基本示例(假设相机和场景):

var sprite = new THREE.Mesh(
    new THREE.PlaneGeometry(100, 100),
    new THREE.MeshBasicMaterial({color: 0xffffff})
);
//assuming camera is at (0,0,0) we need to offset it
sprite.position.set(20, 20, -100);
sprite.lookAt(camera.position);

camera.add(sprite);

//normally camera doesnt need to be added
//but if it has child meshes it is necessary
scene.add(camera);

由于飞机是相机的一个孩子,一旦它的偏移位置正确,它将跟随摄像机的任何地方。需要注意的是,它不能与Sprite完全相同,因为你无法在场景中独立移动它,但它是我找到的最接近的解决方案。