Super Mario 64 es un juego muy modesto en cuanto a carga poligonal y por ello funciona la mayor parte del tiempo a 30 fps a pesar de ser un juego de lanzamiento, con herramientas de desarrollo poco depuradas y conocimientos de programación y modelado en 3D mejorables.
Mueve bastante menos de 90.000 triángulos por segundo, que a 30 fps significaría 3.000 polígonos por frame. El modelo de Mario con la gorra son 752, y los niveles ENTEROS están alrededor de los 1000 polígonos (Bob Omb Battelefield son 962 polígonos, Whomp's Fortress con la torre 1205, Jolly Roger Bay 722, Cool Cool Mountain 929, Lethal Lava Land 1158, Wet Dry World 725 la parte superior y 768 la parte inferior, Big Boo's Haunt se queda un poco por debajo de los 3.000 pero son muchas salas separadas y puntos de cámara fijos). Muchos elementos como árboles y monedas son 2D, y los enemigos en 3D son simples y con un popping agresivo.
Debe de dibujar unos 2.000 polígonos por frame como mucho, y eso considerando que el microcódigo es muy ineficiente y renderiza todo el nivel a la vez (o al menos el trozo que esté cargado). Es decir, que movería alrededor de unos 60.000 polígonos por segundo.
Las partes donde el rendimiento sufre suelen ser zonas donde hay grandes superficies semitransparentes como el tercer nivel cuando entras la primera vez que tiene varias capas de niebla. Lo del submarino quizás se deba a la mala optimización de las colisiones, a parte del agua semitransparente y la falta de optimización de la compilación del código. Otros niveles con agua como Wet Dry World o Tiny Huge Island no sufren esas ralentizaciones.
Se considera que la N64 mueve alrededor de 90.000 polígonos por segundo con todos los efectos activados. Eso equivaldría a 3.000 polígonos por escena a 30 fps o 4.500 a 20 fps que se ajusta a muchos juegos punteros. World Driver Championship se saldria de la norma porque renuncia al Z-buffer y supera holgadamente los 100.000 polígonos por segundo. Indiana Jones and the Infernal Machine también renuncia al Z-buffer, pero renderiza en alta resolución y su rendimiento es mucho peor.
En realidad ya hemos discutido muchas veces que hay muchos factores que afectan al rendimiento y no sólo la carga poligonal. Cosas como varias capas de polígonos semitransparentes para simular humo, el número objetos con los que se pueda interactuar en el escenario de los que hay que calcular las colisiones e incluso la física, efectos de luz en tiempo real, efectos del buffer de imagen, la IA de los enemigos, la resolución de la pantalla....
Vamos, que ver a Super Mario 64 funcionar a 60 fps y con el mismo aspecto gráfico en el hardware original no es para nada descabellado. Juegos muchísimo más complejos gráficamente, con mejores herramientas de desarrollo y más conocimientos de lo que se hacía ya tenían rendimientos similares.
En el vídeo se ve la evolución de un hack con entornos más cargados que los del juego original y con un motor gráfico que ya había sufrido multitud de mejoras y cómo tras aplicar un nuevo mogollón de optimizaciones el rendimiento prácticamente se ha duplicado.
Ya no es que el juego original pueda moverse a 60 fps, es que va a ir sobrado. Lo que ya no sé es si sería posible subirle la resolución desde los 256x224 a 320x240 (es un incremento del 33%). O aplicar filtrado trilineal. Tampoco parece que conserve ningún tipo de antialising.
----------------------
En otro orden de cosas, hace poco que
Olivieryuyu actualizó su blog donde describe el desarrollo de un microcódigo propio basado en el que usó Factor 5 y que él mismo destripó para poder emularlo en el plugin GlideN64:
https://olivieryuyu.blogspot.com/Es interesante ver los objetivos que se ha marcado al final del texto:
* Point lightingIluminación por píxeles en lugar de por vértices, que ofrecería unos degradados más naturales y unos efectos de luces en escenarios espectaculares.
* Triangle strips
Esto sirve para que los modelados ocupen menos en memoria. Los vértices que comparten toda la información se consideran como uno solo en lugar de tener un vértice por cada triángulo. Esto ya lo hace el Editor del GoldenEye, así que no sé si se refiere a otra cosa o si no estaba implementado en el microcódigo de Factor 5.
* "Texture rectangle" done by the mean of a triangle
A ver si alguen sabe a lo que se refiere con esto, porque a mi me suena a renderizar por quads.
* RDP displaylist (you simply don't process the RDP commands one by one in the RSP but you simply retrieve them from RDRAM and ship them directly to the RDP).
Alguien con más conocimientos del hardware que nos explique esto y qué implicaciones tendría, aunque suena a mejora en el rendimiento.
* Save the average of the Z of a triangle in a unused part of the RDP triangle command, send data to RDRAM, then the CPU would sort by Z the data and send to the RDP. We could get rid of Z buffer in this way.
Se elimina el Z-buffer y en su lugar se usa otro sistema más simple para ordenar los triángulos respecto a la cámara. No estoy muy convencido de cómo quiere hacerlo y sospecho que va a dar problemas con polígonos que se intersectan como por ejemplo el plano del agua del Mario 64.
* For special TRIs, check first if they are not trivially rejected before executing the rest of the command. Potentially to be done as well for TRI command
Suena a más mejoras de rendimiento
* Rewrite the organization of the microcode and the overlays. Currently we have no more IMEM space!
¿Qué era el IMEM? Me suena a que consiguiendo más espacio puede preparar al microcídigo para hacer más cosas chulas.
* Rejection instead of clipping as an option (with usage of precised clip ratio macro)
¿Esto se refiere al descarte de polígonos que quedan fuera del punto de vista de la cámara? Podría significar un nuevo paso en la optimización de la carga poligonal en pantalla. Pasaríamos de renderizar niveles enteros como en Mario 64, a renderizar los trozos del nivel que son visibles como en GoldenEye a finalmente renderizar sólo los polígonos en pantalla con este microcódigo. Suena demasiado bien.
* Finally port the ucode to libdragon, get rid of any reference to libultra
@conker64 ¿Esteríamos más cerca de tener un kit de desarrollo funcional y poder crear motores gráficos en 3d eficientes?
* Last but important thing: name the microcode 🙂
Avanza lento pero es apasionante.