Aframe:平滑位置和旋转?
Aframe: smoothing position and rotation?
我一直在尝试使用 Aframe 和 AR.js。对于增强现实应用,一个常见的问题是放置在标记上的对象变得相当 'jittery' 或 'jerky'。我已经对这个问题做了一些研究,看来解决这个问题的一种可能方法是在几个帧上平滑旋转和位置。不幸的是,这样做的教程几乎不存在,我才刚刚开始掌握 Html/Javascript。
因此我的问题是:您是否知道是否可以在框架实体中使用一个函数来提取位置和旋转,平滑它们,然后将它们传递给(我想)一个使用这些的子实体放置的平滑值?
<a-entity position="0 0 0" rotation="0 0 0" >
<a-video Mysmoothingfunction src="#video" width="3.5" height="2"></a-video>
</a-entity>
我可以想象开头可能是这样的:
<script type="text/javascript">
AFRAME.registerComponent("listener", {
schema :
{
stepFactor : {
type : "number",
default : 0.05
}
},
tick: function() {
this.getProperty("position"); // something like this?
}
</script>
您知道如何解决这个问题吗?
您的描述听起来像 linear interpolation。在这里使用应该很简单:
一旦 marker 可见,获取之前的 video 位置/旋转,并使用实际 marker 位置/旋转。然后用近似值更新视频。
近似值应该缓和 'jitter'。在本例中,我将使用 THREE lerp
函数。
如果您不熟悉 linear interpolation,那么可以将其视为一种使用线性函数进行逼近的方法(这可能非常不精确,但我就是这么想的)。
代码(附在标记上)如下所示:
AFRAME.registerComponent("listener", {
init: function() {
this.target = document.querySelector('#target'); // your video
this.prevPosition = null; // initially there is no position or rotation
this.prevRotation = null;
},
tick: function() {
if (this.el.object3D.visible) {
this.target.setAttribute('visible', 'true')
if(!this.prevPosition && !this.prevRotation) {
// there are no values to lerp from - set the initial values
this.target.setAttribute('position', this.el.getAttribute('position'))
this.target.setAttribute('rotation', this.el.getAttribute('rotation'))
} else {
// use the previous values to get an approximation
this.target.object3D.position.lerp(this.prevPosition, 0.1)
// this (below) may seem ugly, but the rotation is a euler, not a THREE.Vector3,
// so to use the lerp function i'm doing some probably unnecessary conversions
let rot = this.target.object3D.rotation.toVector3().lerp(this.prevRotation, 0.1)
this.target.object3D.rotation.setFromVector3(rot)
}
// update the values
this.prevPosition = this.el.object3D.position
this.prevRotation = this.el.object3D.rotation
} else {
// the marker dissapeared - reset the values
this.target.setAttribute('visible', 'false')
this.prevPosition = null;
this.prevRotation = null;
}
}
})
你可以注意到我设置的值是 object3D
而不是官方的 API (setAttribute()
/ getAttribute()
)。它应该更快,这在 tick()
函数内进行更改时是可取的。
Here是一个bug(一个框被插值了,它的移动很流畅)。
我一直在尝试使用 Aframe 和 AR.js。对于增强现实应用,一个常见的问题是放置在标记上的对象变得相当 'jittery' 或 'jerky'。我已经对这个问题做了一些研究,看来解决这个问题的一种可能方法是在几个帧上平滑旋转和位置。不幸的是,这样做的教程几乎不存在,我才刚刚开始掌握 Html/Javascript。
因此我的问题是:您是否知道是否可以在框架实体中使用一个函数来提取位置和旋转,平滑它们,然后将它们传递给(我想)一个使用这些的子实体放置的平滑值?
<a-entity position="0 0 0" rotation="0 0 0" >
<a-video Mysmoothingfunction src="#video" width="3.5" height="2"></a-video>
</a-entity>
我可以想象开头可能是这样的:
<script type="text/javascript">
AFRAME.registerComponent("listener", {
schema :
{
stepFactor : {
type : "number",
default : 0.05
}
},
tick: function() {
this.getProperty("position"); // something like this?
}
</script>
您知道如何解决这个问题吗?
您的描述听起来像 linear interpolation。在这里使用应该很简单:
一旦 marker 可见,获取之前的 video 位置/旋转,并使用实际 marker 位置/旋转。然后用近似值更新视频。
近似值应该缓和 'jitter'。在本例中,我将使用 THREE lerp
函数。
如果您不熟悉 linear interpolation,那么可以将其视为一种使用线性函数进行逼近的方法(这可能非常不精确,但我就是这么想的)。
代码(附在标记上)如下所示:
AFRAME.registerComponent("listener", {
init: function() {
this.target = document.querySelector('#target'); // your video
this.prevPosition = null; // initially there is no position or rotation
this.prevRotation = null;
},
tick: function() {
if (this.el.object3D.visible) {
this.target.setAttribute('visible', 'true')
if(!this.prevPosition && !this.prevRotation) {
// there are no values to lerp from - set the initial values
this.target.setAttribute('position', this.el.getAttribute('position'))
this.target.setAttribute('rotation', this.el.getAttribute('rotation'))
} else {
// use the previous values to get an approximation
this.target.object3D.position.lerp(this.prevPosition, 0.1)
// this (below) may seem ugly, but the rotation is a euler, not a THREE.Vector3,
// so to use the lerp function i'm doing some probably unnecessary conversions
let rot = this.target.object3D.rotation.toVector3().lerp(this.prevRotation, 0.1)
this.target.object3D.rotation.setFromVector3(rot)
}
// update the values
this.prevPosition = this.el.object3D.position
this.prevRotation = this.el.object3D.rotation
} else {
// the marker dissapeared - reset the values
this.target.setAttribute('visible', 'false')
this.prevPosition = null;
this.prevRotation = null;
}
}
})
你可以注意到我设置的值是 object3D
而不是官方的 API (setAttribute()
/ getAttribute()
)。它应该更快,这在 tick()
函数内进行更改时是可取的。
Here是一个bug(一个框被插值了,它的移动很流畅)。