|
Blending (Combinación) En este tutorial vamos a examinar una técnica llamada blending en inglés, que es algo así como mezcla o
combinación, que nos permite mezclar los píxeles que estamos dibujando con
otros que fueron dibujados previamente. Es decir, combinamos primitivas sobre
otras primitivas que ya fueron dibujadas. Esta técnica nos permite obtener una
gran variedad de efectos, por ejemplo, transparencia.
Objetivos: ·
Entender como
funciona el blending y como usarlo. ·
Aprender
acerca de los diferentes modos de blending que tiene Direct3D. ·
Aprender
acerca del componente alfa y como controla la transparencia en las primitivas. La Ecuación de Combinación Imaginemos por
un momento que estamos dentro de una casa, con una ventana, mirando hacia el
exterior. Por simpleza, el exterior ya ha sido dibujado, y lo que queremos
hacer es que se vea la ventana, pero que también se vea el exterior. ¿Cómo se
logra esto? Muy simple, cuando estamos dibujando los píxeles en los triángulos
de la ventana, necesitamos combinar los colores de la ventana con los del
exterior, de tal forma que se vean ambos. La idea de combinar estos dos
píxeles, el píxel origen (source pixel) que se está escribiendo, en nuestro
caso el de la ventana, con otro píxel destino (destination pixel) se llama
blending. Cabe añadir que transparencia no la única operación que se puede
hacer sobre dos píxeles, existen más como veremos más adelante. Regla: Se deben dibujar los objetos que no utilizan blending primero. Luego se
deben ordenar los objetos que usan blending por su distancia a la cámara; esto
se puede lograr más eficientemente si los objetos están en el espacio de vista
(ya transformados para la pantalla), así que se puede simplemente ordenar el
componente z. Finalmente, se deben dibujar los objetos que utilizan
blending de atrás hacia delante. La siguiente es
la fórmula usada para combinar dos valores de píxeles: PixelSalida = PixelOrigen x
FactorCombianciónOrigen + PixelDestino x FactorCombianciónDestino Todas las
variables anteriores son vectores de color 4D (r,g,b,a) y el símbolo x denota una multiplicación de
componentes. PixelSalida -
El pixel resultante. PixelOrigen - El pixel
actual que estamos dibujando, y que será combinado con el que ya existe en el
back buffer. FactorCombinaciónOrigen - Un valor en el intervalo [0,1] que
especifica cuanto del píxel de origen será usado en la combinación. PixelDestino - El píxel
existente en el back buffer, dibujado con anterioridad. FactorCombianciónDestino - Un valor en el intervalo [0,1], que
especifica cuanto del píxel de destino será usado en la combinación. Los factores del
origen y del destino nos dejan modificar los valores originales de los píxeles
en una variedad de formas, y así nos permiten conseguir diferentes efectos. El blending está
deshabilitado por defecto, y se habilita cambiando el estado de renderizado
D3DRS_ALPHABLENDENABLE a verdadero. D3D9->SetRenderState(D3DRS_ALPHABLENDENABLE,
true); Nota:
Blending no es una operación barata y debe utilizarse sólo con aquella
geometría que lo necesite. Cuando se termine de dibujar esa geometría, se debe
deshabilitar de nuevo. También es mejor agrupar todos los triángulos que
utilizan blendin, para así evitar tener que habilitar
y deshabilitar el blending muchas veces por cuadro/frame. Factores de Combinación Usando
diferentes factores de combinación para el píxel de entrada y salida se pueden
crear docenas de efectos. Se pueden establecer los valores del factor de
combinación para el píxel de origen y el de salida estableciendo los valores de
D3DRS_SRCBLEND y D3DRS_DESTBLEND con SetRenderState: D3D9->SetRenderState(D3DRS_SRCBLEND, Origen); D3D9->SetRenderState(D3DRS_DESTBLEND,
Destino); Donde Origen y
Destino pueden tomar los siguientes valores: D3DBLEND_ZERO FactorCombinación* = (0,
0, 0, 0) D3DBLEND_ONE FactorCombinación* = (1, 1, 1, 1) D3DBLEND_SRCCOLOR FactorCombinación* = (rs, gs, bs, as) D3DBLEND_INVSRCCOLOR FactorCombinación* = (1 – rs, 1 – gs, 1 – bs,
1 – bs) D3DBLEND_SRCALPHA FactorCombinación* = (as, as, as, as) D3DBLEND_INVSRCALPHA FactorCombinación* = (1 – as, 1 – as, 1 – as, 1 – as) D3DBLEND_DESTALPHA FactorCombinación* = (ad, ad, ad, ad) D3DBLEND_INVDESTALPHA FactorCombinación* = (1 – ad, 1 – ad, 1 – ad, 1 – ad) D3DBLEND_DESTCOLOR FactorCombinación*
= (rd, gd, bd, ad) D3DBLEND_INVDESTCOLOR FactorCombinación* = (1 – rd, 1 – gd, 1 – bd, 1 – ad) D3DBLEND_SRCALPHASAT FactorCombinación* = (f, f,
f, 1), donde f = min(as, 1 – ad) D3DBLEND_BOTHINVSRCALPHA Este
modo establece el factor de combinación origen como (1 – as, 1 – as, 1 – as, 1 – as) y el valor de combinación destino como
(as, as, as, as). Este modo de combinación solo es
válido para D3DRS_SRCBLEND. Los valores por defecto para los
factores de combinación de origen y destino son D3DBLEND_SRCALPHA
y D3DBLEND_INVSRCALPHA,respectivamente. Transparencia En los tutoriales
anteriores ignoramos el componente alfa del color de los vértices y los
materiales porque no los necesitábamos, ya que son usados generalmente para
blending. Sin embargo, el componente alfa de cada color de los vértices es
dibujado en las caras así como lo son los colores, pero en vez de determinar el
color del píxel, determina el componente alfa. El componente alfa es principalmente
utilizado para especificar el nivel de transparencia de un píxel. Asumiendo que
hemos reservado 8 bits para el valor alfa de cada píxel, el intervalo válido de
valores para el componente alfa sería [0,255], donde [0,255] correspondería a
una opacidad de [0%, 100%]. Luego, píxeles con un valor de alfa negro (0),
serían completamente transparentes, con valores grises se obtendrían
semi-transparencias y con blanco (255), el píxel sería completamente opaco. Para que la combinación funcione de esta
forma, y el componente alfa sea el que describa la transparencia de los
píxeles, debemos establecer el factor de combinación origen a D3DBLEND_SRCALPHA
y el valor destino a D3DBLEND_INVSCRALPHA. Así, el píxel de origen se vería el
factor dado por el valor alfa, y al píxel destino, se vería el resto del
porcentaje, el inverso del valor alfa. Por ejemplo, con un valor de 64 (25%),
el color final sería un 25% del color origen, y un 75% del color destino. Y así
obtendríamos transparencia. El Canal Alfa En vez de utilizar el componente alfa
del vértice, podemos obtener el valor alfa de un canal alfa en la textura. El canal
alfa es un set de bits extra reservados para cada texel y guarda el componente
alfa. Cuando la textura es dibujada en una primitiva, los componentes alfa
también son dibujados y se convierten en el componente alfa para los píxeles de
la primitiva siendo dibujada. En las figuras podemos ver, la representación de
un canal alfa y su efecto en el dibujado de la textura.
Figura: Un mapa de grises de 8 bits
representando el canal alfa de una textura.
Figura: Una textura cuyo canal alfa representa la
opacidad en el cuadrado dibujado. Especificando el Alfa de Origen Por defecto, si la textura actual tiene
un canal alfa, el alfa es tomado de ese canal. Si no tiene canal alfa, el valor
alfa se obtiene del color del vértice. Sin embargo, se puede especificar de
donde obtener el valor alfa, si del valor difuso o del canal alfa de la textura
así: //
Tomar el alfa del valor difuso del vértice D3D9->SetTextureStageState(0,
D3DTSS_ALPHAARG1, D3DTA_DIFFUSE); D3D9->SetTextureStageState(0,
D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); //
Tomar el valor alfa de la textura D3D9->SetTextureStageState(0,
D3DTSS_ALPHAARG1, D3DTA_TEXTURE); D3D9->SetTextureStageState(0,
D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); Como crear un canal alfa No todos los
formatos de imágenes tienen canales alfa. Algunos muy usados son Targa (.TGA), y DDS. DirectX trae
un programa que nos permite añadirle un canal alfa a las texturas llamado
DirectXTex.exe, en \Bin\DXUtils dentro de la carpeta del SDK de DirectX. También se pueden crear usando muchas otras
herramientas disponibles: Adobe Photoshop, CorelDraw, GIMP, etc. Código Para no
complicar las cosas, usaremos el tutorial anterior,
pero añadiremos las siguientes líneas de código y moveremos la esfera en frente
de la caja para ver el efecto de la transparencia. bool Inicializar() { . . .
// Usar el
valor alfa de la textura // 1. Se tomara del píxel origen, los valores alfa de
cada texel en el canal alfa como factores // y se multiplicaran por el color de cada texel,
asi, negro = transparente, blanco = sólido. // Establecer los valores de combinación // 2. En el píxel destino, se utilizara el inverso es
decir, si es negro = sólido, // si es blanco = no se ve
pues queda detrás de la textura. D3D9->SetRenderState(D3DRS_SRCBLEND,
D3DBLEND_SRCALPHA); D3D9->SetRenderState(D3DRS_DESTBLEND,
D3DBLEND_INVSRCALPHA); return
true; } Resumen
|
webmaster aguerra en utp.edu.co