El tamaño del Frustum en una distancia dada desde la cámara
Los rayos de la Cámara

Dolly Zoom (también conocido como el “Efecto Trombón”)

Dolly Zoom es el efecto visual conocido, dónde la cámara se mueve simultáneamente hacia un objeto de destino y se aleja de ella. El resultado es que el objeto aparece más o menos el mismo tamaño, pero todos los otros objetos en la escena cambian de perspectiva. Hecho sutilmente, dolly zoom tiene el efecto de subrayar el objeto de destino, ya que es la única cosa en la escena que no está cambiando de posición en la imagen. Alternativamente, el acercamiento puede ser deliberadamente hecho rápidamente para crear una impresión de desorientación.

Un objeto que sólo encaja dentro el frustum verticalmente va a ocupar toda la altura de la vista como se ve en la pantalla. Esto es cierto sea cual sea la distancia del objeto desde la cámara y sea cual sea el campo de visión (Field Of View - FOV). Por ejemplo, usted puede mover la cámara más cerca al objeto pero luego anchar el campo de visión de manera que el objeto encaje en la altura del frustum. Ese objeto en particular aparecerá el mismo tamaño que en pantalla pero todo lo demás va a cambiar ya que la distancia el FOV cambiarán. Esto es la esencia del efecto dolly zoom.

Crear el efecto en código es una cuestión de guardar la altura del frustum en la posición del objeto en el comienzo del acercamiento(zoom). Luego, al moverse la cámara, su nueva distancia es encontrada y el FOV es ajustado para mantener la misma altura que la posición del objeto. Esto se puede lograr con el siguiente código:-

using UnityEngine;
using System.Collections;

public class ExampleScript : MonoBehaviour {
    public Transform target;
    public Camera camera;
    
    private float initHeightAtDist;
    private bool dzEnabled;

    // Calculate the frustum height at a given distance from the camera.
    void FrustumHeightAtDistance(float distance) {
        return 2.0f * distance * Mathf.Tan(camera.fieldOfView * 0.5f * Mathf.Deg2Rad);
    }

    // Calculate the FOV needed to get a given frustum height at a given distance.
    void FOVForHeightAndDistance(float height, float distance) {
        return 2.0f * Mathf.Atan(height * 0.5f / distance) * Mathf.Rad2Deg;
    }

    // Start the dolly zoom effect.
    void StartDZ() {
        var distance = Vector3.Distance(transform.position, target.position);
        initHeightAtDist = FrustumHeightAtDistance(distance);
        dzEnabled = true;
    }
    
    // Turn dolly zoom off.
    void StopDZ() {
        dzEnabled = false;
    }
    
    void Start() {
        StartDZ();
    }

    void Update () {
        if (dzEnabled) {
            // Measure the new distance and readjust the FOV accordingly.
            var currDistance = Vector3.Distance(transform.position, target.position);
            camera.fieldOfView = FOVForHeightAndDistance(initHeightAtDist, currDistance);
        }
        
        // Simple control to allow the camera to be moved in and out using the up/down arrows.
        transform.Translate(Input.GetAxis("Vertical") * Vector3.forward * Time.deltaTime * 5f);
    }
}

_Ejemplo de un C# script

var target: Transform;

private var initHeightAtDist: float;
private var dzEnabled: boolean;


// Calculate the frustum height at a given distance from the camera.
function FrustumHeightAtDistance(distance: float) {
    return 2.0 * distance * Mathf.Tan(camera.fieldOfView * 0.5 * Mathf.Deg2Rad);
}


// Calculate the FOV needed to get a given frustum height at a given distance.
function FOVForHeightAndDistance(height: float, distance: float) {
    return 2 * Mathf.Atan(height * 0.5 / distance) * Mathf.Rad2Deg;
}


// Start the dolly zoom effect.
function StartDZ() {
    var distance = Vector3.Distance(transform.position, target.position);
    initHeightAtDist = FrustumHeightAtDistance(distance);
    dzEnabled = true;
}


// Turn dolly zoom off.
function StopDZ() {
    dzEnabled = false;
}


function Start() {
    StartDZ();
}


function Update () {
    if (dzEnabled) {
        // Measure the new distance and readjust the FOV accordingly.
        var currDistance = Vector3.Distance(transform.position, target.position);
        camera.fieldOfView = FOVForHeightAndDistance(initHeightAtDist, currDistance);
    }
    
    // Simple control to allow the camera to be moved in and out using the up/down arrows.
    transform.Translate(Input.GetAxis("Vertical") * Vector3.forward * Time.deltaTime * 5);
}

Ejemplo de un JS script

El tamaño del Frustum en una distancia dada desde la cámara
Los rayos de la Cámara