Meow CAD 001 – Logarithmic Zoom

There are two possible way for zooming an object:

  1. Decrease the camera angle (this is the method which optic cameras uses)
  2. Come closer to the object (this is the method which we use)

Decrease The Camera Angle

If you use digital cameras before probably you see 50mm 18-35mm … or similar text on lenses. This number shows the focal length of the lens. The focal length and camera angle is opposite to each other. In other words 50 mm lens have smaller angle than 18 mm lens.

  • Bigger numbers = smaller angles = more zoom
  • Smaller numbers = bigger angles = less zoom

Binoculars use that method in games.

Come Closer To The Object

In real life when we can’t see objects that far away to us. We walk to them. We can use that logic. We can directly change camera position like flying in the air but we need a better approach. Why? Because we want to orbit around an object. So we will use “spring arm”. What is that?

It is a component inside Unreal Engine (the red line). We attach the camera to spring arm. And we attach to spring arm to character.

  • Camera orbit around the character when we change the rotation of the spring arm.
  • Camera zoom in/out to the character when we change the length of the spring arm.

We use that logic inside our code. We just need to adjust cameraArmLength by zoom value. You can use linear steps (1,2,3,4,5,6,7,…) or you can use log scale (1,2,4,8,16). We will use logarithmic scale because we want to smooth transition.

class Camera{
  glm::vec3 cameraPos
  float cameraArmLength = 10;
  glm::vec3 cameraFront;
  double step = 1;
  
public:
  void zoom(float value);
  glm::mat4 get_view();
};

void Camera::zoom(float value) {
    step += value;

    if (step < 0.1)
        step = 0.1;
    if (step > 100)
        step = 100;

    double maxSteps = 100;

    double minZoom = 0.1;
    double maxZoom = 100;
    double logMinZoom = log(minZoom);
    double logMaxZoom = log(maxZoom);
    double logZoom = logMinZoom + (logMaxZoom - logMinZoom) * step / (maxSteps - 1);
    cameraArmLength = exp(logZoom);
}

glm::mat4 Camera::get_view() {
    auto camPos = cameraPos - cameraFront * cameraArmLength;
    return glm::lookAt(camPos, camPos + cameraFront, worldUp);
}


https://www.gamedev.net/forums/topic/666225-equation-for-zooming


Comments

Leave a Reply

Your email address will not be published. Required fields are marked *