Unity Luces
Sumario
Introducción
- La correcta iluminación de una escena es uno de los aspectos más importantes en el desarrollo de un juego y también uno de los recursos que puedo consumir mayor cantidad de CPU.
- Como norma general se recomienda no abusar del número de luces. Veremos más adelante los tipos de luces, pero se recomienda no tener más de:
- 4 Directional Light
- 512 Punctual Lights (point o spot light)
- 64 Area Lights
- Las luces y por tanto sus efectos (objetos más iluminados, sombras,...) deben ser calculados por el ordenador.
- Estos efectos pueden:
- O estar previamente calculados y 'guardados' en la escena, por lo que cuando se inicie el juego dichos efectos aparecen, pero no mostrarían modificaciones (por ejemplo, al mover un objeto, la sombra quedaría en la misma posición).
- Esta es la técnica empleada en las películas, donde todas las luces y sus efectos son generados por uno o múltiples ordenadores y guardados junto a la película.
- O estar calculadas en 'Real Time', de tal forma que de manera continua se 're-calculan' los efectos-sombras sobre todos los objetos de la escena (es la opción que más recursos consume).
- En el desarrollo de videojuegos normalmente se emplean las dos técnicas, de tal forma que se pre-calculan las sombras-efectos sobre aquellos objetos de la escena que no van a modificar su posición-tamaño (proceso que se conoce con el nombre de Lighting Bake y sobre aquellos objetos que se mueven, las sombras-efectos se calculan dinámicamente.
- Podéis ver en este vídeo la importancia del uso de las luces para conseguir una ambientación correcta en el juego.
- En este vídeo se hace uso de una técnica que genera previamente todas las posibles 'rutas' que puedan tener las fuentes de luz sobre los objetos al mover la cámara (una especie de mezcla de las dos técnicas anteriores).
- Las luces van a generar diferentes ambientes sobre la misma escena, transmitiendo sensaciones diferentes al jugador.
- Una escena iluminada con colores cálidos (luz natural) transmitirá alegría y ánimos, mientras que la misma escena poco iluminada y con colores fríos transmitirá miedo o inquietud...
- Importacion de la luz en una escena
- Para explicar los tipos de luces vamos a construir una nueva escena. La nueva escena tendrá de nombre ESCENA_UD3_Luces.
- Creamos un nuevo material para el suelo.
- FREE Cartoon Halloween Pack => https://assetstore.unity.com/packages/3d/free-cartoon-halloween-pack-45896
- BRIGHT SHINING STAR 3 Skyboxes => https://assetstore.unity.com/packages/2d/textures-materials/sky/3-skyboxes-25142
- Mediaval Fantasy House => https://assetstore.unity.com/packages/3d/environments/fantasy/medieval-fantasy-house-31856
Tipos de luces
- Veremos a continuación los diferentes tipos de luces que permite utilizar Unity y sus principales características.
Directional Light-SkyBox
- Son las luces principales que van a dar a la escena un cierto carácter en la ambientación.
- La Directional Light es un tipo de luz que se crea por defecto al iniciar un proyecto en Unity.
- Una luz ambiental se caracteriza por:
- Estar en un punto en el espacio. Este tipo de luz se aplica a toda la escena y por lo tanto no importa donde se coloque. El efecto será el mismo.
- Tener una dirección, que indica la dirección de los rayos de luz, especificada por su rotación y que va a afectar a como se generen las sombras (más alargadas, sentido,...)
- Viene a ser como los rayos del sol.
- Nota: Podemos rotar dicha luz para ver como las sombras de la escena se modifican...
- Asociado al GameObject 'Directional Light' se encuentra un componente Light con ciertas propiedades de la luz:
- Check: Si desactivamos el check, la escena pasará a no tener luz ambiental, por lo que todo quedará oscurecido.
- Type: Indica el tipo de luz. Veremos posteriormente los diferentes tipos. Ahora mismo marca el tipo de luz => Directional
- Color: El color de los rayos.
- Mode: Lo veremos después, pero indica si queremos que los efectos producidos por la luz ambiental (sombras, brillos,...) se calculen previamente (baked) o en tiempo real (por defecto).
- Intensity: Intensidad del brillo de la luz.
- Indirect Multiplier: Indica la intensidad del brillo de la luz pero de la luz reflejada por otras superficies al aplicarle la luz ambiental.
- Para darle un poco más de ambiente a la escena vamos a bajar la intensidad de la luz direccional:
- Relacionado con la luz ambiental disponemos del SkyBox.
- Hay una sección específica en la Wiki para quien quiera consultarla.
- El SkyBox es el 'espacio' que rodea nuestra escena y que viene a ser el horizonte de la misma.
- Por defecto, aparece el siguiente SkyBox cuando creamos un proyecto en Unity.
- Como vemos es un horizonte que refleja un día despejado y con luz.
- Para ver el SkyBox en la vista escena debemos hacer lo siguiente:
- Visualizando el SkyBox en la vista escena
- El SkyBox va a influir sobre el tipo de luz ambiental que se genera, ya que no sería lógico tener un SkyBox de una noche estrellada con una luz ambiental brillante.
- Además va a influir sobre el 'color' de dicha luz, aplicando una especie de 'tinte' a la misma.
- Si pulsamos sobre uno de los SkyBox descargados, podemos ver las propiedades de 'Tint Color' y exposición del SkyBox:
- Hagamos un ejemplo utilizando los ejemplos de SkyBox descargados previamente:
- Cambiando el SkyBox
- Nota: Si queremos volver al SkyBox por defecto, debemos escoger la opción de menú Window => Rendering => Lighting Settings:
- Aparece una ventana en la que podemos cambiar la opción Source por el SkyBox que queramos. El SkyBox por defecto se llama 'Default-SkyBox'.
- En esta sección solamente vamos a ver los aspectos más importantes en el uso de las luces. Más información sobre el SkyBox en esta sección de la Wiki
Point Light
- Las point light son puntos de luz los cuales emiten luz en todas las direcciones pero hasta un determinado alcance.
- Creando un punto de luz (Point Light)
En el ejemplo he creado un punto de luz dentro de la jerarquía, debajo de una de las farolas, para que si movemos la farola, la luz se mueva también. Como se puede apreciar, aparece un nuevo icono en la escena al seleccionar la luz, con una esfera que la rodea, que representa el alcance de dicha luz. Lógicamente cuanto más lejos, la intensidad de la luz es menor.
- Como ejercicio añadir una luz a cada farola un Point Light y ajustarlo a vuestras preferencias.
Spot Light
- Emite la luz siguiendo una forma de cono.
- Creando un SpotLight
- Como ejercicio vamos a ajustar un SpotLight al modelo de linterna importado.
- Recordar siempre de partir de la posición (0,0,0) y rotación (0,0,0) en todos los modelos y una vez colocados-rotados correctamente, entonces añadirlos dentro de la jerarquía.
- Lo que queremos conseguir es lo siguiente:
- Ejercicio con un SpotLight
- Creamos el siguiente Script:
1 using UnityEngine;
2
3 public class UD3_Luces_Mover_Linterna : MonoBehaviour
4 {
5 [SerializeField]
6 private float velRotacion;
7 [SerializeField]
8 private float velTraslacion;
9
10 private void Reset()
11 {
12 velRotacion = 30f;
13 velTraslacion = 5f;
14 }
15
16 // Update is called once per frame
17 void Update()
18 {
19 float valorXY = Input.GetAxis("Horizontal") * velRotacion * Time.deltaTime;
20 transform.Rotate(valorXY * Vector3.up);
21
22 float valorZ = Input.GetAxis("Vertical") * velTraslacion * Time.deltaTime;
23 transform.Translate(transform.forward * valorZ,Space.World);
24
25
26 }
27 }
- Este script va a mover-rotar la cámara pulsando los cursores del teclado.
- Lo asociamos a la cámara y ejecutamos el juego:
- Moviendo la cámara con la Linterna
Area Light
- Emite la luz siguiendo una forma de rectángulo/círculo.
- Es una especie de luz ambiental pero limitada a un rectángulo/cículo. Emite en todas direcciones pero sólo hacia uno de los lados del rectángulo/círculo que conforma la luz.
- Creando un AreaLight
Uso de capas (layers) con luces
- Como comenté anteriormente, el uso de luces lleva consigo una mayor carga de CPU por parte del procesador, sobre todo por parte de luces en tiempo real, por lo que tenemos que intentar optimizar el uso de este tipo de luces.
- Una forma de hacerlo es determinar sobre qué objetos de la escena va a aplicarse una iluminación.
- Esto se consigue mediante el uso de capas (Layers).
- El uso de capas también va a permitirnos tener escenas en las que:
- Una determinada luz afecte sólo a un game object específico, por ejemplo a un personaje concreto dentro de la escena.
- Hacer que todos los objetos de una habitación estén a oscuras excepto el techo o el suelo.
- Vamos a preparar la escena y añadimos la 'Mediaval Fantasy House' importada previamente al proyecto.
- Ahora vamos a hacer que la luz ambiental 'no afecte' a la casa, haciendo que permanezca totalmente a oscuras.
- Haciendo uso de capas para evitar la iluminación
Sombras
- Más información en este enlace.
- Uno de los aspectos que tenemos que tener en cuenta en el uso de luces son las sombras generadas por esas luces.
- El uso de sombras dará un realismo mucho mayor a la escena, pero tendremos que tener en cuenta la carga de CPU que también se genera e intentar minimizarla.
- En el manejo de sombras van a participar dos GameObjects:
- El objeto que se va a iluminar.
- La luz.
- Componente: El objeto que se va a iluminar
- Cada GameObject que se dibuja en la escena tiene un componente 'Mesh Renderer' con una sección específica de sombras:
- Cast Shadown:
- On: Indica que el GameObject va a generar sombras al ser iluminado (dependerá ahora de la configuración de la luz que ese objeto genera sombras).
- Off: No genera sombras. Por ejemplo, en GameObjects muy pequeños sería una opción a considerar.
- Two Sided: Usado para objetos con una geometría simple (de caras) como un Quad o Plano.
- Shadows Only: Hace que se genere la sombra pero el objeto no se dibuja.
- Receive Shadows: Es un CheckBox con el que indicamos si el Mesh va a recibir sombras del resto de GameObjects.
- En nuestro ejemplo, si seleccionamos el suelo (Plane) y desmarcamos esta opción, veremos que el suelo deja de recibir las sombras del resto de GameObjects de la escena.
- Componente: La luz que se va a emplear:
- Cada Tipo de Luz que se utiliza en la escena tiene una propiedad 'Shadow Type':
- Shadow Type:
- No Shadows: Indica que la luz no va a generar sombras. Podemos comprobarlo en el ejemplo, como la luz de la farola no genera sombras.
- Hard Shadows: Genera sombras con un menor coste de CPU pero con unos bordes en la sombra muy 'marcados' por el Mesh que lo genera, poco realistas, ya que las sombras, debido al aire y otras partículas se difumina.
- Soft Shadows: Mayor coste de CPU pero sombras más realistas.
- Veamos un ejemplo con la luz direccional que tenemos en la escena:
- Modificando el tipo de sombras de la luz direccional
Con este tipo de sombras disponemos de varios parámetros para ajustarla. Strength: Valores desde 0-1, siendo 1 la sombra con mayor fuerza, perdiendo 'negrura' hasta llegar al valor 0. Resolution: Cada vez que se mueve la fuente de luz es necesario recalcular las sombras. Con este parámetro indicamos la calidad de la imagen sobre la que se va a generar la sombra. Cuanto más resolución, la sombra estará más definida pero el coste de CPU será más grande. La opción por defecto es la de 'Use Quality Settings' la cual se encuentra definida en la opción de menú Edit => Project Settings.
El uso de los parámetros 'Bias' pueden ser consultados en este enlace. A afectos prácticos, el parámetro 'Bias' va a hacer que la sombra parta de un punto más elejado del Mesh. Debemos ajustarlo para que parta justo donde aparece la base de la cruz y que no le de sombra a la base de la cruz(en esta escena, claro).
El tipo de sombra 'Soft Shadow' intenta emular la sombra de una forma más real, haciendo que se difumine por la distancia. Al igual que en el caso anterior, podemos modificar la 'fuerza' de la sombra haciendo que sea más oscura o difuminada con el parámetro 'Strength' (dependerá de la ambientación que queramos darle a la escena).
- Nota Importante:
- Debemos siempre escoger la opción que con menor consume de CPU nos permite tener una escena lo más realista posible.
- Una técnica empleada es la de 'dibujar' sombras sobre la textura directamente y así ahorrarnos el aplicar la luz sobre el GameObject. Para dibujar sombras se puede emplear cualquier programa de dibujo, como Gimp o PhotoShop. Por ejemplo, en la escena que nos ocupa de ejemplo, veremos en un punto posterior, como crear unos ojos que nos están observando desde la puerta. Dichos ojos podrían ser dibujados sobre la textura directamente...En nuestra escena es más complicado encontrar GameObjects para aplicar esta técnica ya que llevamos una luz, pero en escenas con luces estáticas, muchos de los objetos podrían tener sus sombras 'dibujadas' sobre la textura.
Cookies
- Más información en este enlace.
- Las cookies son un recurso aplicado al uso de luces que nos permite utilizar una textura como 'puente' entre la escena y la luz aplicada a dicha escena.
- Lo que hace dicha textura es, haciendo uso del canal alfa, aplicar un filtro a la luz de la escena, haciendo que el color negro impida el paso de la luz, el color blanco deje pasar completamente la luz y los grises cierto nivel de transparencia.
- El uso que se le puede dar a este tipo de texturas es múltiple, ya que podemos 'simular' el paso de la luz sobre cualquier objeto, el cual da lugar a sombras sobre la escena siguiendo la forma de ese objeto.
- Ejemplos de uso son el paso de la luz a través de una ventana, sombras de árboles sobre los protagonistas de una escena (pero sin que sean las sombras de los GameObjects árboles, serían simuladas), paso de sombras de nubes sobre la escena...
- Para crear una cookie podemos ir a cualquier editor gráfico y hacer uso de los colores negro-gris-blanco para crear dicha textura, ya que Unity, cuando la importamos, podemos indicar que utilice dichos colores para crear el canal ALFA.
- Por ejemplo, la siguiente imagen fue creado con Paint de Windows (pulsar sobre la imagen, después pulsar el botón derecho sobre la imagen y escoger save as):
- La descargamos y la importamos a Unity, arrastrándola desde un explorador de archivos (para que quede todo organizado llevarla a una carpeta Textures dentro de la Unidad 3).
- Creando una cookie
En 'Wrap Mode' determinamos como se va a adaptar la textura al área donde se va a dibujar. Por defecto, se repite una y otra vez hasta ocupar todo el área. En nuestro caso queremos que se adapte al área iluminada por la luz ambiental y no queremos que se repita. Por lo tanto escogemos Clamp y presionamos el botón Apply.
- El ejemplo anterior no es muy útil para la escena que estamos haciendo.
- Vamos a realizar otro ejemplo haciendo uso de una Spot Light para iluminar parte de la entrada de la casa y hacer que aparezcan dos ojos mirando, como muestro en la siguiente imagen:
- Primero creamos la textura de los ojos. Para ello yo he usado Gimp y la textura de los ojos la he obtenido de este enlace.
- La textura para descargar (pulsar sobre la imagen, después pulsar el botón derecho sobre la imagen y escoger save as):
- Tendríais que ser capaces de realizar el ejercicio...
- Solución ejercicio Cookie
Creamos un tipo de luz 'SpotLight'. Yo la he creado dentro del muro (wall) en la ventana de jerarquía para que si se mueve la casa también se mueva la luz. Es necesario arrastrar la Cookie creada a la propiedad Cookie de la luz y cambiamos la propiedad Culling Mask para que sólo afecte a la casa (en un ejercicio anterior asociamos la casa a dicha máscara). Movemos la luz para ajustarla a la pared de la casa y obtendremos el resultado pedido.
Optimizando el uso de luces: BAKING
- Como comenté anteriormente el uso de luces es uno de los aspectos que más consumo de CPU generan.
- Todas las luces utilizadas en el ejemplo anterior son luces 'realtime' (menos el Area Light) en el sentido que el efecto que generan se calcula en tiempo real en cada fotograma del juego.
- Para minimizar el uso de CPU podemos emplear una técnica que consiste en 'precalcular' el efecto de la luz sobre los objetos y guardar los efectos (sombras, brillos,...) para ser mostrados durante el juego pero sin necesidad de que la CPU los tenga que calcular.
- Esta técnica conocida como BAKE tiene como ventaja el aumento del rendimiento en nuestro juego y como desventaja que no podemos aplicarlo a todas las luces y objetos.
- Sólo podremos hacerlo sobre aquellos objetos estáticos que no van a variar de posición y sobre aquellas luces que no van a moverse, si queremos tener una visión real de la escena.
1º Paso: Marcar los GameObject como LightMap Static
- Los objetos Static son aquellos que no van a moverse en la escena.
- Cuando pulsamos sobre un GameObject de la escena, en la ventana Inspector podemos indicar si son estáticos o no.
- Existen diferentes tipos de objetos estáticos que se aplicarán a diferentes recursos de Unity. Por ejemplo, el 'Navigation Static' se aplica a un recurso de Unity que permite moverse dentro de la escena esquivando los objetos estáticos que estén marcados (se puede consultar en este punto de la Wiki).
- En nuestro caso llega con marcar la opción LightMap Static como ya vimos en el tipo de luz 'Area Light'.
- Siguiendo con nuestra escena, vamos a marcar como 'LightMap Static' a la casa, las tumbas, el plano y las farolas (indicar que la casa no recibe luz ambiental, por lo que no tendría por qué marcarse).
- Para ello podemos seleccionar los objetos de uno en uno o todos juntos y cambiar la propiedad.
- Para organizarlo un poco mejor, vamos a crear un Empty GameObject de nombre 'Environment' y colocaremos todos los GameObjects anterior dentro del él en la jerarquía:
- Marcando los objetos como LightMap Static
2º Paso: Crear un mapa específico para las luces
- Cuando hablé sobre las texturas aplicadas a los objetos 3D indiqué que se hacía uso de un mapa específico donde estaban representadas las texturas que serían aplicadas al objeto 3D.
- Para realizar el proceso de Baking es necesario que Unity emplee su propio mapa y que no tenga que hacer uso del mapa de las texturas para 'dibujar' los efectos de las sombras e iluminación sobre los objetos.
- Creando un mapa específico para las luces
3º Paso: Light Baking
- Este es el paso que va a generar y guardar los efectos que produce la luz sobre los objetos marcados como Static LightMap.
- Unity hace uso del motor EnLighten para realizar el proceso de Baking.
- Todas las opciones se encuentran en la opción de menú Window => Rendering => Light Settings.
- Como vemos disponemos de tres pestañas:
- Scene: Relacionado con parámetros globales que afectan a toda la escena.
- RealTime LightMaps: Son los mapas que utiliza la luz relacionados con GameObjets con iluminación en tiempo real.
- Baked LightMaps: Son los mapas que utiliza la luz relacionados con GameObjets con iluminación en pre-calculada (Baked).
- Los mapas se guardan en formato EXR.
- En la pestaña Scene podemos observar como en la parte baja está marcada la opción Auto. Esto significa que Unity empezará a crear los mapas de luz sobre los objetos marcados como 'Static LightMap' y por eso aparece en la parte baja-derecha la opción Baking...(ETA:xx:yy:zz). Si desmarcamos esta opción, debemos de manualmente pulsar el botón Generate Lighting.
- Teniendo la opción 'Auto' marcada, cualquier modificación en la posición de los objetos marcados como 'LightMap Static' llevará consigo la 'recreación' de los mapas asociados a la luz.
- Si queremos borrar la información generada y guardada en los mapas de luz, debemos de desmarcar la opción 'Auto Generate' y pulsar el botón con la opci
- Nota Importante: Con juegos con gran cantidad de GameObjects y uso de Terrains se debe desmarcar la opción de 'Auto Generate' y una vez colocado todo y marcado todos los objetos de la escena que sean 'LightMap Static' se pulsará el botón para generar los mapas asociados a la luz.
Investigación
- Projector: Permiten generar una sombra en base a un material. A diferencia de las Cookies, no es necesario la participación de una luz para generar la sombra.
-- Ángel D. Fernández González -- (2018).


