Three.js:翻译投影的最佳方式?

时间:2016-03-15 10:38:26

标签: javascript three.js augmented-reality

我目前正在项目中使用threex.webar(https://github.com/jeromeetienne/threex.webar)(使用ArucoJS的Three.js)。现在,我正在尝试基于AR标记进行投影(markerObject3D),但我希望它在标记旁边,而不是在标记上。

以下是我使用Three.js translatex()的方法:

function render() {

    translateMarker3D(markerObject3D);
        movieMaterial.update();
        backgroundTexture.update();
        effect.render(scene, camera)
}
function translateMarker3D(marker3D) {
       marker3D.translateX( 80 );
}  

事情是:它有点工作。当它没有翻译时它会变得非常漂亮(因此:当它在标记旁边时会闪烁,但是当它在标记上时它会很棒)。它会闪烁很多。

我也试图改变aruco的返回值(在threex.jsarucomarker.js中):

object3d.position.x = translation[0] + 80;

但它呈现完全相同,闪烁。

所以我的问题是:使用Three.js在AR标记旁边进行投影的最佳方法是什么?

编辑:

由于现场演示很难设置,我只是在Youtube上上传了一个视频来说明我的观点:https://www.youtube.com/watch?v=SM1dZ29SZRk&feature=youtu.be

但是,您可以在此处查看完整代码:https://github.com/cned-di-dev/three-ar-proto/blob/master/tests/stereoscopic/index.html

我缺少什么:

  • 翻译时闪烁的物体(有时只是“颠簸”) 它的翻译)
  • 投影有时是错误的(在屏幕的边缘, 对象是由于透视相机而翻译的,但我无法解决它)

要知道的事情:我不太擅长3D东西(几何,矩阵等)。

1 个答案:

答案 0 :(得分:2)

有点难以理解你的意思"闪烁"。但经过一些测试,我想我知道你的意思。我认为问题是detectMarkers()函数无法在每一帧找到 exact 相同的标记位置,并且markerObject首先被旋转并且然后被翻译。

由于标记每帧的旋转变化很小,并且沿着 new x轴平移,因此markerObject会上下跳动,并且幅度会大于进一步你翻译它。

现在,解决方案取决于您对此翻译行为的要求。一种方法是仅沿着全局x轴平移markerObject。这可以通过将markerObject设为父对象并将其转换为:

来实现
var markerParent = new THREE.Object3D();
var markerObject3D = new THREE.Object3D();
markerParent.add(markerObject3D);
markerParent.translateX(80); // you can do this just one time
scene.add(markerParent)

另一种方法是更改​​markerToObject3D(marker, object3d)源中的转换顺序,以便在转换之前完成转换(并将转换添加到object3d.position.x)。

如果你不想沿着全局x轴转换markerObject,而是沿着它的局部转换,那么摆脱闪烁就会有点困难。一种方法是给markerObject提供最后几帧的平均转换,而不是让JsArucoMarker为每个帧计算一个新的。或者,甚至可能更好,给它一个最后几帧的平均轮换。

使移动更平滑的另一种方法可能是每帧都插入其位置,这将使其变得更少"跳跃"

修改

我观看了您的视频,其中确认了翻译中的一个问题,如下图所示: enter image description here

这仅说明围绕局部z轴的旋转的杠杆作用,但围绕x轴和y轴的旋转也是如此。翻译将使标记检测的错误看起来更大。正如我之前所说,你可以通过给markerObject提供最后几帧的平均翻译来隐藏这个效果。

我也注意到标记有时会被“甩掉”#34;去旁边。这也是因为markerDetection并不完美,在某些帧中,它根本找不到标记。当它找不到标记时,您仍然将markerObject翻译为40,添加最后一帧完成的翻译。你应该做的是:

删除第359行:

translateMarker3D(markerObject3D);

并将其添加到第323行:

markerObject3D.translateX(40);

通过这样做,只有在它可以检测到标记时才转换markerObject