generación procedural de terrenos en la gpu david haro gásquez programación avanzada sobre...
TRANSCRIPT
Generación Procedural de Terrenos en la GPU
David Haro GásquezProgramación Avanzada sobre Tarjetas Gráficas
David Haro Gásquez (2015)
Introducción
• La generación procedural de terrenos:• Obtener un modelo
realista 3D a partir de algoritmos• Obtención de vértices,
normales, coordenadas de texturas, etc.
David Haro Gásquez (2015)
Estado del Arte: Mapas de alturas
Se almacena en una textura un valor de altura.Se desplazan los vértices de un plano con los valores de la textura
David Haro Gásquez (2015)
Estado del Arte: Fractales
• Los fractales son objetos cuya estructura se repite a diferentes escalas• Autosimilitud
• Son muy repetitivas.
David Haro Gásquez (2015)
Estado del Arte: Densidad y Marching Cubes
David Haro Gásquez (2015)
Generating Complex Procedural Terrains Using the GPU
• Permite generar terrenos complejos en tiempo real.
• Aprovecha el alto grado de paralelización de las GPUs actuales y los Shaders de Geometría.
• Define métodos para calcular la geometría, la iluminación y las texturas de manera procedural.
Ryan Geiss – NVIDIA Corporation
David Haro Gásquez (2015)
Marching Cubes
• Se divide el espacio en voxels.• Se calcula la densidad en cada uno
de los 8 vértices del cubo.• Se escoge un umbral que divide los
puntos que están dentro y los que están fuera y concatenan bit a bit
David Haro Gásquez (2015)
Marching Cubes
• Los vértices 0, 6 y 7 están dentro del terreno
David Haro Gásquez (2015)
Marching Cubes
• Lookup tables: el resultado se utiliza para acceder a una tabla que indica el número de polígonos que se deben generar para ese voxel
• En una segunda tabla se indican los índices de los bordes que deben conectarse para generar los triángulos
int case_to_numpolys[256]; int3 edge_connect_list[256][5];
int3 edge_connect_list[193][0]: 11 5 10 int3 edge_connect_list[193][1]: 11 7 5 int3 edge_connect_list[193][2]: 8 3 0 int3 edge_connect_list[193][3]: -1 -1 -1 int3 edge_connect_list[193][4]: -1 -1 -1
David Haro Gásquez (2015)
La función de densidad
• La función de densidad es la parte esencial de este método. Se trata de generar una función que genere un resultado realista.
float density = -ws.y; density += snoise(ws);
David Haro Gásquez (2015)
La función de densidad
• Se utiliza una función o textura de ruido que se aplica a distintas octavas y a distintas amplitudes.
• Frecuencias altas generan más irregularidades en el terreno.• Frecuencias bajas y amplitudes grandes generan grandes estructuras
como cañones y montañas.
density += raw_noise_3d(x*15.93, y*15.93, z*15.93) * 0.12;density += raw_noise_3d( x*8.03, y*4.03, z*4.03) * 0.25;density += raw_noise_3d( x*1.96, y*1.96, z*1.96) * 0.51;density += raw_noise_3d( x*1.01, y*1.01, z*1.01) * 1.01;density += raw_noise_3d( x*0.08, y*0.08, z*0.08) * 3.99;density += raw_noise_3d( x*0.021, y*0.021, z*0.021) * 8.99;density += raw_noise_3d( x*0.007, y*0.006, z*0.005) * 32.2;
David Haro Gásquez (2015)
Oclusión Ambiente: Normales
• Para obtener un modelo de iluminación realista han de calcularse las normales apropiadamente para cada uno de los vértices generados en el Geometry Shader.
• Se utiliza el gradiente de la textura de ruido normalizado como normal.
float d = 1.0/(float)voxels_per_block; vec3 grad;grad.x = texture(uDensity, uvw + vec3(d,0,0)).r - texture(uDensity, uvw + vec3(-d,0,0)).r;grad.y = texture(uDensity, uvw + vec3(0,d,0)) r - texture(uDensity, uvw + vec3(0,-d,0)).r;grad.z = texture(uDensity, uvw + vec3(0,0,d)).r - texture(uDensity, uvw + vec3(0,0,-d).r;gNormal = normalize(grad);
David Haro Gásquez (2015)
Ambient Occlusion
• Con esas normales se aplica el algoritmo de Oclusión Ambiente calculando en la semiesfera la cantidad de luz que es ocultada por otras partes del terreno.
• Se utilizan unos vectores fijos y se calcula la densidad en esos puntos (textura) para comprobar si existe terreno o no en esa dirección y calcular el factor de oclusión.
David Haro Gásquez (2015)
Texturas: Proyección Plana Triple• Se utilizan 3 texturas para los distintos ejes y se mezclan.• Se utiliza la normal para saber la aportación de cada dirección• Si el componente más significativo de la normal es x, se aplica la
proyección plana de la textura en los ejes yz.
David Haro Gásquez (2015)
Demostración
• Precálculo de las densidades en la CPU en un cubo de 129x65x129 vértices para un cubo dividido en 128x64x128 voxels.
• Precálculo del caso de Marching Cubes para cada voxel.
David Haro Gásquez (2015)
Conclusiones
• Algoritmo eficiente para la generación de terrenos de manera procedural. ¿Cierto?• He precalculado la densidad en la CPU porque he trabajado con
un volumen estático. La densidad no cambia por tanto no es necesario calcularla en cada frame.
• La idea del algoritmo es tener buffers que calculen los volúmenes cuando entren en el frustum desechando los ya no se necesiten. De esta manera el cálculo se reparte. • Se marcan los volúmenes vacíos para no volver a calcularlos• Mediante Compute Shaders y SSBO.
David Haro Gásquez (2015)
Conclusiones
• Desventajas:• Utiliza mucha memoria en la GPU.• El algoritmo de los Marching Cubes puede generar agujeros.• Utiliza mucha memoria en la GPU.
David Haro Gásquez (2015)
Referencias
• Nguyen, H. (2007). Gpu gems 3. Addison-Wesley Professional.• Chapter 1. Generating Complex Procedural Terrains Using the
GPU, Ryan Geiss.
David Haro Gásquez (2015)
¡Gracias por vuestra atención!