Esta sección es un tanto singular: no solo esta consola dispone de varias pantallas que renderizar, sino que también combina motores de tile tradicionales con un renderizador moderno.

Comparación de resolución de pantalla y relación de aspecto entre la Game Boy, la Game Boy Advance y la serie Nintendo DS.
Empecemos con los atributos físicos: la Nintendo DS incorpora dos pantallas LCD, cada una con una resolución de 256 × 192 píxeles, lo que supone aproximadamente un 20 % más de píxeles que la GBA. Pueden mostrar 262.144 colores (18 bits) y se refrescan a ~60 Hz.
Arquitectura
El subsistema gráfico puede renderizar objetos tanto 2D como 3D. El primero está compuesto por geometría bidimensional —en otras palabras, bitmaps de 8 × 8 píxeles llamados 'tiles'. El segundo dibuja objetos tridimensionales (polígonos) mediante vértices.
Al adentrarnos en el chip interno que opera estas pantallas, observamos que esta consola cuenta con hardware diferenciado para geometría 2D y 3D. Los datos 2D los gestiona un motor conocido, la Picture Processing Unit (PPU, ahora denominada simplemente motor 2D), mientras que los datos 3D los maneja un subsistema completamente nuevo. Dicho esto, la consola alberga dos motores 2D y un motor 3D. Conviene señalar que, aunque esta no es la primera consola de Nintendo en incorporar gráficos 3D, sí es la primera que incluye un diseño propio para renderizar formas tridimensionales.

Esquema del subsistema gráfico.
Ahora bien, cada motor solo puede vincularse a una de las pantallas. Esto no supone un problema para los juegos exclusivamente en 2D, ya que cada pantalla dispone de su propio motor 2D. Sin embargo, para los juegos que deseen explotar las características más avanzadas, solo hay un motor 3D disponible. En consecuencia, las capacidades 3D solo están disponibles en una pantalla a la vez.
... ¿Y qué ocurre con la mezcla de objetos 2D y 3D? Desde luego, es posible. Permíteme explicar cada motor por separado para abordar este punto después.
Construyendo un frame con gráficos 2D
Antes de repasar cada etapa, te recomiendo leer sobre la PPU de la GBA, ya que aquí me limitaré a destacar los cambios que dieron lugar a la 'siguiente generación' de juegos en 2D.
Para situar el contexto: como hay dos motores 2D, el primero se denomina Main y el segundo Sub. Esto no implica necesariamente a qué pantalla está conectado cada uno. Por otro lado, Main ofrece algo más de funcionalidad que Sub.
Para apoyar las explicaciones, esta vez utilizaré New Super Mario Bros como ejemplo.
Tiles

Algunos tiles encontrados en la VRAM. A efectos demostrativos, se utiliza una paleta por defecto.
A estas alturas todos sabemos cómo funciona un motor de tiles básico, pero ¿cómo se gestionan exactamente los tiles en esta consola? Pues bien, hay un total de 656 KB de VRAM disponibles , y este bloque se reparte en distintos bancos: cuatro de 128 KB, uno de 64 KB, uno de 32 KB y tres de 16 KB. Los programadores pueden rellenar estos bancos con gráficos y luego indicar al motor qué datos necesita. Además, ambos motores pueden leer de cualquiera de los bancos, aunque no pueden acceder al mismo de forma simultánea.
No obstante, existen algunas limitaciones en la distribución de los datos. Por ejemplo, el ARM7 solo puede acceder a dos bancos de 128 KB. Al mismo tiempo, estos dos bancos no pueden almacenar sprites, y Sub es el único motor capaz de acceder al último banco de 16 KB. La lista continúa, pero ya te haces una idea.
Una última cosa: el motor 3D, al que entraremos más adelante, puede acceder a algunos de estos bancos para leer texturas.
Tipos de fondo
Desde que la Super Nintendo debutó, los diseños sucesivos de la PPU han ido orientándose a ofrecer mayor flexibilidad para las capas de fondo. Catorce años después, este esfuerzo culminó en un chip capaz de leer tiles, aplicar numerosas transformaciones afines y, si eso fuera poco, ensamblar una capa directamente desde un frame buffer.
Antes de analizar los distintos modos que el motor 2D utiliza para generar fondos, veamos esta lista, que especifica los tipos de fondos que el motor puede generar:
- Grupo de tipo tile: Estos tipos de fondo siguen el sistema de tiles tradicional; es decir, el frame se renderiza rellenándolo con tiles.
- Fondo estático: Un fondo ordinario de hasta 512 × 512 píxeles, con 256 colores y 16 paletas. Incluye todos los efectos habituales (inversión horizontal/vertical y desplazamiento, mosaico y mezcla alfa) más un efecto de fundido adicional. Se pueden utilizar hasta 1.024 tiles.
- Fondo afín: Un fondo con transformaciones afines. Sin embargo, no admite inversión horizontal/vertical y solo puede leer 256 tiles (una cuarta parte del máximo). El tamaño de esta capa es de 1024 × 1024 píxeles.
- Afín extendido: Igual que el afín, pero con la cantidad total de tiles restaurada y compatible con inversión horizontal/vertical.
- Grupo de tipo bitmap: En lugar de procesar tiles, el motor trata la VRAM como un frame buffer.
- Afín extendido (256 colores): Hereda todos los efectos disponibles en el 'afín extendido' de tile. La diferencia es que ahora se aplican sobre un único bitmap de 512 × 512 píxeles.
- Afín extendido (color directo): Similar al anterior, pero el frame buffer admite hasta 32.768 colores (15 bits).
- Pantalla grande: Consume un bloque entero de 128 KB de VRAM para renderizar un frame buffer de 1024 × 512 píxeles.
- Fondo 3D: Muestra la salida del motor 3D como capa de fondo, algo esencial para visualizar lo que el motor 3D ha procesado. Aunque no ofrece muchos efectos 2D, sí presenta características interesantes como el desplazamiento horizontal y la mezcla alfa (con otras capas de fondo). Además, es el único tipo que admite hasta 262.144 colores (18 bits).
Estos modos no pueden elegirse de forma arbitraria; la consola ofrece un conjunto de modos de fondo con combinaciones predefinidas. Sea como fuere, siempre que un modo de fondo indique que admite 'afín extendido', los desarrolladores pueden elegir la variante ('tile', '256 colores' y 'color directo').
Modos de fondo

Capa de fondo 0 (BG0). Esta capa en particular se desplaza horizontalmente en determinadas líneas de escaneo para simular el movimiento de las nubes.
Aquí es donde los tipos de fondo entran en acción. Main y Sub ofrecen varios modos de operación. Todos ellos generan cuatro capas de fondo; sin embargo, cada capa tiene capacidades distintas según el modo activado :
- Modo 0: 4 capas estáticas.
- Modo 1: 3 capas estáticas + 1 capa afín.
- Modo 2: 2 capas estáticas + 2 capas afines.
- Modo 3: 3 capas estáticas + 1 capa afín extendida.
- Modo 4: 2 capas estáticas + 1 capa afín + 1 capa afín extendida.
- Modo 5: 2 capas estáticas + 2 capas afines extendidas.
- Este es un modo muy popular por su gran flexibilidad.
- Modo 6: 1 capa de fondo 3D + 1 pantalla grande.
- Como solo hay espacio para un único frame buffer, este modo está disponible únicamente en 'Main'.
Además, en los modos 0 a 5, el motor Main puede configurar la primera capa estática como fondo 3D. Las capacidades 3D se tratarán en breve.
Sprites
Los sprites u 'Objetos' heredan la misma funcionalidad que la PPU de la GBA, pero con dos añadidos destacables.
En primer lugar, la Object Attribute Memory (OAM, la región donde se almacenan las entradas de sprites) tiene ahora 2 KB de tamaño , lo que permite mostrar hasta 128 sprites por frame y por pantalla. Por tanto, se asigna 1 KB a cada motor.
En segundo lugar, la OAM puede referenciar ahora bitmaps de la VRAM en lugar de utilizar únicamente tiles y paletas . Este es otro alejamiento del sistema de tiles. De hecho, ambos 'modos' de sprite pueden coexistir en el mismo frame, ya que esta opción se establece por sprite individual.
Resultado

Todas las capas combinadas... ¿falta algo?
A medida que cada capa se renderiza al vuelo, la etapa final se encarga de combinarlas y enviarlas a la pantalla seleccionada. Esto es básicamente lo que ocurre en las anteriores consolas basadas en PPU. ¿Significa esto que hemos terminado?
¡Todavía no! Main aún necesita leer una capa del otro motor, el más potente.
El acelerador 3D
Si alguna vez has jugado con una Nintendo DS, ya sabes que esta consola puede mostrar una cantidad particular de gráficos 3D. Sin embargo, a diferencia de algunos juegos de GBA, estos no se renderizan mediante la CPU. En su lugar, la CPU NTR incluye dos componentes que juntos constituyen el motor 3D, un diseño que me recuerda al Reality Coprocessor de SGI.
Volviendo a la sección 'Modos de fondo', notarás que todos los modos tienen al menos una capa estática. Esto se debe a que puedes rellenar esa capa con los gráficos producidos por el motor 3D. La única condición es que solo Main puede hacerlo. Esto también explica por qué el Modo 6 solo está disponible en Main.
Motor de geometría

Arquitectura del motor de geometría.
Si has leído alguno de los artículos de la 5.ª o 6.ª generación, puede que te preguntes... ¿Dónde está el procesador SIMD? Es una buena pregunta, porque el ARM9 no destaca precisamente en operaciones vectoriales, y no creo que el divisor dedicado sea suficiente. Por eso Nintendo integró un componente llamado Geometry Engine que se encarga de las transformaciones de vértices, la proyección, la iluminación, el clipping, el culling y el ordenamiento de polígonos, este último esencial para el uso correcto de las características de transparencia .
Este motor tiene algunas limitaciones estrictas, especialmente en cuanto al número de polígonos que puede procesar: dispone de 248 KB adicionales de RAM para almacenar la geometría procesada. Esta cantidad admite hasta 2048 triángulos o 1706 cuadriláteros , aunque este límite puede ampliarse mediante tiras de polígonos (en lugar de polígonos individuales). Cabe tener en cuenta, además, que la resolución de pantalla de esta consola es relativamente pequeña, lo que también sirve de compensación.
En cualquier caso, este motor se controla mediante una Command FIFO que la CPU o el DMA van rellenando . La FIFO almacena 256 entradas, complementadas por otro búfer llamado PIPE con capacidad para cuatro comandos más (para un total de 260).
Motor de renderizado

Arquitectura del motor de renderizado.
El motor de renderizado se encarga de convertir los vectores en píxeles (es decir, de la rasterización), de colorearlos (es decir, de aplicar texturas) y de aplicar iluminación y otros efectos . Para interpolar texturas e iluminación, respectivamente, recurre a la perspective correction y al sombreado Gouraud. Además, la unidad ofrece características modernas como niebla, mezcla alfa, depth buffering (ya sea Z-buffering o una variante denominada W-buffering), stencil tests y antialiasing. Sin embargo, este último es muy básico (simplemente define los bordes exteriores de los polígonos como transparentes) y solo funciona con píxeles opacos.
El sistema de renderizado es una mezcla de lo antiguo y lo nuevo: en lugar de generar un frame buffer, emplea el renderizado con búfer de línea, rellenando líneas de escaneo (de forma similar al motor 2D) y almacenando los resultados en un búfer más pequeño. Esto se debe a que el motor 3D debe operar al mismo ritmo que el motor 2D.
Al prescindir del frame buffer tradicional, el rasterizador emplea el renderizado por línea de escaneo, recorriendo cada línea para procesar los bordes de polígonos que encuentre. Arisotura (la desarrolladora del emulador MelonDS) señaló que, por cada cuadrilátero, el renderizador solo puede rellenar un tramo por línea de escaneo . Esto puede resultar problemático, ya que el resultado se desordena si el cuadrilátero es cóncavo o contiene bordes cruzados, por ejemplo.
En cuanto a los efectos, la unidad también ofrece sombreado y una característica singular llamada Toon Shading (otro nombre para el Cel Shading): aunque esta unidad no es programable, se pueden modificar los parámetros de iluminación para lograr un efecto de dibujo animado .
Resultado
En lugar de escribir los resultados en un frame buffer para su visualización, el motor de renderizado escribe en un bloque denominado Colour Buffer que almacena hasta 48 líneas de escaneo . El motor 2D lee cada línea de escaneo para rellenar la capa BG0. Esto se hace siguiendo el modelo FIFO.
El renderizado 3D comienza antes que el 2D, lo que permite a este último aplicar transformaciones sobre la nueva capa si es necesario. Main también permite capturar el frame generado por el motor 2D, el 3D o la combinación de ambos, combinarlo con otro frame de la VRAM y escribir el resultado de vuelta a la VRAM para su posterior visualización.
En cuanto al control, el motor de renderizado también permite modificar sus parámetros a mitad del frame gracias a un mecanismo de doble búfer que preserva una copia del estado anterior hasta que el frame actual ha terminado de dibujarse. De este modo, no se producen desgarros de imagen.
Comparativas famosas
Algunos de los primeros juegos lanzados para esta consola intentan emular sus equivalentes de Nintendo 64. Por eso me pareció una buena oportunidad para resumir por qué los jugadores pueden notar ciertos patrones entre ambas versiones .

Super Mario 64 (1996).
Renderizado a 320×240 píxeles.

Super Mario 64 DS (2004).
Renderizado a 256×192 píxeles.

Mario Kart 64 (1996).
Renderizado a 320×240 píxeles.

Mario Kart DS (2005).
Renderizado a 256×192 píxeles.
Para explicar lo que ocurre, he organizado las distintas aclaraciones en función de lo que algunos usuarios comentaron en foros:
- Las texturas de la NDS parecen más pixeladas: El motor de renderizado no aplica ningún filtro. Por tanto, las texturas se interpolan mediante el método del 'vecino más próximo'.
- Las texturas de la NDS parecen más ricas: El motor de renderizado no está limitado por un bloque de 4 KB de memoria de texturas. En su lugar, dispone de hasta 512 KB de VRAM y numerosos mecanismos de compresión. Naturalmente, esto permite cargar más datos.
- Los modelos de la NDS presentan bordes pixelados: Los modelos de la NDS se renderizan a una resolución inferior a la de sus equivalentes de N64.
- Las texturas de la NDS aparecen distorsionadas al verlas desde lejos: El rasterizador opera con coordenadas de punto fijo. La baja resolución y la ausencia de mip-mapping también contribuyen al aliasing.
En pocas palabras, eso es lo esencial. Para casos más especializados, tendrás que profundizar en ambos motores y posiblemente desensamblar los juegos para investigar qué funciones se utilizan y cómo.
Modelos en 3D
A continuación se visualizan modelos 3D de juegos diseñados para esta consola. Fíjate en el uso de mapas de textura detallados, aunque limitados al filtrado por vecino más próximo. Esto da lugar a un aspecto 'moderno pixelado', icónico de los gráficos de la Nintendo DS.

Modelo interactivo disponible en la edición moderna
Nintendogs (2005).
750 triángulos.

Modelo interactivo disponible en la edición moderna
New Super Mario Bros (2006).
636 triángulos.
A pesar de haber hablado de muchas limitaciones del subsistema gráfico, he de decir que gran cantidad de juegos supieron sacarle partido.


