Pinte un object texturado de alta resolución (esfera) en OpenGL ES

Estoy dibujando planetas en OpenGL ES y encontrando algunos problemas de performance interesantes. La pregunta general es: ¿cuál es la mejor manera de representar texturas "enormemente detalladas" en una esfera?

(la esfera está garantizada; me interesan las optimizaciones específicas de la esfera)

Caso base:

  • La window es de aprox. 2048 x 1536 (por ejemplo, iPad3)
  • El map de textura para globo es de 24,000 x 12,000 píxeles (un área de la mitad del tamaño de EE. UU. Se ajusta al ancho total de la pantalla)
  • Se muestra el globo en todo, desde el zoom (la pantalla se llena de EE. UU.) Hasta el zoom (todo el globo visible)
  • Necesito un MÍNIMO de 3 capas de textura (1 para la superficie del planeta, 1 para las diferencias de día / noche, 1 para la interfaz de usuario (hilighting different regions)
  • Algunas de las capas están animadas (es decir, tienen que cargar y soltar su textura en time de ejecución, rápidamente)

Limitaciones:

  • Las tabletas de gama alta están limitadas a 4096×4096 texturas.
  • Las tabletas de gama alta están limitadas a 8 unidades de textura simultáneas

Problemas:

  • En total, son ingenuamente 500 millones de píxeles de datos de textura
  • Dividir en texturas más pequeñas no funciona bien porque los dispositivos solo tienen 8 unidades; con una sola capa de textura, podría dividirme en 8 unidades de textura y todas las texturas serían inferiores a 4096×4096, pero eso solo permite una capa única
  • La representación de las capas como geometry separada funciona mal porque deben mezclarse utilizando sombreadores de fragment

… en este momento, la única idea que tengo que suena viable es:

  1. divide la esfera en NxM "piezas de esfera" y renderiza cada una como geometry separada
  2. use mipmaps para representar texturas de baja resolución cuando se networkinguce el zoom
  3. … confíe en el sacrificio simple para recortar la mayoría cuando se amplíe y mipmapping para usar texturas pequeñas (er) cuando no puedan ser sacrificadas

… pero parece que debería haber una manera más fácil / mejores opciones?

Parece que no hay forma de adaptarse a estas enormes texturas en memory de la GPU mobile, incluso en la iPad 3.

Entonces tienes que transmitir datos de textura. Lo que necesita se llama clipmap (popularizado por el software id con tecnología megatexture extendida).

Lea sobre esto aquí, hay enlaces a documentos que describen la técnica: http://en.wikipedia.org/wiki/Clipmap

Esto no se hace fácilmente en ES, ya que no hay una extensión de textura virtual (todavía). Básicamente necesitas implementar texturas virtuales (algunos dispositivos ES implementan ARB_texture_array) y transmitir en la menor resolución posible (dependiendo de la vista) de tu esfera. De esta forma, es posible hacerlo todo en un shader de fragment, no se requiere subsplit de geometry. Vea esta presentación (y el artículo) para más detalles sobre cómo se puede implementar esto.

Si hace los cálculos, es simplemente imposible transmitir 1 GB (24,000 x 12,000 píxeles x 4 B) en time real. Y sería un desperdicio, también, ya que el usuario nunca podrá verlo todo al mismo time.