Camera

Reference: http://www.etereaestudios.com/training_img/camera_rig/camera_rig.htm

Recuerdo muy bien cómo en mis primeras animaciones 3D —hace ya unos cuantos años de eso—, cuando tenía que trabajar con la cámara para ver mi escena desde distintos puntos de vista, simplemente, “la movía”… Es decir: me situaba en el frame 0, colocaba la cámara en un determinado lugar apuntando hacia mi objetivo (target); luego iba al frame 150 y recolocaba la camara apuntando al mismo u otro objetivo… Y así sucesivamente, colocando keyframes en cada uno de esas posiciones hasta completar el recorrido.

Y claro, cuando la trayectoria seguida por la cámara no era excesivamente complicada, las cosas salían bien: si la cámara simplemente iba desde “A” hasta “B” siguiento una recta o un ligero arco, todo funcionaba. El problema es que muchas veces, cuando el recorrido empezaba a complicarse, era mucho más difícil mantener el control de lo que estaba sucediendo, apareciendo “quiebros” indeseados, violentas “sacudidas”, cambios de ritmo inesperados, etc, etc.

Problemas que si querías resolver te obligaban a tocar y retocar una y otra vez los recorridos, los giros y las curvas de velocidad, hasta dar con un resultado satisfactorio. Con el grave añadido de que, una vez que tenías resuelta tu animación, si necesitabas acelerar o decelerar el ritmo en todo el conjunto o sólo en una parte, muchas veces tenías que acabar rehaciendo de nuevo todo el proceso. Tedioso.

Todo eso fue así hasta que descubrí que en estas situaciones, con recorridos un poco más complejos, lo que había que hacer es controlar todos los movimientos de un modo, digamos, más “indirecto”, a través de manejadores intermedios (nulls) que se encargaran de controlar cada uno de los aspectos individuales del movimiento, por “capas”.

Antes de entrar en detalle, veamos los movimientos básicos que podemos imprimirle a una cámara. Aunque cada programa 3D tiene sus particularidades, en general todas estas posibilides se encuentran en cualquier software de un modo más o menos directo:

Movemos todo el conjunto Rotamos la cámara
Como cualquier objeto 3D la cámara puede trasladarse… …y también podemos girarla para apuntar donde necesitemos.

Si sólo pudieramos realizar estos dos tipos de operaciones con la cámara sería un poco engorroso ir posicionandola en cada punto y apuntando a nuestro objetivo correctamente. Esto muchas veces puede solventarse viendo la escena (el viewport 3D) a través de la propia cámara y actuando sobre ella con los comandos habituales. Pero si queremos manipular la cámara externamente, sin mirar a través de ella, será mucho más cómodo añadir un target para que la cámara siempre lo siga, apuntando hacia él.

Esto suele resolverse de distintas maneras, según cada programa:

— Algunos ya incorporan por defecto cámaras que tiene esta forma de funcionar internamente, de modo que podemos introducir las coordenadas de la propia cámara por un lado y de su target por otro, pero manteniendose como un único objeto en la escena.

— Otros programas lo que hacen es añadir un elemento externo, generalmente un null —también llamado effector, locator, dummie, etc—, y asignarle a la cámara una orden —“look at”— para que siempre apunte hacia ese elemento.

Movemos sólo la cámara Movemos sólo el target
Al introducir una orden “look at” la cámara siempre mirará hacia el mismo punto —nuestro target— aunque la movamos. Y si lo que hacemos es mover el target, entonces la cámara girará para poder apuntar siempre hacia él.

Bien. Como decíamos al principio, con estas posibilidades será fácil y directo resolver recorridos de cámara sencillos moviendo la cámara y/o el target directamente. Pero si empezamos a complicar un poco esos recorridos la cosa ya no será tan simple.

Es entonces cuando entran en escena esos manejadores intermedios de los que os hablaba. Por supuesto, no conozco todos los programas 3D, pero creo que el concepto de null está presente en todos ellos. En cualquier caso, incluso si vuestro programa no lo tiene os lo podéis crear vosotros mismos: un null no es más que un elemento que sirve de “ancla”, para posicionarlo allá donde lo necesitemos.

En realidad un null podría ser cualquier objeto —por ejemplo un pequeño cubito— con tal de que no se renderice (si vuestro programa no tiene nulls y tampoco podéis ordenarle que un objeto no se renderice —cosa que la verdad, me extrañaría bastante—, siempre podéis hacer que ese elemento tenga una dimensión de cero).

De hecho, en las próximas imágenes, en lugar de auténticos nulls, he empleado una verdadera geometría —unos discos planos— para que todo se vea más claro. Algunos programas, de hecho, pueden hacer que sus nulls puedan tener diferentes aspectos (ejes, pequeños cubos, discos, esferas, etc). Da igual su aspecto, mientras sea funcional. Lo importante, en cualquier caso, es que no se rendericen.

Para empezar veamos lo que podríamos considerar una de las configuraciones o “rig” más básicos, con la que en realidad podréis resolver muchas necesidades de movimiento de un modo muy sencillo y directo:

Empezamos a configurar el rig más básico

1. Situamos en las coordenadas 0,0,0 un null y lo renombramos de un modo que nos sea útil, en función de lo que pretendamos hacer con él. En este caso lo he llamado “rot Y”, básicamente porque la operación que se encargará de realizar es rotar sobre el eje Y. En la imagen, he empleado un disco verde que he situado sobre el plano horizontal para que lo distingáis mejor.

2. Duplicamos ese null y a nuestra copia —que seguirá estando en el origen— la renombramos como “rot X”. En la imagen os lo muestro como un disco rojo girado 90º respecto al primero (pero cuidado: en sus coordenadas tanto la posición como la rotación serán de 0,0,0)

3. Añadimos una Cámara en la escena y hacemos que esté en el origen, todas sus coordenadas también a cero.

En definitiva: al crear nuestro pequeño rig, los 3 elementos deben estar inicialmente en el origen y con todas sus coordenadas —posición, rotación y escala— puestas en 0,0,0. [ Repito que os he colocado el disco rojo en esa posición sólo para que entendáis cuál será su función, pero no debe aparecer como 90º en su rotación en X ]

Finalmente definís una estructura jerárquica con estos elementos tal como se ve en la imagen a la derecha: la Cámara será “hija” de rot X y éste será “hijo” de rot Y.

NOTA: creo que 3DStudioMax —y posiblemente algún otro programa de visualización 3D— al eje vertical lo llama Z y no Y. Simplemente cambiáis la nomenclatura.

Empezamos a configurar el rig más básico

Después de tener definido el rig básico y creada la estructura jerárquica podéis desplazar la cámara hacia atrás para que no esté en el origen pero siga apuntando hacia él. En este caso la he desplazado 2,5 metros en el eje Z positivo.

Movemos sólo la cámara Es muy importante que entendáis que éste pequeño rig no sirve para cualquier movimiento de cámara que podamos necesitar, ni mucho menos. Antes de definir una estructura tendréis que pensar en las caracteristicas de vuestro recorrido y ser capaces de separar en pequeños componentes individuales los diferentes elementos de ese movimiento compuesto.

Después podréis hacer que cada uno de vuestros nulls se encargue de hacer una única tarea o varias, eso depende de cómo os lo queráis montar.

Por ejemplo, en el rig que acabamos de crear, y que yo empleo en muchos de mis movimientos de cámara, generalmente suelo actuar del siguiente modo:

— El null maestro o padre, rot Y, se encarga de la traslación en XYZ y además también rota en el eje vertical (Y).

— El segundo null, rot X, sólo se encarga de rotar en el eje X.

— La propia cámara se desplaza en el eje Z (hacia atrás) y también puedo hacer que rote en el eje Z (roll o cabeceo).

Alguno pensará: ¿y para qué complicar las cosas añadiendo más elementos cuando se lo podemos hacer todo directamente a la cámara? Bueno, desde mi punto de vista no estamos complicando las cosas –aunque estemos añadiendo nuevos elementos— sino simplificandolas, y mucho, porque ahora cada uno de esos componentes sólo se encargará de una parte pequeña de todo el conjunto de movimientos y lo que es más importante: lo hará de un modo independiente, sumandose todos los eventos en forma de “capas”.

Esto permite solventar, entre otros, muchos de los problemas ligados con los órdenes de rotación. Y es que en animación 3D no es lo mismo girar un objeto primero en Y luego en X, que hacerlo al contrario, primero en X y luego en Y (aquí el orden de los factores sí que altera el producto). Si no estáis familiarizados con ello os recomiendo este fántastico videotutorial de GuerrilaCG (eso sí, en inglés).

Como ejemplo, veamos en la siguiente comparativa qué pasaría si sólo empleasemos un null target e hicieramos que se encargara de todos los giros. Después, a la derecha veréis el control que tenemos al contar con un segundo null de apoyo:

http://www.etereaestudios.com/training_img/camera_rig/FLVPlayer_Progressive.swf
Al tener un sólo null como target, si lo giramos primero en el eje vertical (Y) y después en el eje X, cuando más adelante queramos volver a girar en el eje Y resultará que será un eje Y local (no global) y por lo tanto nuestra cámara quedaría ladeada, girada. Sin embargo al contar con un segundo null, podemos girar el primero en el eje Y, después el segundo en el eje X, y luego volver al primero para girarlo de nuevo en Y. Ahora nuestra cámara ya no acaba ladeada como en el caso anterior.

En la siguiente secuencia de 3 tomas animadas vamos a ver cómo elaborar un movimiento muy sencillo con este pequeño rig de cámara. Un recorrido sencillo que no lo sería tanto si lo pretendiéramos conseguir moviendo directamente la cámara.

El recorrido que queremos conseguir es el siguiente: vamos a girar alrededor de una casita, al mismo tiempo que iremos descendiendo —sin dejar de mirarla— y al mismo tiempo que nos acercamos a ella.

Fijaos que es muy importante pensar de antemano en todo el recorido que necesitamos crear para saber cómo podemos dividirlo en sus diferentes componentes y por consiguiente poder decidir el número de nulls de apoyo que vamos a necesitar:

Componente 1: Rotar alrededor de la casa (rot Y)
Componente 2: Descender (rot X)
Componente 3: Acercarnos (traslación en local Z de la propia cámara)

http://www.etereaestudios.com/training_img/camera_rig/FLVPlayer_Progressive.swf

Aquí vemos cómo actúa el primer componente (el null “padre”) que es el primero en ser animado: nos ponemos en el frame 0 y le damos un valor de 0º a la rotación Y de nuestro null rot Y. A continuación vamos al frame 75 y le damos un valor de 360º a ese mismo null. La cámara dará una vuelta completa al rededor de nuestra casita.

http://www.etereaestudios.com/training_img/camera_rig/FLVPlayer_Progressive.swf

A continuación volvemos al frame 0 y le damos un valor de 55º a la rotación X de nuestro null rot X. Después vamos al frame 75 y le cambiamos el valor a 0º. Esa rotación en X se sumará al efecto que realizaba el primer null y como resultado veremos que la cámara da una vuelta alrededor de la casita al mismo tiempo que desciende hacia el suelo.

http://www.etereaestudios.com/training_img/camera_rig/FLVPlayer_Progressive.swf

Finalmente retornamos al frame 0 y añadimos un keyframe en la posición Z de la propia cámara, para fijar esa coordenada en ese momento. Vamos hasta el frame 75 y variamos la distancia en Z para que esté mucho más cerca. Todos los componentes de movimiento se sumarán y como resultado la cámara rotará alrededor de la casa, descenderá hacia el suelo y se acercará a la casita.

¿Podríamos haber resuelto este recorrido de otras maneras sin usar nulls? Por supuesto que sí. Podríamos haberlo hecho, al menos, de otras dos maneras:

1. Podríamos situarnos en el frame 0 colocado la cámara apuntando a nuestra casa a la altura y distancia deseadas. Luego avanzamos un poco en el tiempo, añadimos un nuevo keyframe y reposicianamos la cámara en la zona de la derecha (mirando desde arriba), un poco más baja, un poco más cerca y también mirando a la casa. Avanzamos un poquito más, reposicionamos todo… etc, etc. Es decir: vamos posicionando la cámara en cada punto a cada momento y luego modificamos el path recorrido por la cámara para que tenga un “buen aspecto” desde todos los ángulos.

2. Otra aproximación consistiría en crear un recorrido como una spline, que debería ser aproximadamente una espiral o helicoide descendente y que se fuera cerrando hacia el centro en la base. Una vez creada la spline linkamos la cámara a ella obligandola a que siga ese recorrido y finalmente le damos a la cámara una orden “look at” para que siempre mire hacia la casita.

Pero fijaos: cualquiera de estas dos soluciones os va a llevar un buen rato, en un caso definiendo cada una de las coordenadas claves de la cámara (keyframes) y modificando su path recorrido para que se ajuste a nuestras necesidades; y en el segundo caso creando —modelando— de cero una spline usando las herramientas de las que dispongamos en nuestro software (nurbs, beziers…).

Y aquí viene la parte más importante: ¿qué pasa si una vez descrito el recorrido no estamos satisfechos?, ¿qué hacemos si nos gusta la rotación que describe alrededor de la casa pero necesitamos que descienda más deprisa o más lento?, ¿qué ocurre se tanto la rotación como el descenso nos encajan pero quisiéramos que la cámara se acercará mucho menos o mucho más? Con cualquiera de estos dos últimos procedimientos supuestamente más “directos” probablemente tendremos que repetir todo el proceso.

Sin embargo con nuestro pequeño sistema de rig estos cambios a posteriori serán “pan comido”. De hecho, esa es para mí la grandeza de este sistema: una vez que definimos el recorrido global, luego procederemos a ajustarlo con toda comodidad interviniendo sobre las curvas de velocidad de cada uno de los componentes independientemente: estará “chupado” hacer que el primer null sólo gire 180º en lugar de los 360º que habíamos asignado al empezar; o hacer que el segundo null empiece a 90º en lugar de 55º y que termine un poco por debajo del suelo, a -10º; o hacer que la cámara empieza estando al doble de distancia; o hacer que además de acercarse, la cámara vaya rotando sobre su eje Z (roll)… y así todo lo que podamos necesitar.

Como he dicho al principio no podemos pretender solucionar cualquier necesidad de recorrido con el mismo rig, sino que deberemos “desglosar” los componentes del movimiento para dar con una solución satisfactoria y lo más simple posible. De todos modos este rig tan básico que acabamos de ver puede dar mucho más de sí. A continuación vemos un ejemplo de recorrido resuelto con él:

http://www.etereaestudios.com/training_img/camera_rig/FLVPlayer_Progressive.swf

A la izquierda podéis ver el recorrido que realiza la cámara junto con los dos nulls azules. El primer null, con forma de varilla vertical, se encarga tanto de la traslación en XYZ como de la rotación en Y; el segundo null, con forma de cuadrado amplio se encarga sólo de la rotación en X; y la propia cámara puede acercarse o alejarse en Z. A la derecha tenéis lo que se ve a través de la cámara.

Curvas de velocidad

Y en este gif animado tenéis las distintas curvas de velocidad de cada uno de estos componentes. Una vez definido el recorrido de un modo aproximado es a través de estas curvas donde acabamos de perfeccionarlo actuando sobre cada una independientemente.

A continuación podéis ver un par de casos donde he empleado unos rigs bastante más complejos. En primer lugar en la secuencia inicial de mi animación Fallingwater donde la cámara primero va por encima del cauce del riachuelo mirando hacia abajo, luego pasa a mirar de frente y conforme se acerca a la casa empieza a girar a su alrededor:

[ Probablemente debáis clickar primero en el vídeo para que se cargue a toda velocidad y luego volver a verlo a su velocidad correcta ]

En el siguiente vídeo tenéis la toma única con la que está capturada toda la escena de Isfahan. Este es uno de los rig de cámara más complejos que he realizado, compuesto por 9 nulls, cada uno encargado de una labor muy concreta. A la izquierda veréis el recorrido que realiza la cámara vista desde “afuera” y a la derecha el render final.

[ Os recomiendo que la veáis en HD para captar los detalles. Clickad en el icono “HD” que os llevará a la web de Vimeo para verla a pantalla completa con mejor calidad ]

A continuación os incluyo una imagen donde podéis ver el rig de cámara empleado, con sus nueve nulls (aunque el primero de ellos realmente no ejecuta ningún movimiento, simplemente está ahí para poder reposicionar todo el conjunto, actuándo de “ancla” general)

Isfahan camera rig