摄像机的实现之美

对着背影说爱祢 提交于 2019-11-27 02:37:09

1、基础的跟随摄像机

 

为摄像机创建观察矩阵,需要三个参数:眼睛的位置(摄像机的位置)、摄像机观察目标,以及摄像机的上方向量。在基础跟随摄像机中,眼的位置可以设置为目标的水平和垂直偏移。

//tPso,tUp,tForward=位置、上方和前方向量
//hDist=水平跟随距离
//vDist=垂直跟随距离
function BasicFollowCamera(Vector3 tPos,Vector3 tUp,
                           Vector3 tForward,float hDist,float vDist)
//眼睛就是目标位置的偏移量
Vector3 eye=tPos-tForward*hDist+tUp*vDist
//摄像机向前的方向是从眼睛到目标
Vector3 cameraForward=tPos-eye
cameraForward.Normalize()

//叉乘计算出摄像机的左边及上方向量
Vector3 cameraLeft=CrossProduct(tUp,cameraForward)
cameraLeft.Normalize()
Vector3 cameraUp=CrossProduct(cameraForward,cameraLeft)
cameraUp.Normalize()

//CreateLookAt的参数为eye、target,以及up
return CreateLookAt(eye,tPos,cameraUp)
end

2、弹性跟随摄像机

 

class SpringCamera
   //水平和垂直跟随距离
   float hDist,vDist
   //弹性常量:越高表示越僵硬
   //一个好的初始值很大程度取决于你想要的效果
   float springConstant
   //阻尼常量由上面的值决定
   float dampConstant
   
   //速度和摄像机真实位向量
   Vector3 velocity,actualPosition

   //摄像机跟随的目标
   //(有目标的位置、向前向量、向上向量)
   GameObject target

   //最终的摄像机矩阵
   Matrix cameraMatrix
 
   //这个帮助函数从真实位置及目标计算出摄像机矩阵
   function ComputeMatrix()
       //摄像机的前向是从真实位置到目标位置
       Vector3 cameraForward=target.position-actualPosition
       cameraForward.Normalize()
       //叉乘计算出摄像机左边、然后计算出上方
       Vector3 cameraLeft=CrossProduct(target.up,cameraForward)
       cameraLeft.Normalize()
       Vector3 cameraUp=CrossProduct(cameraForward,cameraLeft)
       cameraUp.Normalize()

       //CreateLookAt参数为eye、target及up
       cameraMatrix=CreateLookAt(actualPosition,target.position,cameraUp)
    end

    //初始化常量及摄像机,然后初始化朝向
    function Initialize(GameObject myTarget,float mySpringConstant,float  myHDist,float myVDist) 
        target=myTarget
        springConstant=mySpringConstant
        hDist=myHDist
        vDist=myVDist

        //阻尼常量来自于弹性常量
        dampConstant=2.0f*sqrt(springConstant)

        //起初,设置位置为理想位置
        //就跟基础跟随摄像机的眼睛位置一样
        actualPosition=target.position-target.forward*hDist+target.up*vDist
        //初始化摄像机速度为0
        velocity=vector3.Zero
        //设置摄像机矩阵
        ComputeMatrix()
      end

      function Update(float deltaTime)
         //首先计算理想位置
         Vector3 idealPosition=target.position-target.forward*hDist+target.up*vDist
         //计算从理想位置到真实位置的向量
         Vector3 displacement=actualPosition-idealPosition
         //根据弹簧计算加速度,然后积分
         Vector3 springAccel=(-springConstant*displacement)-(dampConstant*velocity)
         velocity+=springAccel*deltaTime
         actualPosition+=velocity*deltaTime
         //更新摄像机矩阵
         ComputeMatrix()
       end
end

弹性摄像机的最大好处就是当目标对象旋转的时候,摄像机会有一定的延迟才开始转动。旋转出来的效果要比基础跟随摄像机要好得多。弹性摄像机效果比基础跟随摄像机好很多,都是计算量没多多少。

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!