Occlusion Culling (II de IV)

************************************************************************************************

Back-face culling

Frustum Culling

Occlusion Culling

Optimizaciones para el Occlusion Culling

************************************************************************************************

Frustum Culling: Es otra de las técnicas de visibilidad más usadas ya que es muy simple de implementar, consiste en no enviar a la tarjeta gráfica aquellos objetos que queden fuera del volumen de render de la cámara llamado Frustum.ViewingFrustum

Como podemos ver en la imagen de arriba, se le llama frustum al trozo de pirámide encerrado entre dos planos, near plane y far plane. Todo lo que está dentro de este volumen será dibujado por la tarjeta gráfica, y todo lo que quede fuera será descartado. La mejora de rendimiento que obtendremos con esta técnica esta en no esperar a que la tarjeta gráfica descarte los objetos que estén fuera del frustum perdiendo un tiempo valioso en transferir la información de estos objetos a la GPU, sino detectarlo en CPU.

El frustum de la cámara queda determinado por las matrices de view y projection de una cámara, es muy importante para el futuro rendimiento de nuestro juego que el frustum de la cámara tenga el tamaño optimo. Es decir, el near plane tiene que estar cerca de la cámara y el far plane tiene que estar a una distancia optima, si el far plane se coloca demasiado lejos estaremos dibujando más de lo necesario y si lo situamos demasiado cerca nuestros jugadores verán como van apareciendo polígonos en el horizonte. Antiguamente esto era un serio problema ya que no tenían las GPU de hoy en día entonces siempre si intentaba afinar mucho con el far plane, para evitar que los jugadores viesen como se iba generando el escenario por ejemplo en juegos de rally, el circuito estaba lleno de curvas que impedían ver más allá de la siguiente curva, en otros juegos utilizaban el fog para disimular esto.

Bueno una vez que tenemos el frustum solo nos queda calcular la intersección entre los objetos del escenario con dicho volumen.

view.frustum.culling

 

Pero para hacer más eficiente el test no se realiza una comprobación a nivel de polígono, sino que envolvemos cada uno de nuestros modelos en BoundingBox o BoundingSphere y realizamos el test con estos volumenes simplificados.

220px-BoundingBox

Por lo que a mayor poligonación de los elementos de nuestro juego mayor será la optimización realizada, para que esta técnica nos dé un buen resultado los elementos de nuestro juego de ven ser de un tamaño mediano. Por lo que si tenemos algún elementos muy grande lo partiremos en trozos y a cada trozo le asignaremos un BoundingBox o BoundingSphere.

El código en XNA podría ser algo así:

Matrix view = Matrix.CreateLookAt(new Vector3(0, 0, -10), Vector3.Zero, Vector3.Up);

float aspectRatio = (float)graphics.PreferredBackBufferWidth / graphics.PreferredBackBufferHeight;

Matrix projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, aspectRatio, 1, 1000);

 

BoundingFrustum frustum = new BoundingFrustum(view * projection);

 

foreach (Model model in models)

{

    foreach (ModelMesh mesh in model.Meshes)

    {

        if (frustum.Contains(mesh.BoundingSphere) != ContainmentType.Disjoint)

        {

            //Draw

        }

    }

}      

Podemos mejorar el rendimiento de esta técnica utilizando estructuras de subdivisión de espacio como  QuadTree, OcTree ó KdTree, ya que sino el 90% del test estaremos comprobando intersecciones entre objetos que no serán dibujados.

Octree2

 

Esta mejora consiste en hacer agrupaciones jerárquicas de los elementos de la escena, de manera primero haremos comprobaciones de los boundingbox que representan a conjuntos de objetos, si descartamos alguno nos habremos ahorrado calcular la intersección de todos los elementos que contiene.

Aquí os dejo un pequeño video que muestra el resultado de esta técnica y como podemos optimizarla realizando agrupaciones jerárquicas:

Publicado por

jcanton

Javier is a Computer Science Engineer who has always had a passion for 3D graphics and software architecture. He learned C# almost at the same time as he learned to talk, and his first word was "base". He enjoys imparting talks about technology and has contributed in many important software and video game events. He has participated in multitude of software projects involving multitouch technologies, innovative user interfaces, augmented reality, and video games. Some of these projects were developed for companies such as Microsoft, Syderis, and nVidia. His professional achievements include being MVP for Windows DirectX and DirectX XNA for the last eight years, Xbox Ambassador, as well as Microsoft Student Partner and Microsoft Most Valuable Student during his years at college. Currently he works at Plainconcepts and he is the development team lead at WaveEngine project.

Un comentario en “Occlusion Culling (II de IV)”

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *