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.1.7. SubShader Blending

Esta publicación está disponible en...

Blending es el proceso de mezclar dos píxeles en uno. Su comando es compatible tanto en Built-in RP como en Scriptable RP.

El Blending ocurre en una etapa denominada “merging” la cual permite combinar el color final de un píxel (aquellos píxeles que han sido procesados en el fragment shader stage) con su profundidad (depth). Esta etapa, que ocurre al final del render pipeline; después del fragment shader stage, es donde el stencil-buffer, z-buffer y color blending se ejecutan.

Por defecto, esta propiedad no viene escrita en nuestro shader ya que es una función opcional y es utilizada principalmente cuando trabajamos con objetos transparentes, e.g., cuando debemos dibujar un píxel con bajo nivel de opacidad enfrente de otro.

Su valor por defecto es “Blend Off”, pero podemos activarlo para generar distintos tipos de Blending, similar a los que aparecen en photoshop.

Su sintaxis es la siguiente:

Blend [SourceFactor] [DestinationFactor]

“Blend” es una función que requiere dos valores llamados “factores” para su funcionamiento, y basados en una ecuación será el color final que obtendremos en pantalla. Según la documentación oficial en Unity, la ecuación que define el valor del Blending es la siguiente:

B = SrcFactor * SrcValue [OP] DstFactor * DstValue.

Para entender esta operación debemos considerar lo siguiente: Primero ocurre el fragment shader stage y luego, como proceso opcional; el merging stage.

SrcValue” (source value), el cual ha sido procesado en el fragment shader stage, corresponde al output de color RGB que posee un píxel.

DstValue” (destination value) corresponde al color RGB que ha sido escrito en el “destination buffer”, mejor conocido como “render target” (SV_Target). Cuando las opciones de Blending no están activas en nuestro shader, SrcValue sobrescribe a DstValue. DstValue. Sin embargo, si activamos esta operación, ambos colores son mezclados para obtener un nuevo color, el cual sobrescribe a DstValue posteriormente.

SrcFactor” (source factor) al igual que “DstFactor” (destination factor) son vectores de tres dimensiones que varían dependiendo de su configuración. Su función principal es modificar los valores del SrcValue y DstValue para lograr efectos interesantes.

Algunos factores que podemos encontrar en la documentación de Unity son:

  • Off, deshabilita las opciones de Blending.
  • One, (1, 1, 1).
  • Zero, (0, 0, 0).
  • SrcColor es igual a los valores RGB del SrcValue.
  • SrcAlpha es igual al valor Alpha del SrcValue.
  • OneMinusSrcColor 1 menos los valores RGB del SrcValue (1 – R, 1 – G, 1 – B).
  • OneMinusSrcAlpha 1 menos el Alpha del SrcValue (1 – A, 1 – A, 1- A).
  • DstColor es igual a los valores RGB del DstValue.
  • DstAlpha es igual al valor Alpha del DstValue.
  • OneMinusDstColor 1 menos los valores RGB del DstValue (1 – R, 1 – G, 1 – B).
  • OneMinusDstAlpha 1 menos el Alpha del DstValue (1 – A, 1 – A, 1- A).

Cabe mencionar que el Blending del canal Alpha se lleva a cabo de la misma manera con la que procesamos el color RGB de un píxel, pero se realiza en un proceso independiente debido a que no se utiliza con frecuencia. Así mismo, al no realizar este proceso, la escritura en el render target es optimizada.

Vamos a ejemplificar la explicación anterior de la siguiente manera.

Digamos que tenemos un píxel de color RGB con los valores [0.5R, 0.45G, 0.35B]. Este color ha sido procesado por el fragment shader stage, por lo tanto, corresponde al DstValue. Ahora, multiplicamos este valor por el el “SrcFactor One” el cual es igual a [1, 1, 1]. Todo número multiplicado por “1” da como resultado el mismo valor, por lo tanto, el resultado entre el SrcFactor y el DstValue es igual a su valor inicial.

B = [0.5R, 0.45G, 0.35B] [OP] DstFactor * DstValue.

“OP” se refiere a la operación que vamos a realizar. Por defecto, está configurada en “Add” la cual significa “sumar”.

B = [0.5R, 0.45G, 0.35B] + DstFactor * DstValue.

Una vez que hemos obtenido el valor de la primera operación, está sobreescribe al DstValue, por lo tanto, queda configurada con exactamente el mismo color [0.5R, 0.45G, 0.35B]. Entonces, multiplicaremos este color por el “DstFactor DstColor”, que es igual al valor que tenemos actualmente en el DstFactor.

DstFactor [0.5R, 0.45G, 0.35B] * DstValue [0.5R, 0.45G, 0.35B] = [0.25R, 0.20G, 0.12B].

Finalmente, el color output para el píxel es.

B = [0.5R, 0.45G, 0.35B] + [0.25R, 0.20G, 0.12B].
B = [0.75R, 0.65G, 0.47B]

Si deseamos activar el Blending en nuestro shader, debemos usar comando Blend seguido del SrcFactor y luego el DstFactor. Su sintaxis es la siguiente:

Shader “InspectorPath / shaderName”
{
    Properties {} …
    SubShader
    {
        Tags { "Queue" = "Transparent" “RenderType”=”Transparent”} 
        Blend SrcAlpha OneMinusSrcAlpha
    }
}

Si deseamos utilizar Blending en nuestro shader va ser necesario agregar y modificar el “Render Queue”. Como ya sabemos, el valor por defecto del tag “Queue” es igual a “Geometry”, lo que significa que nuestro objeto lucirá opaco. Si deseamos que nuestro objeto luzca transparente, entonces primero debemos cambiar el “Queue” a “Transparent” y luego agregar algún tipo de blending.

Los tipos de blending más comunes son los siguientes:

Blend SrcAlpha OneMinusSrcAlpha     // Common transparent blending 
Blend One One                       // Additive blending color 
Blend OneMinusDstColor One          // Mild additive blending color 
Blend DstColor Zero                 // Multiplicative blending color 
Blend DstColor SrcColor             // Multiplicative blending x2 
Blend SrcColor One                  // Blending overlay 
Blend OneMinusSrcColor One          // Soft light blending 
Blend Zero OneMinusSrcColor         // Negative color blending

Una manera distinta de configurar nuestro Blending es a través de la dependencia “UnityEngine.Rendering.BlendMode”. Esta línea de código nos permite cambiar el Blending de un objeto desde el inspector en el material. Para configurarla primero debemos agregar el “Toggle Enum” en nuestras propiedades y luego declarar tanto el SrcFactor como el DstFactor.

Su sintaxis es la siguiente:

// [Enum(UnityEngine.Rendering.BlendMode)] _SrcBlend (“Source Factor”, Float) = 1
// [Enum(UnityEngine.Rendering.BlendMode)] _DstBlend (“Destination Factor”, Float) = 1

Shader “InspectorPath / shaderName”
{
    Properties 
    {
        [Enum(UnityEngine.Rendering.BlendMode)] 
            _SrcBlend (“SrcFactor”, Float) = 1
        [Enum(UnityEngine.Rendering.BlendMode)] 
            _DstBlend (“DstFactor”, Float) = 1
    }
    SubShader
    {
        Tags { "Queue" = "Transparent" “RenderType”=”Transparent”} 
        Blend [_SrcBlend] [_DstBlend]
    }
}

Las opciones de Blending pueden ser escritas en campos distintos: dentro del campo del SubShader o dentro del campo del Pass, la posición va a depender de la cantidad de pases y resultado que deseamos obtener.

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.