Frustum Culling

Sabemos que es muy conveniente evitar procesar vértices que finalmente serán recortados en la última etapa del pipeline. Para esto existen muchas técnicas y en ciertas ocasiones estas técnicas se combinan. En este documento veremos una de ellas llamada “frustum culling” que puede ser combinada, por ejemplo, con árboles bsp, quadtrees, octrees o incluso ser utilizada de modo independiente.

El frustum es básicamente el volumen de visualización generado a partir de una matriz de proyección en perspectiva; la forma de este volumen es el de una pirámide con la punta recortada. El frustum se encuentra delimitado por 6 planos: Plano de recorte lejano, plano de recorte cercano, plano superior, plano inferior, plano izquierda y plano derecho.

frustum fig1

Figura 1. El frustum visto de arriba

Estos planos son especificados al momento de especificar la matriz de proyección, recordemos como lo hacíamos:

D3DXMatrixPerspectiveFovLH(&matrix, D3DX_PI/4.0f, fAspectRatio, 1.0f, 1000.0f);

El primer parámetro de la función retorna la matriz creada, el segundo parámetro especifica el campo de visualización (field of view, fov) que el ángulo formado entre el plano izquierdo/derecho y superior/inferior; el tercer parámetro especifica la relación de aspecto, el cuarto especifica el plano de recorte cercano y, finalmente, el quinto especifica el plano de recorte lejano.

La idea básica del frustum culling será aplicar un pequeño algoritmo para verificar si un determinado objeto se encuentra dentro o fuera del frustum y de este modo saber si debemos dibujarlo o no.

frustum fig2

Figura 2. Las distintas situaciones con las cuales nos podemos encontrar

En la figura 2 se especifican todos los casos que podremos encontrar cuando realicemos el frustum culling: En el caso A, B y C los objetos se encuentran totalmente fuera del frustum por lo tanto no serán vistos por el jugador y por lo tanto no deberemos procesar ninguno de sus vértices; en el caso D el objeto se encuentra totalmente dentro del frustum y naturalmente debe ser dibujado; en el caso E el objeto se encuentra parte dentro y parte fuera del frustum, en estos casos usualmente se dibuja el objeto completo (si es que el mismo no posee una estructura de bounding boxes de mayor detalle para practicar nuevamente el frustum culling).

Como habíamos mencionado anteriormente, el frustum se encuentra definido por 6 planos, para verificar si un objeto se encuentra dentro de él deberemos aplicar un algoritmo que tenga en cuenta estos planos. El objeto contra el cual se realiza la verificación es, usualmente, una esfera o una bounding box debido a que con esto simplificaremos mucho las cuentas.

frustum fig3

Figura 3. Bounding Sphere y Bounding Box

Esfera vs. Frustum

La primer verificación que haremos será la más sencilla y más “económica” para nuestro motor. Verificar si una esfera se encuentra dentro o fuera de un frustum, veamos:


|Frustum::EFrustumCol Frustum::SphereIn(Vector3 &v3Center, float fRadius)
|{
| float fDistance;
|
| // Calculamos la distancia a cada uno de los planos
| // Debug: Sólo chequeo plano izquierdo
| for(int i=0; i<6; i++)
| {
| const Vector3 * pNormal = m_plane[0].GetNormal();
|
| // Buscamos la distancia de la esfera al plano
| fDistance = m_plane[i].GetPointDistance(v3Center);
|
| // Si la distancia es < -sphere.radius, entonces estamos fuera
| // del frustum
| if (fDistance < -fRadius)
| return out; // out
|
| // Si la distancia está entre +- el radio, entonces interseca
| if (fabs(fDistance) < fRadius)
| return intersect; // intersect
| }
|
| // De otro modo, estamos dentro
| return in; // in
| }

La idea es tomar el centro y el radio de la esfera y comenzar a testearla contra cada uno de los planos de nuestro frustum.

frustum fig4

Figura 4. Los distintos casos de la evaluación de una esfera contra un plano

En el caso de estar detrás de uno de los planos del frustum ya podremos concluir que la esfera está totalmente fuera del frustum ¡el mejor caso!; si la distancia está entre +/- el radio entonces la esfera se encuentra parte dentro y parte fuera del frustum, también en dicho caso podremos dejar de realizar la verificación contra los otros planos. Por último si la esfera se encuentra delante de un plano del frustum no podremos extraer conclusiones y deberemos seguir realizando testeos contra los otros planos.

Pages: 1 2 3 4 5

Comments

  1. May 1st, 2007 | 5:39

    En el algortimo del test del bbox hay un fallo:
    –iInCount; debería ser -–iInCount;

    Muy buen tutorial, me ha gustado especialmente la parte en la que extraes los planos del frustrum de la matriz, nunca había visto la demostración matemática.

Leave a reply