Sombras y Reflejos en Tiempo Real - PowerPoint PPT Presentation

1 / 31
About This Presentation
Title:

Sombras y Reflejos en Tiempo Real

Description:

Sombras y Reflejos en Tiempo Real Implementaci n mediante OpenGL Uso del stencil buffer Introducci n Renderizar pol gonos con texturas Z-Buffer mostrar la salida ... – PowerPoint PPT presentation

Number of Views:60
Avg rating:3.0/5.0
Slides: 32
Provided by: UNIVILLE3
Category:

less

Transcript and Presenter's Notes

Title: Sombras y Reflejos en Tiempo Real


1
Sombras y Reflejosen Tiempo Real
  • Implementación mediante OpenGL
  • Uso del stencil buffer

2
Introducción
  • Renderizar polígonos con texturasZ-Buffer
    mostrará la salida correcta
  • La limitación de los efectos viene dada por el
    hardware
  • Dos efectos que mejoran la calidad gráfica son
    las sombras y los reflejos

3
Stencil Test
  • Mejoran la calidad de las sombras y reflejos
  • Stenciling es un test extra por pixel y un
    conjunto de operaciones muy parecidas al z-buffer
  • Añade planos de bits adicionales para cada pixel,
    ademas de los bits de color y profundidad

4
Stencil Test II
  • Es una manera de marcar pixeles en una
    renderización para controlar su actualización en
    renderizaciones siguientes
  • Algunas tarjetas gráficas como RivaTNT soporta
    stencil buffer de 8-bits
  • Tanto DirectX y OpenGL soportan Stencil Buffer

5
Secuencia de operaciones
6
Per-pixel Stencil Testing
  • Inicialización mediante GLUT OpenGL
  • glutInitDisplayString(stencilgt1 rgb depth
    double)
  • glutCreateWindow(Stencil Buffer Example)
  • El valor stencil de un pixel es un entero sin
    signo (unsigned int)

7
Per-pixel Stencil Testing II
  • Como borrar el stencil buffer
  • glClearStencil(0)
  • glClear(GL_COLOR_BUFFER_BIT GL_DEPTH_BUFFER_BIT
    GL_STENCIL_BUFFER_BIT)
  • Activar y desactivar el test
  • glEnable(GL_STENCIL_TEST)
  • glDisable(GL_STENCIL_TEST)

8
Per-pixel Stencil Testing III
  • El stencil test compara el valor del pixel del
    stencil buffer con un valor de referencia
  • Permite las siguientes comparaciones never,
    always less than, less than or equal greater
    than, greater than or equal equal, not equal

9
Per-pixel Stencil Testing IV
  • Es más potente que el buffer de profundidad,
    antes de comparar realiza una operación AND,
    tanto del valor de referencia como del valor del
    buffer, con un valor que sirve como máscara
  • glStencilFunc( GL_EQUAL, // función de
    comparación 0x1, // valor de
    referencia 0xff) // máscara

10
Per-pixel Stencil Testing V
  • Si el pixel no pasa el test de profundidad es
    rechazado, en cambio si pasa reemplaza el valor
    del z-buffer. El stencil test es más complicado
  • NO pasa el stencil test
  • Pasa stencil test y NO el test de profundidad
  • Pasa stencil test y el test de profundidad

11
Per-pixel Stencil Testing V
  • Para cada caso tenemos seis operaciones posibles
  • GL_KEEP, GL_REPLACE, GL_INVERT,
  • GL_INCREMENT, GL_DECREMENT, GL_ZERO
  • Antes de escribir se aplica una máscara
  • glStencilOp( GL_KEEP, // stencil
    fail GL_DECR, // stencil pass, depth
    fail GL_INCR) // stencil pass, depth pass
  • glStencilMask(0xff)

12
Per-pixel Stencil Testing VI
  • State Description Initial Value State
    Update State Query Token Command
  • Stencilling enable GL_FALSE glEnable GL_STENCIL_TE
    ST glDisable
  • Stencil function GL_ALWAYS glStencilFunc GL_STENCI
    L_FUNC
  • Stencil compare mask All 1s glStencilFunc GL_STEN
    CIL_VALUE_MASK
  • Stencil reference value 0 glStencilFunc GL_STENCIL
    _REF
  • Stencil fail operation GL_KEEP glStencilOp GL_STEN
    CIL_FAIL
  • Stencil depth fail operation GL_KEEP glStencilOp G
    L_STENCIL_PASS_DEPTH_PASS
  • Stencil depth pass operation GL_KEEP glStencilOp G
    L_STENCIL_PASS_DEPTH_PASS
  • Stencil write mask All 1s glStencilMask GL_STENCI
    L_WRITEMASK
  • Stencil buffer clear value 0 glClearStencil GL_STE
    NCIL_CLEAR_VALUE

13
Reflejos Planos sin Stencil
  • Tiene una serie de limitaciones
  • El objeto reflejado sale por fuera de la
    superficie reflectante
  • Desde detrás del espejo se ve el objeto reflejado
  • No permite reflejos infinitos, esta limitado a un
    número n de reflejos

14
Algoritmo
  • 1. Cargar la matriz de modelización glMatrixMode(
    GL_MODELVIEW) glLoadIdentity() glLookAt(eye0
    , eye1, eye2, center0, center1,
    center2, up0, up1, up2)
  • 2. Introducir en la pila la matriz de
    modelización glPushMatrix()
  • 3. Aplicar la matriz de reflejo (plano z
    0) glScalef(1.0, 1.0, -1.0)
  • 4. Si usamos recorte de caras traseras, debemos
    realizar el contrario, eliminación de caras
    delanteras glCullFace(GL_FRONT)
  • 5. Renderizar la escena, pero solo los objetos
    que estan en el lado reflectante del espejo

15
Algoritmo (continuación)
  • 6. Restaurar los valores antes del
    espejo glCullFace(GL_BACK) glPopMatrix()
  • 7. Renderizar el espejo (por ejemplo si es
    marmol) glEnable(GL_BLEND) glBlendFunc(GL_ONE,
    GL_ONE) // aditivo rederizarEspejoConTextura()
    glDisble(GL_BLEND)
  • Incluso si el espejo no esta renderizado como
    una superficie semitransparente es importante
    renderizarlo para actualizar el z-buffer y evitar
    que aparezcan objetos que estan detrás del
    objeto glColorMask(0, 0, 0, 0) renderizarEspejo
    ConPoligonos() glColorMask(1, 1, 1, 1)
  • 8. Finalmente renderizar la escena no reflejada

16
Resultados
Stenciling
17
Reflejos Planos con Stencil
  • Técnica más perfeccionada
  • Permite tener espejos de tamaño limitado
  • Podemos situar la cámara al otro lado del espejo

18
Algoritmo
  • Renderizar la escena, excepto los espejos, con
    z-buffer pero sin stencil test glClearStencil(0)
    glClear(GL_COLOR_BUFFER_BIT
    GL_DEPTH_BUFFER_BIT GL_STENCIL_BUFFER_BIT)
    glEnable(GL_DEPTH_TEST) glDisable(GL_STENCIL_TES
    T) DrawScene()
  • Para cada espejo realizar los siguientes pasos
  • 1. Configurar para que escriba 1 en el stencil
    buffer cuando pasa el buffer de profundidad,
    deshabilitar escribir en el buffer de color.
    Entonces renderizar el espejo glEnable(GL_STENCIL
    _TEST) glStencilOp(GL_KEEP, GL_KEEP,
    GL_REPLACE) glStencilFunc(GL_ALWAYS, 1,
    0) glColorMask(0, 0, 0, 0) RenderizarPoligono
    Espejo()

19
Algoritmo (continuación)
  • 2. Con el buffer de color deshabilitado poner en
    el z-buffer el valor de profundidad máxima para
    los pixeles que corresponden al
    espejo glDepthRange(1, 1) glDepthFunv(GL_ALWAY
    S) glStencilFunc(GL_EQUAL, 1,
    0) glStencilOp(GL_KEEP, GL_KEEP,
    GL_KEEP) RenderizarPoligonoEspejo()
  • 3. Restaurar el test de profundidad, la mascara
    de color y el rango de profundidad a los valores
    estándar glDepthFunc(GL_LESS) glColorMask(1,
    1, 1, 1) glDepthRange(0, 1)
  • Ahora tenemos marcados como 1 en el stencil
    buffer los pixeles que corresponden al espejo y
    con la máxima profundidad en el z-buffer

20
Algoritmo (continuación)
  • 4. Para evitar renderizar polígonos ubicados
    detrás del espejo definiremos un plano de
    clipping GLfloat matrix44 GLdouble
    clipPlane4 glPushMatrix() CalcularPlanoCort
    eEspejo(clipPlane) glClipPlane(GL_CLIP_PLANE0,
    clipPlane) CalcularMatrizEspejo(matrix00)
    glMultMatrix(matrix00) glCullFace(GL_FR
    ONT) DrawScene() DibujarOtrosEspejosComoSupe
    rficiesGrises() glCullFace(GL_BACK) glDisabl
    e(GL_CLIP_PLANE0) glPopMatrix()
  • Ahora esta correctamente rederizado el reflejo
    del espejo

21
Algoritmo (continuación)
  • 5. Ahora reseteamos el valor del stencil buffer a
    0 para que no se confundan con otros espejos,
    ademas actualizamos el z-buffer para que tenga
    como profundidad la del espejo y no la del objeto
    reflejado glColorMask(0, 0, 0,
    0) glStencilop(GL_KEEP, GL_KEEP,
    GL_ZERO) glDepthFunc(GL_ALWAYS) RenderizarPoli
    gonoEspejo() glDepthFunc(GL_LESS) glColorMask(
    1, 1, 1, 1)

22
Sombras Planas sin Stencil
  • Los modelos de iluminación locales soportados por
    OpenGL y Direct3D no provocan sombras
  • Proyectando un polígono sombre el plano a
    sombrear es una técnica para provocar el efecto
    sombra

23
Algoritmo
  • 1. Cargar la matriz de modelización glMatrixMode(
    GL_MODELVIEW) glLoadIdentity() glLookAt(eye0
    , eye1, eye2, center0, center1,
    center2, up0, up1, up2)
  • 2. Dada la luz y la ecuación del plano donde se
    proyecta, y asumiendo que el objeto esta entre la
    luz y el plano, habilitar la luz y renderizar el
    objeto y el plano GLfloat lightPosition4
    LX, LY, LZ, 1.0 GLfloat groundPlaneEquation4
    A, B, C, D glLightfv(GL_LIGHT0,
    GL_POSITION, lightPosition) glEnable(GL_LIGHT0)
    glEnable(GL_LIGHTING) DibujarObjeto() Dibuja
    rPlano()

24
Algoritmo (continuación)
  • 3. Meter en la pila la matriz de
    modelización glPushMatrix()
  • 4. Construir la matriz de proyección, multiplicar
    la matriz de modelización por la matriz de
    proyección de la sombra GLfloat
    matrix44 ShadowMatrix(matrix00,
    lightPosition, groundPlaneEquation) glMultMa
    trix(matrix00)
  • 5. A menos que lo remediemos la sombra y el plano
    donde se proyecta son coplanares. Esto causa
    problemas en el Z-Buffer, a veces la sombra esta
    más cerca, a veces igual y otras veces más
    alejado, esto es debido a imprecisiones en el
    cálculo numérico glEnable(GL_POLYGON_OFFSET_FILL)
    glPolygonOffset(1.0, 2.0)Esto provoca que
    este dos unidades más cerca

25
Algoritmo (continuación)
  • 6. Deshabilitar la iluminación, poner el color
    gris oscuro y dibujar el objeto de
    nuevo glDisable(GL_LIGHTING) glColor3f(0.25,
    0.25, 0.25) DibujarObjeto()
  • 7. Volver al estado anterior glDisable(GL_POLYGON
    _OFFSET) glPopMatrix()

26
Resultados
Polygon Offset
Stenciling
27
Sombras Planas con Stencil
  • Evita problema de doble transparencia
  • Impide que la sombra salga del polígono sobre el
    cual se quiere calcular la sombra

28
Algoritmo
  • 1. Cargar la matriz de modelización glMatrixMode(
    GL_MODELVIEW) glLoadIdentity() glLookAt(eye0
    , eye1, eye2, center0, center1,
    center2, up0, up1, up2)
  • 2. Dada la luz y la ecuación del plano donde se
    proyecta, y asumiendo que el objeto esta entre la
    luz y el plano, habilitar la luz y renderizar el
    objeto y el plano GLfloat lightPosition4
    LX, LY, LZ, 1.0 GLfloat groundPlaneEquation4
    A, B, C, D glLightfv(GL_LIGHT0,
    GL_POSITION, lightPosition) glEnable(GL_LIGHT0)
    glEnable(GL_LIGHTING) DibujarObjeto() Dibuja
    rPlano()

29
Algoritmo (continuación)
  • 3. Meter en la pila la matriz de
    modelización glPushMatrix()
  • 4. Construir la matriz de proyección, multiplicar
    la matriz de modelización por la matriz de
    proyección de la sombra GLfloat
    matrix44 ShadowMatrix(matrix00,
    lightPosition, groundPlaneEquation) glMultMa
    trix(matrix00)
  • 5. Asignar un valor distinto de cero al stencil
    buffer glEnable(GL_STENCIL_BUFFER) glStencilFun
    c(GL_ALWAYS, valor, 0) glStencilOp(GL_KEEP,
    GL_KEEP, GL_REPLACE) DibujarPlanoASombrear() g
    lDisable(GL_STENCIL_TEST)

30
Algoritmo (continuación)
  • 6. Deshabilitar la iluminación glDisable(GL_LIGHT
    ING) glEnable(GL_BLEND) glBlendFunc(GL_DST_COL
    OR, GL_ZERO) glColor3f(0.5, 0.5,
    0.5) glDisable(GL_DEPTH_TEST)Solo debemos
    actualizar los pixeles marcados con
    valor glEnable(GL_STENCIL_TEST) glStencilFunc(G
    L_EQUAL, valor, 0) glStencilOp(GL_KEEP,
    GL_KEEP, GL_ZERO) DibujarObjeto()
  • 7. Restaurar los valores glDisable(GL_BLEND) gl
    Disable(GL_STENCIL_TEST) glEnable(GL_DEPTH_TEST)
    glPopMatrix()

31
Programa Demo
  • Dinoshade
Write a Comment
User Comments (0)
About PowerShow.com