Tema 2.4 Etapa de Teselación
Transcripción
Tema 2.4 Etapa de Teselación
TEMA 2.4 ETAPA DE TESELACIÓN E IMPLEMENTACIÓN HARDWARE Curso 2013 / 14 Procesadores Gráficos y Aplicaciones en Tiempo Real Profesores: David Miraut y Óscar D. Robles c GMRV 2005-2014 – Febrero 2014 David Miraut Andrés Procesadores Gráficos y Aplicaciones en Tiempo Real 2013/14 1/ 48 1/48 Índice • • • • • • ¿Qué es la teselación? Utilidad de los shader de teselación Tessellation Control Shader Tessellation Patch Generator Tessellation Evaluation Shader Niveles de división internos y externos David Miraut Andrés Etapa de Teselación Índice inicial 2/ 48 2/48 Localización en el cauce gráfico Shader de vértices Variables entr./salid Ensamblado de primitivas Shader de control de teselación Variables entr./salid Variables (atributos) por vértice Variables Uniform Generador de primitivas de teselación Shader de evaluación de teselación Variables entr./salid Ensamblado de primitivas Shader de Geometría Ensamblado de primitivas Variables entr./salid Rasterizador Shader de fragmentos David Miraut Andrés Etapa de Teselación Posición y utilidad del shader de teselación 3/ 48 3/48 Definición Si buscamos en el diccionario, la teselación es la técnica artística para la creación de mosaicos David Miraut Andrés Etapa de Teselación Definición 4/ 48 4/48 ¿Qué es la teselación? En un contexto más moderno, la teselación es el proceso es la creación de un patrón regular (o irregular) que cubre (o pavimenta) una superficie mediante la repetición de una forma (primitiva) sin que: • queden huecos • se superpongan las figuras / piezas En general se aplica a superficies planas, pero en informática gráfica se generaliza a superficies en dimensiones más altas. Teselado en un pavimento David Miraut Andrés Los patrones de repetición suelen ser regulares en construcciones humanas Etapa de Teselación Definición Las mejores teseladoras son las abejas En problemas de elementos finitos, la triangularización del dominio es esencial 5/ 48 5/48 ¿Para qué sirve el shader de teselación? modelo grosero (baja poligonización) modelo “teselado” con suavidad modelo teselado al que se ha aplicado mapa de desplazamiento http://www.nvidia.com/object/tessellation.html Típicamente se utiliza para convertir un modelo grosero en otro con mayor detalle David Miraut Andrés Etapa de Teselación Definición 6/ 48 6/48 ¿Para qué sirve el shader de teselación? Aparece en OpenGL 4.0 e interpola la descripción geometrica para crear nuevas primitivas que permiten: • realizar subdivisión adaptativa (según el criterio que deseemos: tamaño, curvatura. . . ) • suavizar modelos lowpoly, de modo que se puede considerar • • • • una forma de “comprimir” geometría aplicar mapas de desplazamiento de manera se añada detalle sólo donde sea necesario (el muestreo pasa a no ser uniforme) adaptar la calidad visual al nivel de detalle requerido crear siluetas más suaves realizar skinning con mayor facilidad. . . David Miraut Andrés Etapa de Teselación Definición 7/ 48 7/48 Se nota especialmente en las siluetas http://www.chromesphere.com/tutorials/vue6/Optics_Basics_Print.html Como ya hemos comentado, el sistema visual humano es especialmente sensible con la frontera de los objetos a la hora de reconocerlos y determinar su “realismo”. David Miraut Andrés Etapa de Teselación Definición 8/ 48 8/48 La etapa de teselación Los shaders de teselación tienen acceso a toda la información de renderizado (al igual que la implementación moderna del resto de las etapas programables). Por ello, “brillan” cuando sus programas se adaptan dinámicamente a la situación de la escena: las transformaciones aplicadas, curvatura, espacio ocupado en pantalla. . . De forma análoga al Modern Geometry Engine (2001), la etapa de teselación se subdivide en dos etapas con shaders separados: • Tesellation Control Shader (TCS) • Tesellation Evaluation Shader (TES) Cuando hablamos en términos generales nos referimos a ambos. David Miraut Andrés Etapa de Teselación Definición 9/ 48 9/48 Shader de teselación vs geometría • Los shaders de teselación amplifican una única primitiva (a diferencia del shader de geometría que puede tener información de localidad) y están limitados a generar primitivas exactamente del mismo tipo de la primitiva de partida. • No pueden emitir primitivas con información de adyacencia, porque actúan sobre cada primitiva por separado. De modo que si se activa el shader de teselación, hay shaders de geometría que dejan de poderse utilizar (al no disponer de las primitivas de partida). • A cambio, el limite en la cantidad de geometría a generar es mucho más alto. David Miraut Andrés Etapa de Teselación Definición 10 / 10/4848 El Patch • Los shaders de teselación utilizan una nueva primitiva como entrada: el parche (patch). • Es necesario declarar este tipo de topología, independientemente de que utilicemos vertex arrays, o bufferes, o glBegin / glEnd glBegin( GL_PATCHES ); glVertex3f( . . . ); glVertex3f( . . . ); glEnd( ); • No implica un orden en la lista de vértices. Es suficiente con tener la convención consistente para el tipo de geometría que se tesela1 / subdivide. 1 De hecho los valores de coordenadas de los vértices no tiene porque ser reales, los podemos utilizar como parámetros geométricos. 11 / David Miraut Andrés Etapa de Teselación Conceptos 11/4848 Número de vértices en el patch Se suele recomendar establecer previamente el número de vértices que compone cada parche. glPatchParameteri( GL_PATCH_VERTICES, num ); De esta forma no es necesario indicar con el par glBegin / glEnd el inicio y el final de una primitiva. Es suficiente con ir enumerando los vértices. Una vez alcance num vértices, se iniciará la siguiente primitiva. David Miraut Andrés Etapa de Teselación Conceptos 12 / 12/4848 Subetapas en la teselación datos por vértice parche de salida v TCS parche inicial niveles de teselación TPG 1 TES 0 OpenGL 4 Shading Language Cookbook David Miraut Andrés Etapa de Teselación Conceptos 1 u primitivas generadas en coordenadas de teselación (espacio de parámetros) 13 / 13/4848 Tessellation Control Shader (TCS) • Su función es preparar los puntos de control final y determinar cuánto se va a teselar. • Es llamado una vez por cada punto de control y toma como entrada num vértices modificados por la etapa anterior. • Transforma las coordenadas de entrada para formar una representación de una superficie regular • el cálculo del nivel necesario de teselación dependerá de los criterios escogidos: ◦ área ocupada en espacio de pantalla ◦ curvatura de la superficie ◦ rugosidad del mapa de desplazamiento. . . David Miraut Andrés Etapa de Teselación Tessellation Control Shader 14 / 14/4848 TCS: Parámetros y variables de entrada El TCS recibe de la etapa anterior una estructura gl_in[] por vértice de control, que contiene: vec4 gl_Position; float gl_PointSize; float gl_ClipDistance[ ]; Además de las siguientes variables: • int gl_InvocationID indica sobre que vértices de salida se está trabajando. Es el índice de la estructura gl_out[], Se puede leer cualquier valor del array, pero sólo escribir en éste. • int gl_PatchVerticesIn Es el número de vértices en cada patch, y la dimensión de gl_in[] • int gl_PrimitiveID Es el número de elementos desde el últimoglBegin() (el primero es 0) David Miraut Andrés Etapa de Teselación Tessellation Control Shader 15 / 15/4848 TCS: Parámetros y variables de salida Se puede indicar al cauce cuántos puntos de control se dan como salida2 , mediante el calificador layout: layout( vertices = N ) out; La estructura de datos de salida gl_out[] tendrá el número de puntos de control (N) indicado: vec4 gl_Position; float gl_PointSize; float gl_ClipDistance[ ]; Y las variables gl_TessLevelOuter[4] y gl_TessLevelInner[2] 2 el número de puntos de control está relacionado con el tipo de ecuaciones geométricas que estemos utilizando para el parche. No tiene que ver con cuantas primitivas se vayan a producir durante la teselación (ya que dependen del número de niveles escogido). 16 David Miraut Andrés Etapa de Teselación Tessellation Control Shader / 16/4848 TCS: funcionamiento • Las instancias de TCS se ejecutan de forma prácticamente independiente → sin un orden relativo preestablecido • Sin embargo, es posible que en ciertos puntos estas instancias necesiten leer variables que otras instancias todavía no hayan escrito • barrier() permite establecer un punto de sincronización pata todas las instancias de una misma primitiva ◦ Sólo se puede llamar desde la función principal del shader ◦ Y no debe ser invocada desde una porción de código que potencialmente pueda dar lugar a divergencia de codigo (bucles for, do, while. . . ramificaciones switch, ifs. . . ) David Miraut Andrés Etapa de Teselación Tessellation Control Shader 17 / 17/4848 Tessellation Patch Generator (TPG) Polymorph Engine Vertex Fetch Tesselator Viewport Transform Attribute Setup Stream Output También en la subetapa de teselación tenemos unidades funcionales que internamente mantienen un diseño con arquitectura streaming David Miraut Andrés Etapa de Teselación Tessellation Patch Generator 18 / 18/4848 Tessellation Patch Generator (TPG) • Es una etapa no programable que se ha incorporado en la parte de funcionalidad fija del cauce gráfico • No se puede cambiar su funcionamiento, pero puede configurarse mediante parámetros • Se invoca una vez por patch • Crea el adecuado número de triángulos, quads o segmentos de línea y sus posiciones como coordenadas paramétricas en un sistema baricéntrico semiregular (u, v , w ) donde 0 ≤ u, v , w ≤ 1 David Miraut Andrés Etapa de Teselación Tessellation Patch Generator 19 / 19/4848 Tessellation Evaluation Shader (TES) • Lee las coordenadas (u, v , w ) del TPG y las coordenadas de los puntos de control del TCS y a partir de ellas: ◦ establece las coordenadas de salida (x , y , z) ◦ interpola los atributos a lo largo del parche ◦ aplica el desplazamiento (si tomamos datos de texturas) • Hay una instancia de TES por vértice a generar • Si se utiliza TES pero no TCS, se deben crear algunos datos -en el programa principal- que normalmente daría el TCS glPatchParameterfv( GL_DEFAULT_OUTER_LEVEL, float [4] ); glPatchParameterfv( GL_DEFAULT_INNER_LEVEL, float [2] ); La teselación interna y externa define el número de subdivisiones del perímetro y el interior de la primitiva de entrada David Miraut Andrés Etapa de Teselación Tessellation Evaluation Shader 20 / 20/4848 Patrón de interpolación El patrón de interpolación generado por TPG se establece en el layout de TES: triangles equal_spacing ccw layout( quads , fractional_even_spacing , cw , point_mode) in; fractional_odd_spacing isolines { • • • • }{ }{ { El primer parámetro define el patrón de teselación El segundo la separación entre segmentos El tercero la orientación de los triángulos (de haberlos) point mode le indica a TES que genere puntos en lugar de triángulos o líneas El funcionamiento por defecto genera triángulos con orientación antihoraria uniformemente equiespaciados. layout( triangles, equal_spacing, ccw ) in; David Miraut Andrés Etapa de Teselación Tessellation Evaluation Shader 21 / 21/4848 Separación entre segmentos • equal_spacing limita el nivel de tesleación entre [1, max ] y redondea al entero más cercano. Cada segmento tiene igual longitud • fractional_even_spacing limita el nivel de teselación entre [2, max ] y redondea al entero par más cercano. • fractional_odd_spacing limita el nivel de teselación entre [1, max − 1] y redondea al entero impar más cercano. donde max es el valor devuelto por GLuint maxLevel; glGetIntegerv(GL\_MAX\_TESS\_GEN\_LEVEL, &maxLevel); David Miraut Andrés Etapa de Teselación Tessellation Evaluation Shader 22 / 22/4848 Separación entre segmentos En los dos fraccionales, los segmentos tienen igual longitud, salvo el inicial y el final, cuyo tamaño es proporcional a la fracción del nivel recortado. Esto permite una transición suave entre niveles, que reduce el efecto de popping David Miraut Andrés Etapa de Teselación Tessellation Evaluation Shader 23 / 23/4848 TES: Parámetros y variables de entrada El TES tiene acceso a la estructura de entrada gl_in[] que es idéntica a la de salida gl_out[] del TCS in int gl_PatchVerticesIn; in int gl_PrimitiveID; in vec3 gl_TessCoord; David Miraut Andrés Etapa de Teselación Tessellation Evaluation Shader 24 / 24/4848 TES: Parámetros y variables de salida Escribe la información para un único vértice mediante 3 variables: vec4 gl_Position; float gl_PointSize; float gl_ClipDistance[ ]; Sólo gl_Position es obligatoria, el resto son opcionales. Es posible definir variables de usuario para incorporar información adicional. David Miraut Andrés Etapa de Teselación Tessellation Evaluation Shader 25 / 25/4848 Niveles de división interna y externa El TCS le dice al TPG cuántas primitivas tiene que generar especificando los niveles de división interna y externa mediante un par de arrays: patch out float gl_TessLevelOuter[4] patch out float gl_TessLevelInner[2] quad triángulo isolínea gl_TessLevelOuter[0] gl_TessLevelOuter[1] gl_TessLevelOuter[2] gl_TessLevelOuter[3] gl_TessLevelInner[0] gl_TessLevelInner[1] David Miraut Andrés Etapa de Teselación Niveles de división internos y externos 26 / 26/4848 Teselación en los quads: niveles de división internos y externos (u=0,v=1) OL3 (u=1,v=1) IL0 v OL0 OL2 IL1 (u=0,v=0) OL1 u David Miraut Andrés Etapa de Teselación (u=1,v=0) El nivel exterior viene determinado por un array en coma flotante de 4 elementos. El nivel interior sólo por 2 elementos La clave está en el orden de dichos elementos al ser aplicados (primero externos, luego internos en el orden de los índices según su posición en el dibujo - antihorario) Niveles de división internos y externos 27 / 27/4848 Teselación en los quads: niveles de división internos y externos Primero se subdivide el rectángulo en una malla regular de rectángulos en la que el número de subdivisiones viene dado por el nivel de teselación interno v u gl_TessLevelInner[0] = 5 gl_TessLevelInner[1] = 4 David Miraut Andrés Etapa de Teselación Niveles de división internos y externos 28 / 28/4848 Teselación en los quads: niveles de división internos y externos Todos los rectángulos, salvo aquellos adyacentes a los bordes del rectángulo original, se descomponen en pares de triángulos. La especificación de OpenGL advierte “algorithm used to subdivide the rectangular domain in (u, v) space into individual triangles is implementation-dependent” David Miraut Andrés Etapa de Teselación Niveles de división internos y externos 29 / 29/4848 Teselación en los quads: niveles de división internos y externos Los rectángulos en la parte exterior son subdivididos de forma independiente gl_TessLevelOuter[0] gl_TessLevelOuter[1] gl_TessLevelOuter[2] gl_TessLevelOuter[3] David Miraut Andrés Etapa de Teselación = = = = Niveles de división internos y externos 1 2 4 5 30 / 30/4848 Teselación en los quads: niveles de división internos y externos El área entre los rectángulos internos y los bordes externos se rellena con triángulos que se producen al conectar los vértices del borde exterior con el borde de la zona interior David Miraut Andrés Etapa de Teselación Niveles de división internos y externos 31 / 31/4848 Teselación en los quads: niveles de división internos y externos Ejemplo más simple: del capítulo 6 del libro OpenGL Insights David Miraut Andrés Etapa de Teselación Niveles de división internos y externos 32 / 32/4848 Teselación en triángulos: niveles de división internos y externos coordenadas baricéntricas u w Se determina en coordenadas baricéntricas. Este sistema de coordenadas da una única representación única a cada punto (u, v , w ) La clave está en el orden de dichos elementos al ser aplicados (primero externos, luego internos en el orden de los índices según su posición en el dibujo). v (u=0,v=1,w=0) OL0 OL2 IL0 (u=0,v=1,w=0) David Miraut Andrés OL1 (u=1,v=0,w=0) Etapa de Teselación Niveles de división internos y externos 33 / 33/4848 Teselación en triángulos: niveles de división internos y externos Primero, temporalmente se subdivide cada arista en triángulos equiláteros utilizando el nivel de teselación interna n gl_TessLevelInner[0] = 4 David Miraut Andrés Etapa de Teselación Niveles de división internos y externos 34 / 34/4848 Teselación en triángulos: niveles de división internos y externos Se genera un triángulo interno con las aristas subdivididas en n-2 segmentos David Miraut Andrés Etapa de Teselación Niveles de división internos y externos 35 / 35/4848 Teselación en triángulos: niveles de división internos y externos Se continúa generando triángulos anidados en el interior hasta que se alcanza el nivel de subdivisión 1 ó 0 David Miraut Andrés Etapa de Teselación Niveles de división internos y externos 36 / 36/4848 Teselación en triángulos: niveles de división internos y externos Se continúa generando triángulos anidados en el interior hasta que se alcanza el nivel de subdivisión 1 ó 0 gl_TessLevelInner[0] = 5 David Miraut Andrés Etapa de Teselación Niveles de división internos y externos 37 / 37/4848 Teselación en triángulos: niveles de división internos y externos Se descarta la subdivisión temporal y se reconecta de acuerdo con el muestreo indicado en los parámetros. gl_TessLevelInner[0] = 8 gl_TessLevelInner[1] = 2 gl_TessLevelInner[2] = 4 David Miraut Andrés Etapa de Teselación Niveles de división internos y externos 38 / 38/4848 Teselación en triángulos: niveles de división internos y externos Ejemplo más simple: del capítulo 6 del libro OpenGL Insights David Miraut Andrés Etapa de Teselación Niveles de división internos y externos 39 / 39/4848 Teselación en triángulos: ejemplo en un icosaedro Fijaros bien en la relación entre niveles internos y externos: David Miraut Andrés Etapa de Teselación Niveles de división internos y externos 40 / 40/4848 Teselación en triángulos: ejemplo en un icosaedro Depende del efecto buscado: inner = 1 outer = 1 inner = 3 outer = 1 inner = 1 outer = 4 % http://prideout.net/blog/?p=48 David Miraut Andrés Etapa de Teselación Niveles de división internos y externos 41 / 41/4848 Teselación en isolíneas: niveles de división internos y externos Se crean n segmentos de líneas paralelas subdivididas en m segmentos, donde m y n son los dos primeros niveles de teselación. u 1, v 1 u 1, v 1 v v u gl_TessLevelOuter[0] = 3 gl_TessLevelOuter[1] = 1 u gl_TessLevelOuter[0] = 6 gl_TessLevelOuter[1] = 4 David Miraut Andrés Etapa de Teselación Niveles de división internos y externos 42 / 42/4848 Consideraciones al establecer los niveles de subdivisión Los niveles vienen determinados por criterios • estéticos: para que la imagen sintética tenga suficiente calidad (pero no tiene sentido invertir recursos en subdividir más allá de lo que se puede percibir) • Evitar cracks: los parches vecinos deben encajar apropiadamente, lo que implica que tengan un borde exterior con el mismo nivel y que sus vértices estén alineados y encajen. David Miraut Andrés Etapa de Teselación Niveles de división internos y externos 43 / 43/4848 Impacto relativo en GPUs poco potentes Sin teselación: 30 fps David Miraut Andrés Etapa de Teselación Niveles de división internos y externos 44 / 44/4848 Impacto relativo en GPUs poco potentes Con teselación uniforme (Inner: 2, Outer: 2): 9 fps David Miraut Andrés Etapa de Teselación Niveles de división internos y externos 45 / 45/4848 Impacto relativo en GPUs poco potentes Con teselación uniforme (Inner: 3, Outer: 2): 6 fps Se puede mejorar mucho si se hace en función de la distancia al 46 /48 David Miraut Andrés Etapa de Teselación Niveles de división internos y externos 46/48 Vídeo http://www.youtube.com/watch?v=NH7hO2kSE4s David Miraut Andrés Etapa de Teselación Niveles de división internos y externos 47 / 47/4848 Bibliografía sobre arquitectura unificada • OpenGL Insights. Patrick Cozzi y Christophe Riccio. A K Peters/CRC Press - Capítulos 6 y 10 • Graphics Shaders: Theory and Practice. Mike Bailey, Steve Cunningham. Second Edition. A K Peters/CRC Press • Programming Massively Parallel Processors – A Hands-on Approach. D. B. Kirk and W. W. Hwu. Morgan Kaufmann. David Miraut Andrés Etapa de Teselación Niveles de división internos y externos 48 / 48/4848