我目前正在项目中使用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东西(几何,矩阵等)。
答案 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
为每个帧计算一个新的。或者,甚至可能更好,给它一个最后几帧的平均轮换。
使移动更平滑的另一种方法可能是每帧都插入其位置,这将使其变得更少"跳跃"
修改强>
这仅说明围绕局部z轴的旋转的杠杆作用,但围绕x轴和y轴的旋转也是如此。翻译将使标记检测的错误看起来更大。正如我之前所说,你可以通过给markerObject提供最后几帧的平均翻译来隐藏这个效果。
我也注意到标记有时会被“甩掉”#34;去旁边。这也是因为markerDetection并不完美,在某些帧中,它根本找不到标记。当它找不到标记时,您仍然将markerObject翻译为40,添加最后一帧完成的翻译。你应该做的是:
删除第359行:
translateMarker3D(markerObject3D);
并将其添加到第323行:
markerObject3D.translateX(40);
通过这样做,只有在它可以检测到标记时才转换markerObject 。