9 de junio de 2008

Revisiting cosas antiguas

Hasta el momento siempre que he querido hacer motion blur he seguido la misma técnica: guardarme dos matrices ViewProjection (la actual y la del frame anterior), generar un vector de velocidad 2D en el vertex shader y pasarlo al pixel shader para sacar estas velocidades en una textura y así usarlas en un paso posterior para "blurrear" el frame.

Por norma general esto funciona de lujo y es my sencillo de implementar, pero tiene un gran fallo. Como se calculan las velocidades por vértice, puede ocurrir que algún vértice de un polígono quede fuera del frustum y otros dentro, y entonces al hacer clipping se le va completamente la olla ocurriendo cosas como esta:


Efectivamente, esto no mola un carajo. ¿Cómo solucionarlo? La idea es calcular la velocidad por píxel. Es mucho más costoso pero abordable hoy en día. En principio se puede reconstruir la posición en world space de un punto en el pixel shader sabiendo su profundidad. Basta con multiplicar el punto en cuestión en screen space con sus coordenadas de la forma (x, y, depth, 1.0) por la matriz ViewProjection inversa y dividirlo después por la componente w que le queda después de esta multiplicación. De esta manera se consigue otra vez su posición en el mundo 3D. Para conseguir el vector de velocidad buscado sólo queda multiplicar este punto reconstruido por la matriz ViewProjection del frame anterior y ver la diferencia con el actual.

Ahora es cuando debería enseñar la foto molona de cómo queda siguiendo este nuevo método, pero no la tengo. No sé porqué todavía no he conseguido que funcione, y no veo que esté haciendo nada mal. Estoy un poco cansado así que lo dejaré por hoy, pero ahora voy a estar pensando en ello hasta que pueda volver a ponerme. Qué rabia.

No hay comentarios: