0
\$\begingroup\$

I am trying to smooth a camera I create in my game, but I can't seem to find a way to actually do this correctly.

What I have :

//Calculate the "current" Forward vector
var cameraForward = 
    -Vector3.Cross(-Self.forward, target.up)
    .normalized.Cross(target.up).normalized;
//Rotate the camera on the Y axis of the current target,
// and X Axis based on delta.y and CurrentVerticalLook
cameraForward = 
    Quaternion.AngleAxis(delta.y, ViewTarget.transform.up) * 
    Quaternion.AngleAxis(CurrentVerticalLook, Self.right) * cameraForward;

var offset = cameraForward * CameraDistance;
var pos = LookAt + offset;
Self.Position = pos;
Self.transform.LookAt(ViewTarget.position)

So what I ahve tried :

I tried Lerping the Vector Position, I tried smoothing the delta.y based on the last N frames.

The Camera I need is something like this :

Rotate on the Around UP Axis of the target and Rotate on Right Axis of the Camera, Camera Up is always = to Target UP.

So this is sort of Orbital Camera, but I am having trouble finding the correct rotation/operations. The way its set right works, but the camera movement is jaggy, but I can't seem to find a way to add Slerp in there without messing everything.

Thanks!

Edit : <>

\$\endgroup\$
1
\$\begingroup\$

All you really need is an exponential filter on each of the relevant variables. Have:

// Translation parameters
Vector3 target;

// Rotation parameters
float phi;
float theta;
float radius;


// Values we want to smoothly interpolate to
Vector3 nextTarget;
float nextPhi;
float nextTheta;
float nextRadius;

// Value between 0.0 and 1.0. If 1.0, no interpolation happens.
// If 0.0, no movement happens at all. Intermediate values determine
// intermediate interpolation
float alpha;

Here's how you calculate the new camera parameters:

void UpdateCurrentTarget()
{
    target = (alpha) * nextTarget + (1.0f - alpha) * target;
    phi =    (alpha) * nextPhi    + (1.0f - alpha) * phi;
    theta =  (alpha) * nextTheta  + (1.0f - alpha) * theta;
    radius = (alpha) * nextRadius + (1.0f - alpha) * radius;
}

The camera parameters will converge to the new values smoothly. Here's how you actually compute the pose of the camera using spherical coordinates:

void UpdateCameraPose()
{
    float x = radius * sin(theta) * cos(phi) + target.x;
    float y = radius * sin(theta) * sin(phi) + target.y;
    float z = radius * cos(theta) + target.z;

    Self.transform.position = new Vector3(x, y, z);
    Self.transform.LookAt(target);
}

I prefer to do it this way because no quaternions are required.However, because they are Euler Angles, you will inevitable run into Gimbal Lock at around phi = +/- 0.5 * pi, as well as the LookAt function failing due to having the wrong up vector. You can avoid this by limiting phi so it never gets to 0.5 * pi.

\$\endgroup\$
  • \$\begingroup\$ My problem is actually joining all the requirements, I can and know how to smooth a "normal" camera, but I can't wrap my head around this one at all. Even when using Slerp I can't find how to do this. \$\endgroup\$ – Morphex Jan 15 '15 at 20:32
  • \$\begingroup\$ Alright, then wait for someone to post the quaternion solution. \$\endgroup\$ – mklingen Jan 15 '15 at 20:36
  • \$\begingroup\$ I just realized my asnwer sound a bit rude , by all means that wasnt what I wanted! I am actually trying a solution with what you posted, not sure if it works. Thank you for the feedback btw! \$\endgroup\$ – Morphex Jan 15 '15 at 21:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.