XNA 4.0:第一人称摄影机在地形抖动上的移动
最近,我成功地实现了第一人称摄影机和地形碰撞,但我遇到了另一堵墙,当在高度地图上移动时,摄影机会抖动。虽然这个问题并不少见,但我找不到任何明确的解决方案,也找不到达到预期效果的方向。 有人能建议我如何调整我的实现以使渲染执行平滑吗 摄像机等级:XNA 4.0:第一人称摄影机在地形抖动上的移动,xna,camera,collision-detection,terrain,Xna,Camera,Collision Detection,Terrain,最近,我成功地实现了第一人称摄影机和地形碰撞,但我遇到了另一堵墙,当在高度地图上移动时,摄影机会抖动。虽然这个问题并不少见,但我找不到任何明确的解决方案,也找不到达到预期效果的方向。 有人能建议我如何调整我的实现以使渲染执行平滑吗 摄像机等级: public class Camera { public Matrix view { get; protected set; } public Matrix projection { get; protected set; } p
public class Camera
{
public Matrix view { get; protected set; }
public Matrix projection { get; protected set; }
public Vector3 direction { get; protected set; }
public Vector3 side_direction { get; protected set; }
public Vector3 position { get; set; }
public Vector3 up { get; protected set; }
public float _rotationX { get; protected set; }
public float _rotationY { get; protected set; }
public float rotX
{
get { return _rotationX; }
set
{
_rotationX = value;
RotateX(value);
}
}
public float rotY
{
get { return _rotationY; }
set
{
_rotationY = value;
RotateY(value);
}
}
public Matrix rotationX;
public Matrix rotationY;
public Camera(Game game, Vector3 pos, Vector3 up)
: base(game)
{
this.direction = new Vector3(0, 0, 1);
this.side_direction = new Vector3(1, 0, 1);
this.rotationX = Matrix.Identity;
this.rotationY = Matrix.Identity;
this.position = pos;
this.up = up;
this.view = Matrix.CreateLookAt(pos, pos + direction, up);
this.projection = Matrix.CreatePerspectiveFieldOfView(
MathHelper.PiOver4, (float)Game.Window.ClientBounds.Width /
(float)Game.Window.ClientBounds.Height,
1, 3000);
}
public override void Initialize()
{
base.Initialize();
}
public void RotateX (float degree)
{
if (_rotationX + degree >= 89)
_rotationX = 89;
else if (_rotationX + degree <= -89)
_rotationX = -89;
else
_rotationX = _rotationX + degree;
float radians = MathHelper.ToRadians(_rotationX);
rotationX = Matrix.CreateRotationX(radians);
updateView();
}
public void RotateY (float degree)
{
_rotationY = (_rotationY + degree) % 360;
float radians = MathHelper.ToRadians(_rotationY);
rotationY = Matrix.CreateRotationY(radians);
updateView();
}
protected void updateView()
{
this.side_direction = Vector3.Transform(new Vector3(1, 0, 1), rotationX);
this.direction = Vector3.Transform(new Vector3(0, 0, 1), rotationX);
this.side_direction = Vector3.Transform(side_direction, rotationY);
this.direction = Vector3.Transform(direction, rotationY);
this.view = Matrix.CreateLookAt(position, position + direction, up);
}
public override void Update(GameTime gameTime)
{
base.Update(gameTime);
}
public void moveForward(float p)
{
this.position = position + direction * p;
updateView();
}
public void moveSide(float p)
{
this.position = position + side_direction * p;
updateView();
}
public void moveForward(float p, Terrain t)
{
Vector3 tmp = position + direction * p;
tmp.Y = t.GetTerrainHeight(tmp.X, tmp.Z);
this.position = tmp;
updateView();
}
public void moveSide(float p, Terrain t)
{
Vector3 tmp = position + side_direction * p;
tmp.Y = t.GetTerrainHeight(tmp.X, tmp.Z);
this.position = tmp;
updateView();
}
public void Draw(ref BasicEffect effect)
{
effect.Projection = this.projection;
effect.View = this.view;
}
}
公共级摄像机
{
公共矩阵视图{get;protected set;}
公共矩阵投影{get;保护集;}
公共向量3方向{get;受保护集;}
公共向量3侧_方向{get;受保护集;}
公共向量3位置{get;set;}
公共向量3 up{get;受保护集;}
公共浮点_rotationX{get;protected set;}
公共浮点_rotationY{get;protected set;}
公共浮动轮换
{
获取{return\u rotationX;}
设置
{
_旋转X=值;
RotateX(值);
}
}
公共浮球
{
获取{return\u rotationY;}
设置
{
_旋转Y=值;
RotateY(值);
}
}
公共矩阵旋转X;
公共矩阵轮换;
公共摄像机(游戏、Vector3 pos、Vector3 up)
:基地(游戏)
{
这个方向=新矢量3(0,0,1);
该方向=新矢量3(1,0,1);
this.rotationX=矩阵.Identity;
this.rotationY=矩阵.Identity;
这个位置=位置;
this.up=up;
this.view=Matrix.CreateLookAt(位置,位置+方向,向上);
this.projection=Matrix.CreatePerspectiveFieldOfView(
MathHelper.PiOver4,(浮动)Game.Window.ClientBounds.Width/
(float)Game.Window.ClientBounds.Height,
1, 3000);
}
公共覆盖无效初始化()
{
base.Initialize();
}
公共空间旋转度(浮动度)
{
如果(_旋转X+度>=89)
_旋转X=89;
否则如果(_rotationX+degree你能告诉我们更多关于GetTerrainHeight函数的信息吗?
据我所知,您正在直接读取地形高度-它是存储在阵列中还是其他什么东西中?
尝试在相邻点之间插入地形高度,因为角色位置很容易位于两个或多个数据点之间(如果我正确理解代码)。
UPD:
尝试在当前相机位置和计算的相机位置之间进行lerp,而不是立即分配:
this.position=Vector3.Lerp(this.position,tmp,0.05f);
0.05f是您希望向目标移动的百分比的阈值(范围从0.0f到1.0f)。校准它,甚至引入游戏时间,使平滑独立于您的帧速率。您能告诉我们更多关于GetTerrainHeight函数的信息吗?
据我所知,您正在直接读取地形高度-它是存储在阵列中还是其他什么东西中?
尝试在相邻点之间插入地形高度,因为角色位置很容易位于两个或多个数据点之间(如果我正确理解代码)。
UPD:
尝试在当前相机位置和计算的相机位置之间进行lerp,而不是立即分配:
this.position=Vector3.Lerp(this.position,tmp,0.05f);
0.05f是阈值的百分比(在0.0f到1.0f的范围内)你想向目标移动。校准它,甚至引入游戏时间,使平滑独立于你的帧速率。当相机抖动时,它跟随的是什么?你考虑过移动吗?相机跟随的是一个点,它是相机位置向量(camera.position),视图矩阵是根据Camera.position和Camera.direction normal计算的,其余部分在向前移动(浮动,地形)功能下。我不认为平滑会有帮助,因为相机每秒更新60次(是的,fps很好),你试过了吗?更频繁的更新可能意味着你需要更强的平滑(即考虑更多的值进行平滑处理)。我没有,我应该首先尝试哪种技术/过滤器?一个简单的方法是保存相机计算到的最后n
点的存储,并将相机的实际可见位置设置为这些点的平均值。(根据需要调整n
)“运行平均值”的变化比原始数据更平稳。相机抖动时跟随的是什么?您考虑过移动吗?相机跟随的是一个点,该点是相机位置向量(相机位置),视图矩阵是根据相机位置和相机方向法线计算的,其余点在向前移动(浮动,地形)功能。我不认为平滑会有帮助,因为相机每秒更新60次(是的,fps很好),你试过了吗?更频繁的更新可能意味着你需要更强的平滑(即考虑更多的平滑值)。我没有,我应该先试用哪种技术/过滤器?一个简单的方法是保存相机计算到的最后一个n
点的存储,并将相机的实际可见位置设置为这些点的平均值。(根据需要调整n
。)这是“运行平均值”“更改比原始数据更平滑。它的功能与@thormond相同您使用的是第一篇文章中的功能还是简化的功能?它的功能与@thormond相同您使用的是第一篇文章中的功能还是简化的功能?