¿Qué es el stencil buffer?
Así como existen el color buffer y el Z-Buffer, éste contiene información extra normalmente guardando valores enteros y es usado comúnmente para delimitar el área de 'rendering' de ciertos objetos en pantalla e indicar las condiciones bajo las cuales se van a pintar.
Tiene muchos usos avanzados en VFX pero en este artículo veremos un ejemplo muy sencillo de como utilizarlo con shaders de Unity.
- Funciona con cualquier Render Pipeline, en mi caso utilizare URP.
- Conocimiento básico de programación de shaders en HLSL.
- Conocimiento básico de Unity.
- En mi caso, estoy utilizando Unity 2020.3 pero debería funcionar en otras versiones sin problema.
EJERCICIO
SINTAXIS
Para esto, debemos utilizar dos shaders distintos, uno para el objeto 'máscara' y otro para el objeto que se va a pintar únicamente en la silueta de la misma.
Voy a crear dos 'Unlit Shader' distintos para este ejemplo, uno para la máscara y otro para el objeto a enmascarar.
Escribiremos el siguiente código en el campo del 'SubShader' y antes del 'pass', recuerda que son dos shaders distintos.
- ref: Un entero que se asigna al shader que el buffer leerá y podrá comparar con otros shaders para saber como comportarse. Estos enteros pueden ir desde 0 a 255.
- comp: La operación de comparación que debe hacer para saber si el objeto se renderiza o no. De ser exitosa la comparación se ejecutara el 'pass' y por ello el 'fragment output'.
- pass: Esta sección indica que hacer con el número de referencia en relación con el stencil buffer, en este caso usamos 'replace', 'este escribirá el número de referencia en nuestro stencil buffer.
-'equal' Se refiere a que los pixeles van a pintarse en pantalla cuando el valor de referencia sea el mismo en el stencil buffer que en el shader (en este caso 1)
-'always' Se refiere a que los pixeles del objeto que tenga este shader siempre se van a pintar en pantalla.
A continuación, vamos a crear un plano y una esfera como objetos de prueba, posicionaremos la esfera por delante del plano
Creamos dos materiales a partir de los dos shaders que acabamos de escribir, asignamos la máscara al plano (este va a delimitar el área de rendering de nuestra esfera), y asignaremos el otro material a la esfera.
Podemos ver ahora como nuestro plano está actuando como máscara limitando el área donde nuestra esfera se está pintando en pantalla.
Esto sucede debido a que el plano está sustituyendo el valor dentro del stencil buffer a 1, y en el shader de la esfera le estamos indicando que solo se va a ejecutar el 'pass' de su shader (y con esto su fragment output) solo si al comparar las referencias en el stencil buffer éste es igual a 1.
NOTA: Es posible que al momento de asignar los materiales la esfera o el plano parpadeen o desaparezcan de repente, para resolver esto, basta con aumentar +1 al render queue del material de la esfera, esto es para informarle al z-buffer que ésta debe pintarse frente al plano, de otra manera estarán compitiendo por el mismo espacio dentro del buffer.
EXTRAS
En muchas ocasiones no queremos que nuestra máscara tenga color alguno, hacer esto es muy sencillo, simplemente agregaremos una línea 'ColorMask 0' en el campo del SubShader, esto detiene al shader de escribir en cualquiera de los canales de color RGBA, por lo que nuestra máscara tendrá el mismo funcionamiento pero sin color alguno.
Es posible utilizar el stencil Buffer con shader graph?
ResponderBorrarHasta donde yo sé, no es posible.
Borrar