Consigue un 20% de descuento usando el código RELEASE en la compra de tu libro. Por tiempo limitado.

Introducción al lenguaje de programación de shaders

3.2.0. SubShader Culling y Depth Testing

Esta publicación está disponible en...

Para poder entender ambos conceptos primero debemos conocer el funcionamiento del Z-Buffer (también conocido como Depth Buffer) y del Depth Testing.

Antes de iniciar debemos considerar que los píxeles poseen valores de profundidad.

Estos valores son almacenados en el Depth Buffer el cual determina si es que un objeto va en frente o detrás de otro en pantalla.

Por otra parte, el Depth Testing es una condicional que determina si es que un píxel será actualizado o no en el Depth Buffer.

Como ya sabemos, un píxel posee un valor asignado que se mide en color RGB el cual es almacenado en el Color Buffer. El Z-Buffer agrega un valor extra que mide la profundidad de un píxel en términos de distancia a la cámara sólo para aquellas superficies que se encuentran dentro del frustum de la misma, esto permite que dos píxeles sean iguales en color, pero distintos en profundidad.

Mientras más cercano se encuentre el objeto a la cámara, más bajo será el valor del Z-Buffer y los píxeles con valores de búfer más bajo sobrescriben a los píxeles con valores más altos.

Para entender el concepto, vamos a suponer que tenemos una cámara y algunas primitivas en nuestra escena; todas posicionadas en el eje “Z” del espacio. Ahora bien, ¿por qué en el eje Z? la “Z” de Z-Bufferproviene del hecho de que el valor Z mide la distancia entre la cámara y un objeto en el eje “Z” del espacio, mientras que los valores en “X e Y” miden el desplazamiento horizontal y vertical en la pantalla.

La palabra «Buffer» se refiere a un “espacio de memoria” en el que se almacenarán datos de manera temporal, por lo tanto, Z-Buffer se refiere a los valores de profundidad entre los objetos de nuestra escena y la cámara, los cuales se asignan a cada píxel.

Para ejemplificar, vamos a dibujar una pantalla de 36 píxeles totales.
Cada vez que posicionamos un objeto en nuestra escena, tal objeto ocupa una cierta área de píxeles en la pantalla. Entonces, vamos a suponer que deseamos posicionar un quad de color verde en la escena. Dada su naturaleza, este ocupará desde el píxel 8 al 29, por ende, todos los píxeles entre esta área se encenderán y se pintarán de color verde, así mismo, esta información será enviada tanto al Z-Buffer como al Color Buffer.

(Fig. 028. En el Z-Buffer se guardará la profundidad del objeto en la escena, y en el Color Buffer se guardará la información de color RGBA).

En el Z-Buffer se guardará la profundidad del objeto en la escena, y en el Color Buffer se guardará la información de color RGBA.

Posicionamos un nuevo quad en la escena, esta vez de color rojo y su posición será más cercana a la cámara. Para diferenciarlo del anterior, haremos este quad más pequeño, ocupando desde el píxel 15 al 29. Como podemos ver, esta área ya está ocupada por la información del quad inicial, entonces, ¿qué ocurre aquí? Por el hecho de que el quad rojo se encuentra a menos distancia de la cámara, este sobrescribe los valores tanto del Z-Buffer como del Color Buffer, generando que los píxeles entre esta área se enciendan, reemplazando al color anterior.

(Fig. 029)

En el caso de agregar un nuevo elemento en la escena que esté aún más cercano a la cámara, este proceso se repetirá de la misma manera. En conclusión, los valores del Z-Buffer y del Color Buffer serán sobrescritos en la medida en que un objeto se encuentre más cercano a la cámara.

Una manera de generar efectos visuales atractivos es a través de la modificación de los valores del Z-Buffer. Para ello hablaremos de tres opciones que están incluidas en Unity: Cull, ZWrite y ZTest.

Al igual que los Tags, las opciones de culling and depth testing pueden ser escritas en campos distintos: dentro del campo del SubShader o dentro del campo del Pass. La posición va a depender del resultado al cual queramos llegar y a la cantidad de pases con la cual deseamos trabajar.

Para entender este concepto, vamos a suponer que deseamos crear un shader para representar la superficie de un diamante. Para ello, vamos a necesitar dos pases: Al primero lo utilizaremos para el color de fondo del diamante, y al segundo lo utilizaremos para el brillo de la superficie del mismo . En este caso hipotético, debido a que necesitamos dos pases que cumplen una función distinta, será necesario configurar las opciones del Culling dentro de cada pase de manera independiente.

Siguenos para mantenerte informado sobre todas las novedades, actualizaciones y más.

Únete al grupo para compartir tus experiencias con otros desarrolladores.

¡Suscríbete a nuestro canal y sigue aprendiendo sobre desarrollo de juegos!

jettelly-logo

Jettelly Team

Somos un equipo de desarrolladores independientes con más de 9 años de experiencia en videojuegos. Como estudio independiente, hemos desarrollado Nom Noms el que publicamos con Hyperbeard en 2019. Actualmente estamos desarrollando La Biblia de Shader en Unity.

Síguenos en nuestras redes sociales.