En esta oportunidad vamos a reutilizar un poco algo de código para explicar cómo funciona el campo de profundidad más conocido en el bajo mundo como DOF, para eso debemos haber hecho el tutorial de desenfoque gaussiano y saber hacer el componente que se le agrega a la cámara para manipular el shader directamente.
Que es Depth of Field
El término viene del mundo de la fotografía y trata de simular las distancias de las lentes que enfocan un objetivo, generalmente las cámaras aficionadas baratas vienen con una distancia de enfoque de 30 mts, eso quiere decir que hasta 30mts el objetivo se verá enfocado, pero más allá de eso todo se verá desenfocado. Hoy en día muchas cámaras tienen enfoque automático y se puede apreciar cómo se enfoca el objetivo y como se desenfoca lo que hay detrás.
En videojuegos le da ese toque cinematográfico como si nuestros personajes fueran actores de una película, de hecho su función narrativa es usar el enfoque para dar el protagonismo a los distintos actores, por eso es usado principalmente en cinemáticas y dentro del gameplay cuando nuestro personaje está observando un objeto cercano o está haciendo uso del zoom.
Preparando el Script de cámara
Lo primero que vamos a hacer es usar crear una variable llamada depth power en nuestro archivo TestRenderImage.cs, luego vamos a clampar o restringir los valores de este entre 0 y 200, luego lo aplicamos a nuestro material.
Pero aunque manipulemos este valor, no hará nada porque aún falta que la cámara nos genere una textura de profundidad.
Este tipo de textura solo lo dá la camara y es transferido al shader a traves de la variable DepthTextureMode.Depth, que activa la textura, algunas veces activar la textura en el ciclo Start() no funciona, entonces a veces toca forzarlo en el ciclo Update(), para saber si está activo vaya a window/analysis/frame debugger y habilitarlo.
Si ve en los primeros resultados una textura como esta ya está listo para comenzar el shader.
Solo un par de anotaciones más sobre esta textura, los tonos de gris depende de la distancia de dibujado de la camara osea del Camera.farClipPlane.
Y la segunda es que esta textura da buen rendimiento en PC, pero para móviles puede tragarse el rendimiento y aca tocaría hacer uso de una sola textura para un montón de efectos o un super shader combinado que administre la misma textura para distintos efectos como SSAO, DOF y SSR
Preparación del Shader
Para el shader podemos tomar el mismo Shader de Gaussian Blur que se hizo la ves pasada y agregarle unas cuantas líneas
Vamos a agregarle la propiedad _DepthPower con un rango entre 0 y 200 que capturaremos su valor a una variable fixed _DepthPower, también agregaremos una variable llamada sampler2D _CameraDepthTexture, esta es una variable que viene por defecto en la cual la textura de profundidad que anteriormente tomamos de la cámara, se irá por defecto a esta textura, por eso no hace falta crear una propiedad para capturar esta textura.
Esta fixed4 blur que seria nuestro blur gaussiano del blog anterior y fixed source que seria la textura original sin modificacion, luego con ellas usaremos una transición.
el truco está en la en la variable float depth que asigna la función predeterminada llamada UNITY_SAMPLE_DEPTH() que toma los datos de profundidad que envia la camara y los convierte en flotante, pero estos deben ser limitados usando las funciones pow y clamp del lenguaje CG .
Ahora teniendo los datos de profundidad, las texturas tanto la original como la desenfocada, procedemos a hacer una mezcla en este caso usando la función de interpolación lerp de la librería del lenguaje CG y voila.
Aqui les dejo el codigo completo para que lo analicen y hagan las modificaciones que quieran.
En si este shader no es el más bonito pero es el más explicativo de como implementar profundidad y este es solo un ejemplo de como usar depth textures, hay más ejemplos por ejemplo como niebla o profundidad del agua.
Quizás se pueda optimizar una que otra instrucción, pero este ejemplo debería bastar para funcionar en un smartphone.
Nos vemos en un próximo blog
Comments