Alpha Blending, Stencil Buffer - PowerPoint PPT Presentation

1 / 13
About This Presentation
Title:

Alpha Blending, Stencil Buffer

Description:

... el efecto de 'double blending' al proyectar sombras ... Double Blending ... Para evitar este efecto de 'double blending' se utiliza el stencil buffer, ... – PowerPoint PPT presentation

Number of Views:144
Avg rating:3.0/5.0
Slides: 14
Provided by: Dan8181
Category:

less

Transcript and Presenter's Notes

Title: Alpha Blending, Stencil Buffer


1
Alpha Blending, Stencil Buffer
  • Francisco Javier Tirado Sarti
  • fjtirado_at_lucent.com

2
Componente Alpha
  • De los 32 bits que componen un D3DColor (o de los
    cuatro números decimales entre 0 y 1 que existen
    en un D3DColorValue) hasta ahora solo hemos usado
    los 24 últimos (o los campos r, g y b) que
    definen las componentes roja, verde y azul del
    mismo.
  • Los 8 primeros bits de un D3DColor (o el campo a
    de al estructura D3DColorValue) indican la
    componente ALPHA, que se utiliza para conseguir
    efectos de transparencia. 255 (o 1.0) significa
    que el pixel es completamente opaco mientras que
    0 implicaría que es invisible.

3
Blending
  • El blending, que se efectúa durante la fase de
    rasterización, se produce (está deshabilitado a
    menos que se indique lo contrario) cuando se
    trata de escribir un pixel en una posición en la
    que ya se ha dibujado otro anteriormente y
    consiste en calcular el color del píxel
    resultante a partir del valor de ambos.
  • Para habilitar el Blending se utiliza el metodo
    IDirect3DDevice9SetRenderState(D3DRS_ALPHABLENDE
    NABLE,TRUE)
  • Como el blending es una operación costosa, sólo
    habría que habilitarlo mientras dibujamos los
    objetos que queremos sean transparentes. Por lo
    tanto, es conveniente agrupar dichos objetos para
    no estar constantemente cambiando el estado del
    blending. También es importante dibujar primero
    aquellos objetos que se encuentran a mayor
    profundidad

4
D3DBLEND
  • La formula para calcular el color del píxel
    resultante es srcColorsrcBlending
    destColordestBlending
  • srcColor es el color del píxel que queremos
    dibujar
  • srcBlending se fija usando IDirect3DDevice9SetRe
    nderState(D3DRS_SRCBLEND,value), value es una
    constante del tipo D3DBLEND
  • destColor es el color del píxel ya dibujado
  • destBlending se fija usando IDirect3DDevice9SetR
    enderState(D3DRS_DESTBLEND,value), value es una
    constante del tipo D3DBLEND
  • Los valores mas relevantes del tipo D3DBLEND son
  • D3DBLEND_ZERO No usar ese color
  • D3DBLEND_ONE No variar la cantidad de ese color
  • D3DBLEND_SRCCOLOR Utilizar el color del píxel
    origen
  • D3DBLEND_DESTCOLOR Utilizar el color del píxel
    destino
  • D3DBLEND_SRCALPHA Utilizar la componente alpha
    del píxel origen
  • D3DBLEND_INVSRCALPHA Utilizar la inversa de la
    componente alpha (1-a) del píxel origen
  • Por defecto, SRCBLEND es igual a SRC_ALPHA y
    DESTBLEND es igual a INVSRCALPHA, lo que
    significa que en función de la componente alpha
    del objeto que estamos dibujando este será más o
    menos transparente. Si ALPHA es 1 el color que
    aportara el píxel destino será 0. Por el
    contrario si es 0, solo se vera el píxel destino

5
Alpha Channel
  • La componente alpha se puede coger bien de la
    componente alpha del color difuso resultado de la
    interpolación del color de los vértices o bien de
    la componente alpha del texel de la textura.
  • Si la textura activa tiene un Alpha channel, esto
    es, un conjunto de bits extra con información de
    transparencia, entonces la componente alpha para
    el calculo del blending se coge automáticamente
    de éste. Si no, se coge la del vértice.
  • Este comportamiento por defecto se puede
    modificar usando el método IDirect3DDevice9SetTe
    xtureStageState( DWORD Stage, D3DTEXTURESTAGESTATE
    TYPE tipo, DWORD valor)
  • Stage es el id de la textura. En tipo
    especificamos D3DTSS_ALPHAARG1 y en valor usamos
    una de las constantes D3DTA
  • D3DTA_DIFFUSE. Coge el valor alpha del vértice
  • D3DTA_TEXTURA. Coge el valor alpha de la textura
  • También podemos determinar si el valor del alpha
    se coge del establecido en ALPHAARG1 o es una
    combinación de este con otro valor usando como
    tipo D3DTSS_ALPHAOP y como valor una de las
    constantes D3DTEXTUREOP
  • D3DTOP_SELECTARG1. Coge el valor alpha fijado
    para ALPHAARG1
  • D3DTOP_SELECTARG2. Coge el valor alpha fijado
    para ALPHAARG2
  • D3DTOP_MODULATE. El valor alpha es igual a
    ALPHAARG1ALPHAARG2

6
Ejercicio
  • Dibujar una malla delante de una pared y cambiar
    la transparencia de la misma haciendo uso del
    teclado

7
Stencil Buffer
  • El Zbuffer se compone de tantas entradas como
    pixels en pantalla. Cada entrada tiene 32 bits
    para almacenar la profundidad. Un pixel se dibuja
    solo si su valor Z es menor que el almacenado en
    el Z-buffer.
  • Como 24 bits es suficiente para almacenar la
    profundidad, se pueden utilizar 8 de estos 32
    bits para efectuar el stencil, o bloqueo del
    dibujado de ciertos pixels. Esta tecnica se
    utiliza para reflejar objetos en espejo o pare
    evitar el efecto de double blending al
    proyectar sombras
  • El stencil buffer se configura al crear el device
    usando los campos EnableAutoDepthStencil (TRUE) y
    AutoDepthStencilFormat (cuyo valor es dependiente
    del hardware, por lo que hay leerlo del
    D3D9CAPS) de la estructura D3DPRESENT_PARAMETERS
  • Para crear el StencilBuffer usando
    CD3DApplication hay que especificar en el
    constructor de la clase hija lo siguiente
  • m_d3dEnumeration.AppUsesDepthBuffer TRUE
  • m_d3dEnumeration.AppMinStencilBits 8
  • Para habilitar el Stencil (que al igual que el
    Blending es costoso y debe hacerse unicamente
    cuando es necesario) utilizamos
    IDirect3DDevice9SetRenderState(D3DRS_STENCILENAB
    LE, true)

8
Función Stencil
  • El Stencil consiste en un test que, caso de ser
    satisfecho, escribe el píxel en pantalla.
  • El test se satisface si referenciamascara
    operación valormascara devuelve true.
  • El valor de referencia se fija con el método
    IDirect3DDevice9SetRenderState(D3DRS_STENCILREF,
    entero)
  • La mascara se fija con el metodo
    IDirect3DDevice9SetRenderState(D3DRS_STENCILMASK
    ,entero)
  • Valor es el valor del pixel en el Stencil buffer
  • Operación se fija con el metodo
    IDirect3DDevice9SetRenderState(D3DRS_STENCILFUNC
    ,op) donde op es una constante del tipo
    D3DCMPFUNC
  • D3DCMP_EQUAL El test devuelve true si
    referenciamascara es igual a valormascara
  • D3DCMP_ALLWAYS El test siempre devuelve true (lo
    usamos cuando queremos rellenar el buffer)
  • Además, podemos indicar que debe hacerse con el
    valor tanto en el Z como en el stencil buffer
    tras ejecutar el test, con los métodos
    IDirect3DDevice9SetRenderState(D3DRS_STENCILFAIL
    ,valor), IDirect3DDevice9SetRenderState(D3DRS_ST
    ENCILZFAIL,valor), IDirect3DDevice9SetRenderStat
    e(D3DRS_STENCILPASS,valor) donde valor es una
    constante del tipo D3DSTENCILOP
  • D3DSTENCILOP_KEEP Mantiene el valor actual
  • D3DSTENCILOP_ZERO Fija el valor a 0
  • D3DSTENCILOP_REPLACE. Reemplaza el valor actual
    por el de referencia
  • D3DSTENCILOP_INCR. Incrementa el valor actual en
    una unidad
  • Antes de actualizar el valor en el buffer se
    aplica la mascara definida con el método
    IDirect3DDevice9SetRenderState(D3DRS_STENCILWRIT
    EMASK,valor)

9
Reflejar un objeto
  • Reflejar un objeto es equivalente a multiplicarlo
    por su matriz de reflexión sobre un plano
    determinado
  • Un plano se describe en Direct3D con la
    estructura D3DXPLANE FLOAT a FLOAT b FLOAT c
    FLOAT d donde a, b, c y d son los coeficientes
    de la ecuación ax by cz dw 0
  • La matriz de reflexión se obtiene con la funcion
    D3DXMatrixReflect( D3DXMATRIX pOut, D3DXPLANE
    plano)

10
Dibujar sobre un espejo
  • Poner a cero el Stencil Buffer (añadiendo la
    constante D3DCLEAR_STENCIL en el método
    IDirect3DDevice9Clear())
  • Dibujar la escena normalmente, excepto la
    reflexión en el espejo
  • Dibujar el espejo actualizando únicamente el
    stencil buffer, deshabilitando la escritura en el
    Z-buffer y en pantalla (configurando debidamente
    el blending) Esto se hace con los valores
    STENCILFUNCD3DCMP_ALWAYS, STENCILPASSD3DSTENCILO
    P_REPLACE, STENCILREF0x1, D3DRS_SRCBLENDD3DBLEND
    _ZERO, D3DRS_DESTBLENDD3DBLEND_ONE y
    D3DRS_ZWRITEENABLEfalse).
  • Dibujar la malla reflejada. Para ello fijamos
    STENCILFUNCD3DCMP_EQUALS, D3DRS_STENCILPASSD3DST
    ENCILOP_KEEP, de forma que solo pasan el stencil
    test los píxeles de la malla reflejada que están
    dentro del área ocupada por el espejo (cuyo
    stencil buffer vale 1 tras la ejecución del paso
    anterior). Para el blending de la malla con el
    espejo (evitando la sensación de que la reflexión
    de la taza esta SOBRE el espejo y no EN el
    espejo) ponemos D3DRS_SRCBLEND
    D3DBLEND_DESTCOLOR y D3DRS_DESTBLEND
    D3DBLEND_ZERO, de manera que se multiplica el
    color de la malla por el del espejo
  • Como la malla reflejada es más profunda que el
    espejo, es necesario deshabilitar el Z-Buffer
    antes de dibujarla. También hace falta cambiar el
    sentido habitual del backface_culling, puesto que
    ahora queremos quitar las caras opuestas, al
    haber reflejado la malla.

11
Sombreado
  • Para calcular la sombra que proyecta una luz
    sobre una superficie plana, Direct3D nos
    proporciona la función D3DXMatrixShadow(
    D3DXMATRIX pOut, CONST D3DXVECTOR4 pLight,
    CONST D3DXPLANE pPlane ) donde pLight
    representa bien la dirección (coordenada w0),
    bien la posición (w1) de la luz y pPlane es el
    plano sobre el que queremos proyectar la sombra.
  • Para dibujar la sombra de un objeto, una vez que
    tenemos la matriz de sombreado, dibujamos de
    nuevo el objeto original (usando color negro 50
    transparente) con dicha matriz fijada como matriz
    de mundo.
  • Las sombras sobre superficies planas son un atajo
    computacional para dotar de mayor realismo a la
    escena. En los juegos actuales se utilizan
    sombras volumétricas, más costosas de calcular,
    pero también más realistas.
  • La matriz de sombreado es

12
Double Blending
  • Cuando se aplana la sombra, puede suceder que dos
    triángulos coincidan, sumándose la intensidad del
    color negro en dichos píxeles, alterando la
    densidad de la sombra. Para evitar este efecto de
    double blending se utiliza el stencil buffer,
    configurándolo para evitar que una vez dibujado
    un píxel en dicha posición, puede volver a
    pintarse otro encima
  • Esto se consigue fijando el STENCILPASS a
    D3DSTENCILOP_INCR, el STENCILREF a 0 y el
    STENCILFUNC a D3DCMP_EQUAL. De manera que el test
    de Stencil solo da true cuando el valor en el
    buffer es 0. O sea, la primera vez, porque la
    segunda ya valdrá uno al haberse incrementado
    tras el primer test satisfactorio.
  • Al dibujar la sombra en el suelo, para evitar el
    llamado z-fighting, que es un efecto visual que
    se produce cuando dos superficies tienen la misma
    profundidad y Direct3D no sabe cual esta más
    cercana, deshabilitamos el Z-Buffer, con el
    metodo IDirect3DDevice9SetRenderState(D3DRS_ZENA
    BLE,false)

13
Ejercicio
  • Dibujar una escena donde reflejemos una malla
    sobre un espejo colgado en la pared y proyectemos
    su sombra sobre el suelo.
Write a Comment
User Comments (0)
About PowerShow.com