【问题标题】:XNA 4.0: first person camera movement on terrain jitterXNA 4.0:第一人称摄像机在地形抖动上的移动
【发布时间】:2013-05-11 13:46:55
【问题描述】:

最近我成功地实现了第一人称相机和地形碰撞,但我遇到了另一堵墙,即在高度图上移动时相机抖动。虽然这不是很常见的问题,但我找不到任何明确的解决方案或方向,我应该遵循以达到预期的效果。 谁能建议我如何调整我的实现以使渲染执行顺利?

相机类:

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;
    }
}

`

【问题讨论】:

  • 相机抖动时跟随的是什么?你考虑过smoothing这个运动吗?
  • 相机跟随一个点,即相机位置向量(Camera.position),视图矩阵由Camera.position和Camera.direction法线计算,其余在moveForward(float,Terrain)函数下.鉴于相机每秒更新 60 次,我认为平滑不会有帮助(是的,fps 很好)
  • 你试过了吗?更频繁的更新可能只是意味着你需要更强的平滑(即考虑更多的值来平滑)。
  • 我没有,我应该先尝试哪种技术/过滤器?
  • 一个简单的方法是保存相机被计算定位到的最后一个n点,并将相机的实际可见位置设置为这些点的平均值。 (根据需要调整 n。)这个“运行平均值”的变化比原始数据更平滑。

标签: xna camera collision-detection terrain


【解决方案1】:

您能多谈谈 GetTerrainHeight 函数吗? 据我所知,您是在直接读取地形高度 - 它是存储在数组中还是其他东西中?
尝试在相邻点之间插入地形高度,因为您的角色位置很容易在两个或多个数据点之间(如果我理解您的代码的话)。

UPD:
尝试在当前相机位置和计算出的相机位置之间调整,而不是立即分配它:
this.position = Vector3.Lerp(this.position, tmp, 0.05f);
0.05f 是您想要向目标移动的百分比(范围从 0.0f 到 1.0f)的阈值。校准它甚至引入 GameTime 以使平滑独立于您的帧速率。

【讨论】:

  • this one功能一样
  • @thormond 你是使用第一篇文章中的函数还是简化的函数?
猜你喜欢
  • 1970-01-01
  • 2013-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多