Hilo de detalles y curiosidades de N64

@Conker64
Esto es una extracción de la caverna que aparece en el menú. Hay otras habitaciones que no están conectadas físicamente. Unos 9k polys tiene el export.
Imagen

Aquí se puede ver el clásico efecto de reflejo antes de que los cubemap y el raytracing vinieran a atormentarnos.
Imagen

Dentro de la taberna si tomamos, si posicionamos la cámara en la entrada y descartamos los polys que no tocan, se nos quedan en unos 4200:
Imagen

Después hice una captura nada más empezar el juego, en esta posición:
Imagen

Prácticamente todo el nivel se manda al RSP, no parece haber mucho o ningún culling antes (la escena entera son unos 3600 triángulos):
Imagen

El modelo de Conker son 844:
Imagen

El modelo utilizado para su sombra son 131:
Imagen

La sombra parece funcionar proyectando un cubo sobre el escenario (desde el foco de luz en dirección a la posición de Conker) y generando nueva geometría en los puntos de corte, una cámara renderizará el modelo de la sombra desde la posición desde donde se proyecta ese cubo a una textura que luego se aplica sobre esa nueva geometría generada.

La escena inicial parece renderizar unos 1900 polys:
Imagen

@Sogun Curiosamente implementé ese método en mi homebrew aquí lo explico brevemente (https://youtu.be/BvG-71v-b0o?t=30) También funciona en N64 aunque el video es de la versión de hace un año (https://youtu.be/NFK9DnI3cPk?t=53).

Básicamente funciona como has mencionado, puedes agrupar texturas en filas, columnas o ambas siempre que el número de estas sea 1 o una potencia de 2. Por ejemplo puedes agrupar 4x4 quads, el sistema generará una única textura para la 4x4, cuatro texturas para el primer agrupamiento (2x2) y luego 16 texturas individuales (en el caso de que fuesen todas diferentes). Después el sistema morphea del de 4x4 al de 4x(2x2) y luego al de 16x1 dependiendo de la distancia a la cámara, el morphing se hace en screen space y también se hace morphing de los colores de los vértices. En Jak & Daxter esas agrupaciones se pueden hacer por triángulos también, en el caso de CTR solo para quads y con la única combinación de 2x2.

Como comentaste te quita la gestión manual de los mipmaps (en 64 lo gestiona el sistema solo, pero así tampoco tienes que usar ningún bloque de la cache con eso).

También te permite descartar grandes polígonos de golpe (puedes determinar si por ejemplo un 4x4 no está mirando la cámara y hacer backface culling de 16 polígonos de golpe, lo mismo para el frustum culling)

Aunque hay también un gasto extra por el morphing que en otros juegos no se haría.

En cuanto a datos del CTR, al parecer lo que más consume del juego es la IA de los enemigos. En el modo free-roaming he capturado unos 2500 triángulos:
Imagen

Dentro de carrera solo he llegado a ver 2000. Una cosa interanste es que la gente que está trabajando en el dcomp al parecer tienen una versión que corre a 60 en hardware real: https://www.youtube.com/watch?v=d9psliWJ0es&ab_channel=Darkaiser pero no he podido comprobar su veracidad.
Misscelan escribió:Esto es una extracción de la caverna que aparece en el menú. Hay otras habitaciones que no están conectadas físicamente. Unos 9k polys tiene el export.
Imagen


Ah sí, la habitación de arriba creo que es la de Berri, Conker llama desde la taberna en la intro, siempre me ha encantado eso de poner diferentes estancias y luego desplazar la cámara para hacer el cambio de escena.
Imagen

La entrada que pones de la taberna, creo que era uno de los picos de geometría de esa escena, en su momento jugué con el debug activado durante largo y tendido (aunque se colgaba), y si mal no recuerdo ese momento funcionaba sobre los 17-20, 20 es bastante común en los puntos de estrés, aunque fluctúa como una montaña rusa.
Imagen

EMaDeLoC escribió:¿Pero sí estaban seguros de que podían optimizar el código, porqué no lo optimizaban desde el principio?
A mí me suena más a marketing. En plan "mira el juego que hemos hecho en PS1 y solo hemos explotado 3/4 de su potencial!! eh! eh! mira aquí, a la PS1!! no, no mires la N64!! Aquí, la PS1!"


No sé, puede ser lo que comentas pero yo lo veo bastante común, mis códigos a lo largo de los años cada vez han ido a mejor, más pequeños, más flexibles, más rápidos.. si tengo que montar ej. un plataformas normalmente me leo algo que ya haya hecho, como hice el motor de tiles, como interactúan los sprites con esos tiles para hacer las colisiones, las cuestas e inclinaciones.. y normalmente es en ese momento cuando me pongo a retocar.

Luego por otro lado si tienes fechas que hay que cumplir, se te puede encender la bombilla, pero muchas optimizaciones requieren cambios en muchas partes, como no estés fino y te olvides de algo viene la catástrofe, a veces es mejor eso de que si algo funciona no lo toques.

Suena raro, porque ahora te sacan los juegos rotos sin optimizar y lo hacen al final, pero antes no podías cargarte toda la producción de cartuchos o CDs por ello, optimizar puede traer errores.

Yo creo que cuando hablan pueden referirse a esto, o ser puro humo como comentas, a veces es en los siguientes juegos de la misma plataforma cuando se aplican esas mejoras y deberían ir mejor / verse mejor, o similar, aunque no siempre es el caso, o no siempre son el mismo equipo y la cosa se cae.

O´Neill escribió:@Conker64 podéis hacer un hilo con ese tipo de información (cantidad de polígonos que sacaban estás consolas ps1,Saturn,n64, dreamcast,etc)?

Me parece interesante ver lo que realmente sacaban estás máquinas y lo que nos vendían las compañías, aún recuerdo la publi de ps2 y sus 75 millones de polígonos xD


No sería mala idea, en su momento tenía pensado algo así, en models resource se pueden conseguir muchos modelados y visualizarlos con blender, para escenas y datos reales ya haría falta más análisis, más gente que participe.

Los modelados a partir de cierto nivel dejan de tener sentido, de 1000 a 10000 las diferencias son enormes, de 10000 a 20000, ya se reducen y así, pero de la generación 32bit a la 128bit es cuando se produjo todo ese maravilloso salto. (esta imagen es un clásico de internet, como gol de señor, pero sirve)
Imagen

Lo de los 75 millones también me suena haberlo leído, ahora no recuerdo que Hobby Consolas fue, pero era entre el 2001 y el 2002, con una comparativa de todas las "128bit".

De hecho llevé la revista al instituto y todos quedaron maravillados con PS2 y esos números, se acompañaba una captura del Tekken Tag, en un escenario lleno de césped, que comparado con las 4 hojas que te ponían las 32/64bit parecían trillones, nadie dudaría de esas cifras.

Sogun escribió:Otra prueba que hice fue comparar el rendimiento de los niveles vacíos de GoldenEye en ambos motores gráficos. Se movían básicamente igual, normalmente a 30 fps y bajando a 20 en los mismos sitios. Había zonas en las que en GE bajaba a 20 pero PD se mantenía a 30, y otras zonas donde pasaba al revés. Especialmente curioso el caso del final del nivel de Bunker, la zona exterior donde acaba el nivel. En GE se mueve a 60 fps si no miras a la puerta del bunker, pero en PD en todo momento funciona a 30 fps. Es como si GE sólo tuviera en memoria los trozos de nivel que se ven directamente (y está cargando y descargando parte del escenario constantemente) mientras que PD además gestiona trozos del escenario cercanos aprovechando que usa más RAM (se ve que para ayudar en la descompresión de datos).


Me suena que vi un vídeo donde se eliminaban muchos elementos de las fases de Goldeneye, se dejaba solo el escenario y luego se medía el rendimiento, no sé si se puso aquí o lo vi yo por casualidad en Youtube.

Pero esa parte del Búnker que comentas salía y iba a 60.
@Misscelan
Dentro de ps1 el motor que más me impresionó ha sido el de Spyro que mueve unos 2000 polys (algo más de 3000 triángulos), algunos son sin textura pero a una resolución horizontal de 512px


Hay muchos juegos cañeros @512x240 en PlayStation; los Spyro que comentas, los Tobal, Crash Racing Team, Rapid Racer, incluso Soul Edge:

Imagen

Éste además es 1 portento en todos los campos; transparencias, fuentes de luz, polycount, texturas, etc.

Saturn cuando se pone tonta te planta entrelazados de hasta 704x448i, la mayor parte de veces en juegos de lucha eso sí, entornos que como tú bien has dicho son más controlables para el programador. Astra SuperStar (2D) te planta hasta 640x224 en progresivo si no recuerdo mal:

Imagen

También me consta que a la Saturn conviene más ponerla @352 horizontales que @320 porque en este último se underclockean los SH-2 de 28 a 26 Mhz, sabe Dios porqué.

En cambio Nintendo 64 es aún un misterio para mí. O sea me consta que al igual que las otras su resolución "de confort" es 320x240p (352 en Saturn), pero más allá de ese ratio estoy perdido, y además me rayan cosas como ésta:

@Sogun
NTSC 440x330 "progresivo" con antialising


En referencia a la resolución intermedia en GoldenEye: 007.

Sí de verdad es cierto, entonces sería imposible de ver en los CRT de consumo en la época, ya 440x330p sería un rango de 24khz, y por ello necesitaría mínimo de un monitor trifrecuencia para poder visionarse, similar los que calzan las placas MODEL de SEGA (496x384).

¿Alguien me da un tour rápido de resoluciones en N64?
Nadie dice que saturn y playstation no metan 640x224, pero n64 lo hizo con todo un perfect dark.

Y la ampliación de memoria... pues bueno, la podias dejar en 8MB porque la podías dejar en 8MB, si no pudiera ampliarse si que sería una pega.
@Sexy MotherFucker
A nivel de código que es lo que yo controlo, te puedo decir que 440x330 sería el framebuffer y luego eso lo envías a VI (Video Interface), que se hace allí? Bueno basándome en los datos que hay (ultra64.ca):

42 Video Display Modes
The VI is responsible for displaying the RDP-rendered images in different video modes. Currently, VI supports 42 video display modes -- 14 for NTSC, 14 for PAL, and 14 for MPAL. Each mode contains different settings to handle attributes such as interlaced and non- interlaced, 16-bit and 32-bit color pixel, and low and high resolution. Furthermore, a mode can be configured to rescale the image to sacrifice resolution for rendering speed.

These supported modes can be represented by 5 switches:

high/low resolution
16-/32-bit color pixel
anti-aliased/point-sampled
filtered/not filtered
NTSC/PAL/MPAL format


Yo aquí veo 2 modos de vídeo, high y low resolution, según el documento:

Low
In low resolution (320 pixels by 240 lines), you have a choice between non-interlaced and interlaced mode. Non-interlaced mode repeats the same frame each field. Interlaced mode interpolates between adjacent lines, weighting 75% of the line above plus 25% of the line below in the first field, and then weighting 25% of the line above plus 75% of the line below in the second field. Note that there is no flicker because there are no high spatial frequencies.


High
In high resolution (640 pixels by 480 lines), you have a choice between normal interlace and deflickered interlace. Normal interlace uses just the data rendered in one field to display that field. This mode can use one high resolution frame buffer without additional double buffering because one field can be displayed while the next is being rendered without stepping on each other. However, any single pixel with high detail will flicker because it is only displayed in one field. Deflickered interlace averages adjacent lines to filter out the high frequency vertical detail, but at the cost of requiring double buffering of the entire high resolution frame because both rendered fields are used to display each field.


Da la impresión de 240p y 480i, luego configuras la interfaz para redimensionar el framebuffer o dejarlo tal cual si llena la pantalla, o con marcos negros si no queda muy lejos del target, además puedes establecer su posición, a partir de donde empieza a pintarse, para centrar imagen como hacen los Quake desde el menú.

Más info, de una entrevista de Nintendolife:
"The N64 has two possible output formats: 240p and 480i," Bartmann explains. "The most common rumour is that 240p is 320x240 pixels and 480i is 640x480, but that’s not true for 240p. If you take a look at Perfect Dark (NTSC version), in the menu you have the option to switch between high resolution mode and low resolution mode. However, the output is always 240p. So, what changes? Just the horizontal resolution, or not? The N64 has a constant pixel clock of about 12.5MHz in each possible resolution. So what’s going on here is 240p low resolution mode is 320x240, 240p high resolution mode is 640x240, and 480i is 640x480 – the horizontal resolution split in two frames, each frame with 640x240 – even and odd; that’s interlaced."

That's where Deblur comes into play. "What the N64 simply does in the 240p low res mode is that the console outputs 640x240, where in the horizontal direction every second pixel is a 'true' or 'useful' pixel and every other one just an interpolated version of the neighboured pixels," continues Bartmann. "This results into a blurry picture. However, if one blanks these interpolated pixels and simply holds the previous 'true' pixel, you can effectively "deblur" the image. The true challenge is to detect whether the 240p content is low res or high res.


Si hay más dudas (o errores en lo que pongo) creo que @radorn y @EMaDeLoC controlaban sobre este tema.

--
@Señor Ventura
No preocupare, estás en el hilo correcto ;)
@Señor Ventura pero no son los 640x480i que tú decías, sólo quise corregirte éso. Bueno y también decir que en modo "hi-res" Perfect Dark se asfixia en muchísimas zonas, yo habiéndolo jugado en hardware real no sacaría pecho por ello...

En cambio @320x240 (218 en realidad) va decentemente.

Nintendo 64 es una máquina de 240p, asúmelo de una vez. Puede hacer sus "pinitos" en pseudo-hires como PlayStation con los Spyro, o Saturn con sus juegos de lucha 3D, pero enseguida la realidad las golpea diciéndoles que están volando demasiado lejos de casa, que aterricen antes de quedarse sin combustible. Lógicamente al ser más potente que las otras logra surcar un par de KM más, pero sigue sin ser capaz de cruzar el océano entero sin agotarse. N64 es una máquina de la misma generación que PlayStation, de la misma forma que Neo Geo era de la misma que SNES, MD, o PCE.

Ésta:

Imagen

Sí es una máquina de 480p.
Sí pertenece a otra generación distinta.
Dreamcast hace realidad con creces todo lo que tú sueñas que a lo mejor puede hacer Nintendo 64; da la vuelta al mundo volando más alto.

Cómprate una N64 y JUEGA por Dios. Opina en base al planeta Tierra 🌍 No opines desde Marte xD

Y la ampliación de memoria... pues bueno, la podias dejar en 8MB porque la podías dejar en 8MB, si no pudiera ampliarse si que sería una pega.

Pero no se si pillas que no es algo opcional: sin Expansión no hay campaña en PD. Tú no puedes jugarla en una N64 de stock, tal cual. Tienes que doparla, al igual que pasa con ciertos títulos de Saturn.

Zelda Majora's Mask y DK64 directamente no encienden sin élla. En la época te obligaban a invertir en el pack de memoria si querías jugarlos.

@Conker64 gracias por responder tan rápido.

Según esos documentos... ¿Lo que haría el VI sería escalar y estabilizar un ratio a priori incompatible, haciéndolo compatible con los viejos CRT?
Eh, eh, yo soy un usuario de ultra 64, igual que todos los demás: tengo derecho a soñar.

Si, tendré mi n64 en un mueblecito, hay consolas que hay que probar, como la 3ds. No te lo pueden explicar, lo tienes que experimentar.

...pero es que no he dicho que 480i sea lo justo para perfect dark, solo he dicho en que contextos estas máquinas se atrevían con resoluciones mayores. No le pones un perfect dark a 640 vertical a cualquiera (¿640 entonces, pero menos resolución horizontal?).


No se, los pies los mantengo en el suelo, pero no queremos ser realistas, queremos pushing.

Me gustaría saber como rendiría una n64 sin postprocesos a 480i reales y 30fps estables, ¿con que tralla en pantalla?. ¿Ves?, no tiene nada de malo pensar estas cosas... es FE, si, pero también es sano.
No se muy bien qué puedo aportar aqui. Pero comentaré alguna cosilla a ver qué sale.

Como alguna vez expliqué, la N64 tiene un bus de audio y video con una frecuencia fija cercana a los 50MHz que es ligeramente diferente en las tres "regiones' de la consola (NTSC, MPAL y PAL). Digo bus AV porque tanto el bus de audio como el de video están alimentados por el mismo reloj. En cuanto al bus de video, se transmite un pixel cada cuatro ciclos de reloj (R G B y uno extra para sincronización y otras señales auxiliares que nunca llegué a entender). Esto resulta en un pixel clock cercano a 12.5Mhz. Calculando desde esa cifra redondeada, dividiéndola entre el refresco horizontal nominal de PAL y NTSC, no saldrían unos 800 y 794 pixels por linea. Tendría que ponerme a hacer calculos mas precisos con las frecuencias reales y datos a los que no tengo acceso, pero el concepto sería el mismo.
De todos esos pixels, según me dijo marshallh en su día, autor del 64drive y UltraHDMI, 640 pixels son visibles.
Eso es lo que se transmite ente el VI dentro del RCP al DAC SIEMPRE. Obviamente, cómo rellene esos pixels el VI según esté programado ya es otra cosa.

Yo nunca había oído eso de los 42 modos de video soportados por el VI. Yo entendía que era programable. Quizá esos 42 modos de video son las combinaciones documentadas, y que no está necesariamente limitado a ellas ni es que las tenga integradas dentro.
Como comprobamos por estos lares hace unos años, las configuraciones del VI que traían los juegos NTSC que al aplicarse a una consola NTSC producían 60Hz, en una consola PAL acababan produciendo unos 61.X Hz, y viceversa, las configuraciones PAL en hardware NTSC resultaban en 59.x, o algo así. Y esas cifras eran consistentes con las diferencias de velocidad del bus en las distintas variantes regionales de la consola (existentes porque de ellas también se derivaba luego la frecuencia de la portadora de color para compuesto y s-video en el DAC). Eso me dió a entender que el VI era totalmente configurable por software y que de alguna manera, teniendo un pixel clock fijo, podía "cortarlo" en lineas y cuadros a placer (lo que no quiere decir que el DAC lo fuera aceptar, o que aún aceptándolo, la TV pudiera tragar con el resultado, pero esas son otras cuestiones)

Cuando tenía el hardware e investiqué estas cosas, nunca vi un solo juego que tuviese 640x480 (o 640x576 para PAL) "reales" o sea, que el framebuffer no era de ese tamaño si no menor y luego el VI lo estiraba.
Y al colación de esto mencionto también que si que creo que el VI puede estirar cualquier resolución de freimbúfer arbitraria a la pantalla, y no está limitada a "algunos modos fijos", y lo deduzco por mi esperiencia usando una funcionalidad que tiene el ActionReplay / GameShark v3.3. SI alguno lo teneis probad esto: Al cargar un juego, con o sin trucos activos, activad el cheat generator. Esta funcion carga un loader trainer que se engacha al loop general de libultra para ejecutar su propio código. Una de sus funciones es que al presionar el botón del cartucho, se congela la ejecución del juego y se abre un menú con herramentas de visualización de memoria y comparación de valores para hackear trucos. Pero además, tiene una funcion extra para visualizar la memoria de la consola como si fueran gráficos del framebufer. Lo que hace es pasar una sección de la memoria al VI para que la muestre con la misma configuración gráfica que tenga el juego. y permite avanzar y retrocder por toda la memoria, aplicando incluso los bit extra de la RDRAM para la segunda capa de antialiasing, lo cual refuerza mi teoría de que esta funcionalidad simplemente pasa la sección de memoria que le indiques al VI de forma directa. La otra alternativa sería escalado por software, y creo que eso iría lentísimo.
Con esta funcion, se pueden visualizar todos los framebufers que haya en memoria (tipicamente 2, el que ya está completo y el que se está dibujando, que, dependiendo de en qué momento detengais la ejecución al presionar el botón, encontrareis a medio dibujar, e incluso podeis ver el z-buffer como imagen, resultando en un mapa de profundidad un poco extraño, al interpretarse como RGB15 siendo internamente valores monocromáticos de 16bits. pero se reconoce la escena claramente.

La cosa es que este visualizador de "gráficos" permite variar la ventana grafica no recuerdo si usando qué botones del mando, pero efectivamente cambiabas el punto de inicio, la longitud de linea (o sea, cuantos bytes/pixels de la memoria encajas por linea visible del VI) y la escala vertical, y era totalmente lineal y sin retrasos, totalmente 60Hz, lo cual me sugiere que realmente se limitaba a cambiar los parámetros del VI para pasar memoria a este como si fuera framebufer.

Lamentablemente no os puedo hacer una demostración al no disponer de nada de aquello ya. Quizá haya en youtube algo. Buscad ActionReplay o GameShark "code generator" e igual encontrais algo. O compraos uno y trastead.
Si ademas disponeis de un PC viejo con puerto paralelo con Windows 98, Me, 2000 o XP (estos últimos con algún programa de apertura de puertos legacy, porque los cierran por defecto), podreis incluso durante la ejecución del juego, mandar un comando con las utilidades del aparato (si las podeis encontrar) o puede que hasta ucon64, capturar un dump del framebufer como un BMP (aunque solo el RGB15, sin la segunda capa de antialiasing del VI porque dpende del bit extra de la RDRAM y ese no lo lee el software de la CPU, o no sin procedimientos extraños que KazeEmanuar recientemente documentó y no entendí)

En fin, además de eso, como ya he dicho alguna vez, hay juegos que hacen cosas muy raras con las resoluciones.
Primeramente no recuerdo ver un solo juego que en su modo de video entrelzadao tenga una relación 1:1 entre el framebufer y la pantalla (o quizá uno raro de ajedrez con personajes feísimos en las animaciones de cada movimiento), en "todos" los que investigué puede apreciar "artefactos" del re-escalado, como los que se ve en la mayoría de juegos PAL a pantalla completa sin barras negras, que son mas borrosos que NTSC porque reescalan en bufer que en NTSC es 1:1 con la salida 240p, pero en PAL se estiran a 288p con una relación 5 a 6, o sea, que cada 5 lineas originales, se producen 6 en pantalla y se puede ver un patrón de colores mezclados con esa cadencia si haces una buena captura de video.
Ni siquiera los juegos NTSC con modos 480i tienen un búfer 640x480. Creo que hasta el libro de los bomber de Majora's Mask renderizaba a una resolución inferior, aunque quizá me equivoque en ese caso y solo sea la versión PAL...
AProvecho para recordar la breve lista de juegos PAL con auténtica resolucion 288p: GoldenEye, Perfect Dark, Diddy Kong Racing, y el prototipo de 40 Winks. No pude encontrar ninguno mas, ni si quiera de Rare o EuroCom. Todos los demás a pantalla completa reescalan.
Y un par de curiosidades: El primer juego de Goemon en la consola, la aventura 3d de mundo abierto, en su versión europea PAL, observamos el tipico reescalado de 240 a 288, lo normal. La versión americana NTSC es 240p 1:1, lo normal. Pero la versión NTSC Japonesa original... por alguna razón incomprensible, renderiza a 240p, pero lo reescala a 480i en VI, introduciendo borrosidad innecesaria sin ganar nada. Como nota a pie de esto, a veces me preguntosi hubiera sido beneficioso en algún juego PAL reescalar los 240p originales a 576i en vez de a 288p. Quizá hubiese sido menos borroso el resultado, aunque de un cierto flicker no nos libraba nadie. La otra curiosidad es que Body Harvest, ya sea PAL o NTSC, ni siquiera usa tiene unframebuffer 240p, si no inferior, y todas las regiones reescalan... bueno, nunca se me dió por probar la japonesa, si es que la hubo, pero la EuroPAL y la USANTSC reescalan las dos, así que no es ni 240p internamente.

Conker64 escribió:In high resolution (640 pixels by 480 lines), you have a choice between normal interlace and deflickered interlace. Normal interlace uses just the data rendered in one field to display that field. This mode can use one high resolution frame buffer without additional double buffering because one field can be displayed while the next is being rendered without stepping on each other. However, any single pixel with high detail will flicker because it is only displayed in one field. Deflickered interlace averages adjacent lines to filter out the high frequency vertical detail, but at the cost of requiring double buffering of the entire high resolution frame because both rendered fields are used to display each field.


Recientemente Kaze Emanuar me respondió a esta misma cuestión en los comentarios de YouTube
https://www.youtube.com/watch?v=BA_HMsz ... IX4AnOePJA
@radornkeldam 1 month ago
At 6:47 you say that some games RENDER in interlaced, so only half the lines (field) each time, but from what I understand, this just can't really be done, unless you can 100% guarantee you'll render the next frame by the time the video signal starts transmitting the next field. So games would need to render the full frame (640x480 or something else with scaling) and just drop half the frames to display the even or odd field the screen is synchronized to during the next slot.

If you only render the even or odd fields to save on render time and/or memory and your renderer misses the next screen refresh, you won't have the corresponding video information to fill those lines, and things will look really bad.

When I did have the console and a 64drive, I did some investigations and I don't recall finding a single hi-resolution interlaced game that rendered 1:1 with NTSC/PAL interlaced resolution. All of them rendered at some weird nonstandard resolution and then used the VI to scale the output so it filled the screen. For example, TUROK 2's famous fullscreen hi-rez mode with the expansion pak, renders to 4XX by 3XX and stretches that, like all games do, horizontally to 640, and vertically to 480i or 576i depending if it's NTSC or PAL.

On the topic of N64 video scaling, the usual third party and early first party PAL adaptation involved slower timings and/or black horizontal bars to compensate for the resolution difference between PAL and NTSC. Most first party titles and the third party ones that bothered with PAL fullscreen, went with stretching of the output, incurring in an extra layer of blur. Then there are a handful of British developed titles where the PAL versions do 1:1 rendering and displaying at 288p (Diddy Kong Racing, GoldenEye 007, Perfect Dark, and the 40 Winks prototype), and furthermore, there are oddball games, like Body Harvest which renders to a sub-240p framebuffer and stretches to fullscreen 240p for NTSC and 288p for PAL. Probably one of the blurriest games because of that. Or what about the Japanese release of the first Goemon game, the 3D roaming adventure, which renders to 240p, but scales it up to 480i for video output (USA release does the proper 1:1 rendering and display at 240p, and PAL just does the standard 240 to 288 stretch that most PAL fullscreen games do)

So anyway... RENDERING in interlaced... not unless you can guarantee 60 steady fps for NTSC or 50 for PAL. if you miss one single refresh without the corresponding framebuffer, you'll either have to repeat the last rendered frame that'd me 1 frame too old, and display it on the wrong lines, or use the last rendered frame for that field (even or odd) which would be 2 frames old and run the animation back, or, maybe, interpolate the lines of the last frame, which, now that I think of it, might be the best alternative, but wouldn't look too good anyway, and would be extra blurry, and I'm not sure if the VI would let itself be coerced into doing it.


@KazeN64 1 month ago
@radornkeldam Spooky Illuha has a REALLY cool tech for this! It's a bit complicated and too much to explain here right now, but it does solve this issue. But yo uare right that commercial games simply render the whole thing and only display half.


Intenté encontrar a esa persona que menciona y esa técnica maravillosa, sin éxito. No tengo ni idea de qué forma se puede renderizar en entrelazado 1:1 en un sistema que ni de coña va a rendir a 60Hz 480i (campos de 640x240) o 50Hz 576i (campos de 640x288) sin perder ni un frame/field. Por que en el momento en que pierdas un paso se va a notar graficamente. No se cómo se "soluciona" eso. No lo veo ni lo he podido encontrar.

Bueno, en definitiva. Desconozco el aspecto programático de cómo se hacen estas cosas en la consola, pero mi experiencia de mucho trastear con la consola durante años es que el VI lo aguanta todo.

Sexy MotherFucker escribió:Según esos documentos... ¿Lo que haría el VI sería escalar y estabilizar un ratio a priori incompatible, haciéndolo compatible con los viejos CRT?

Espero que lo que he relatado te aclare algo
radorn escribió:Intenté encontrar a esa persona que menciona y esa técnica maravillosa, sin éxito. No tengo ni idea de qué forma se puede renderizar en entrelazado 1:1 en un sistema que ni de coña va a rendir a 60Hz 480i (campos de 640x240) o 50Hz 576i (campos de 640x288) sin perder ni un frame/field. Por que en el momento en que pierdas un paso se va a notar graficamente. No se cómo se "soluciona" eso. No lo veo ni lo he podido encontrar.

¿Es posible que se trate del Driving Strikers que salió hace poco?



Según asegura su GitHub:
Full 480i TrueColor graphics at high framerates of up to 60 FPS without the expansion pak, extremely rare in N64 titles
@EMaDeLoC Madre mía... si que funcionan bien los buscadores. Kaze me dió bien el nombre, lo busqué tal cual, y no logré encontrar NADA. Que le diste al buscador para que te diera el resultado? xD

En fin, pues, viendo lo que dicen Kaze y el video ese, será ese juego, supongo. Si tuviera lo que solía tener, haría unas cuantas comprobaciones en hardware.
Lo que no tengo claro es si todo esto se debe a una técnica secreta que escapa a mi comprensión o simplemente ha optimizado el juego lo suficiente para garantizar no perder ni un solo refresco con un campo nuevo de forma consistente.

Normalmente, para garantizar consistencia en la secuencia de fotogramas cuando tu salida de video es entrelazada, lo que se hace es renderizar la imagen completa, y solo mostrar la parte correspondiente al campoo actual en pantalla que avanza y alterna campos sin compasión ni consideración hacia tus problemas de rendimiento. Si lograses renderizar a 480p o 576p a 60 o 50fps por segundo estarías perdiendo detalle en cada frame porque solo se mostrarían la mitad de las lineas. En N64 eso es casi imposible a no ser para un menú sencillo o algo así... Todos los juegos que ofrecen "alta resolución" en modo entrelazado renderizan muy por debajo de 480 o 576 y reescalan, pero en definitiva, hay una imagen progresiva detrás del refresco entrelazado, así que incluso si la imagen ha de estar en pantalla durante do o mas refrescos mientras se termina de renderizar el siguiente cuadro, siempre hay datos de imagen disponibles que son apropiados para ya sea el campo par o el impar. Pero si renderizas exclusivamente par o impar y pierdes un refresco de pantalla, que siempre conlleva cambio de campo, tienes un problema porque no dispones de información de imagen apropiada para el campo opuesto, y eso va a resultar en un renqueo de la imagen.

Ahora bien, si realmente puedes GARANTIZAR que siempre vas a tener un nuevo campo listo para el siguiente refresco de pantalla, entonces no hay problema... pero claro, en una plataforma como N64 eso es mucho decir.
O sea, por repetir: 640x240 @ 60Hz o 640x288 @ 50Hz... quizá la resolución horizontal puede ser menor.
Estará optimizadísimo el juego este para conserguir hacer algo así. Otra cosa no se me ocurre.

Kaze Emanuar en su respuesta parece dar a entender como que es una técnica especial, pero por mas vueltas que le doy no se me ocurre que podría ser, mas que optimización salvaje.

Sería interesante si alguien puede capturar video en bruto sin desntrelazar ni nada, por ver si incluso este juego en algún momento pierde el ritmo y se ve alguno de los tipos de renqueo que esperaría ver en ese supuesto.

Si renderizas en entrelazado esperando no perder nunca un refresco de pantalla, y resulta que si que lo pierdes, existen las siguientes posibilidades de cómo se podría proceder. Digamos que acabas de renderizar el cuadro-campo para lineas impares y no llegas a tiempo al refresco de pares:

1) No tienes Vsync y muestras las lineas del campo impar que ya tienes hasta que se completa el cuadro de pares y lo empiezas a mostrar a mitad de refresco, provocando efecto tearing, renqueo en la parte superior de la imagen e imagen correcta en la inferior.
2) Tienes Vsync y muestras las lineas del campo impar que ya tienes directamente, provocando un renqueo temporal en toda la pantalla.
3) Tienes Vsync y muestras una interppolación de las impares como si fuera campo de impares. Sería la opción mas optima dada la situación, pero tendría aspecto borroso y quizá un tanto extraño
4) Tienes Vsync y doble búfer y decides usar el cuadro-campo anterior, correspondiente a un momento temporal previo, pero que encaja en la zona de pantalla. Dependiendo de cuanto movimiento haya en ese momento puede no notarse o notarse y molestar muchísimo, con un renqueo aún mas brutal, con movimiento de avance y retroceso.
5) se podría combinar la omisión de Vsync con la interpolación de la opción 3.
6) dejar ese campo en negro o en blanco o en gris y darlo por perdido. Probablemente la peor opción, aunque me gustaría ver el resultado, en un CRT especialmente.

Alguna combinación mas se podría hacer, pero os dejo que os lo imagineis vosotros.

Igual lo que hace este juego es alguna de estas cosas, no lo se. No se me ocurre qué mas podría ser.

Aunque tiene efectos de partículas y todo, el entorno se ve bastante sencillote y las físicas algo "floaty", quizá sea ahí donde radica la optimización que le permite el rendimiento necesario para mantener los 60fps.

AÑADO: Le he dejado un comentario al autor del juego este preguntándole qué hace cuando se retrasa en un refresco de pantalla. A ver si nos aclara el tema
https://www.youtube.com/watch?v=xQ2lsyH ... ZGt4AaABAg
@radornkeldam 55 minutes ago
What do you do when you miss a screen refresh? Reuse the last field-frame corresponding to the other group of lines causing spatial judder? Reuse the previous field-frame that matches the odd or even field that's currently on screen, avoiding special judder, but causing temporal judder? You interpolate the previous field-frame to fill the current field to simulate a progressive frame? Something else?


Quizá ni siquiera renderize con un framebuffer 1:1 y haga escalado de campos...
radorn escribió:@EMaDeLoC Madre mía... si que funcionan bien los buscadores. Kaze me dió bien el nombre, lo busqué tal cual, y no logré encontrar NADA. Que le diste al buscador para que te diera el resultado? xD

Me acuerdo que vi el juego en un vídeo que mencionaban los 60fps en entrelazado, pero no recuerdo cual vídeo era ni tampoco me quedé con el nombre del juego... Pero como era de coches y fúbol, busqué "Rocket League n64" y me salió.
[qmparto] [qmparto] [qmparto]

Sobre como puede funcionar el 480i a 60fps o casi, no lo tengo nada claro.
No sé si mirando el código fuente se puede saber, supongo que si.
@radorn gusto en volver a leerte por estos lares [oki]

Tu sugerencia de coger nuestras consolas, atarlas en palos con alambre de espino, y después quedar en un descampado para darnos de hostias entre los foreros sigue inmortal en mi memoria XD

Respecto al tema, por más que os leo, lo que sigo interpretando es que el VI de la N64 es una "movida" que coge cualquier resolución entre 240 y 480, sea compatible o no con el monitor, sea real o estirada, y le pone un "parche" para que de el pego en pantalla.

Como cuando se te está acabando el gel de la ducha y tú lo que haces es echarle más agua a la botella haciendo espuma para poder seguir lavándote. Sabes que no es la misma calidad del gel original, pero da el pego.

Más o menos éso, o yo que sé [360º]
mmm... yo lo que he entendido es que cuanto mas te acerques a dibujar los 640 pixeles horizontales, menos va a emborronar. No es por el número de líneas.
El VI saca 640x480i o 320x240p.
Cuando es una resolución horizontal menor de 640, el VI puede meter una fusión leve entre un pixel horizontal y el siguiente, lo que da un efecto de desenfoque. Los cacharros que hacen deblur como el RGB de Tim alargan el primer pixel hasta el segundo, quitando esa fusión o desenfoque. Eso hace la imagen nítida.
Si no me equivoco esa fusión se puede desactivar, y creo que la información que ha aportado Conker64 lo respalda.

De todas lo que repito siempre: estos filtros de desenfoque funcionan estupendamente en un CRT. Elimina dientes de sierra y suaviza mucho el dithering de la consola. Quitar los filtros puede ir bien en una pantalla plana y los juegos 2D y algunos 3D, pero en otras ocasiones van fatal. Por ejemplos, los textos de los Zeldas te los cargas de esa manera.

Tengo una consola con el N64Digital, antes de pasar al RetroGEM. Tiene salida RGB, directa de digital, la más nítida que existe para la consola. Es un desastre. Vuelve un CRT en un monitor CGA de PC.

Si teneis CRT para la N64, aprovechadlo.
@EMaDeLoC ¿Consume recursos esa interpolación de la interfaz?.
@Señor Ventura Que yo sepa todo lo que hace el VI es inmediato y sin gastar recursos.
Piensa que hacer una fusión o media entre dos pixeles es muy sencillo matematicamente: sumas el valor de cada color y lo divides entre dos. En binario es aún más sencillo: sumas el valor y luego haces shift hacia la derecha (shift es desplazar los bits a un lado, descartando el último).
El VI es bastante tocho dentro del RCP, no me extrañaría que tuviese un pequeño circuito que hiciera esta operación directamente, además de cualquier otra como reescalar.
Sexy MotherFucker escribió:@radorn gusto en volver a leerte por estos lares

Tu sugerencia de coger nuestras consolas, atarlas en palos con alambre de espino, y después quedar en un descampado para darnos de hostias entre los foreros sigue inmortal en mi memoria

JUAS Bueno, yo ahora no tendría nada que llevar a ese épico enfrentamiento.

Sexy MotherFucker escribió:Respecto al tema, por más que os leo, lo que sigo interpretando es que el VI de la N64 es una "movida" que coge cualquier resolución entre 240 y 480, sea compatible o no con el monitor, sea real o estirada, y le pone un "parche" para que de el pego en pantalla.


EL VI, siglas de Video Interface, es el componente dentro del RCP que se encarga de coger la imagen terminada del framebuffer y generar la señal de video digital que luego consume el DAC para hacer su compuesto, s-video o RGB.
Es un componente programable y que puede hacer diversas operaciones por su cuenta CASI gratis, pero no del todo, si no por otra cosa, al menos por acceso a la RAM unificada. Debido precisamente a la RAM unificada, al VI se le tiene que decir dónde esta el Framebuffer en RAM, y, como me demostró mi experiencia con el Action Replay, puedes pasarle cualquier región de RAM, con su punto de inicio, formato de color, longitud de linea y número de lineas, parámetros de escalado, y lo sacará por la pantalla en el modo de video configurado.

Imagino que otros sistemas son mas rígidos y requieren una relación directa 1:1 entre el framebufer y el pixel clock de la interfaz digital de video, donde cada pixel del framebufer es un pixel en pantalla. Pero el VI de N64 puede hacer, hasta donde yo he podido ver, cualquier escalado arbitrario sin problema (si, incluso el framebufer puede ser inferior a 240p y el VI lo puede estirar, con o sin suavizado, sin problema... no es que sea algo recomendable, claro, por calidad visual)

La grandísima mayoría de juegos PAL que llenan la pantalla y no tienen barras negras usan el VI para estirar el framebufer pensado para 1:1 240p (que puede ser una resolución menor, pero con una relación 1;1 con la pantalla a 240p, o sea, alguna barrita negra, pero que también está en el original, como mario 64, que renderiza 237 lineas y deja 3 en negro incluso en NTSC) y las escalan a 288p, lo cual es una relación 5:6, o sea, que la mayoría de juegos NTSC 240p, en sus versiones PAL el VI estira cada 5 lineas del framebufer a 6 lineas de pantalla, con suavizado/emborronamiento... o lo que técnicamente se llama INTERPOLACIÓN: Es posible que en este hilo aún esté alguna imagen que quizá postease detallando este efecto. Por ejemplo, una comparativa de Smash Bros en la arena de Star Fox, que tiene el perfil inclinado del lomo del great fox superpuesto al fondo negro espacial, permitiendo ver claramente la escalera. En NTSC, que muestra el framebufer en pantalla en relación directa 1:1, se ve una escalera con antialiasing normal, regular. Pero en PAL, que toma ese mismo resultado del framebufer y lo reescala con el VI, cada 6 lineas se repite un patron bastante claro cuando lo ves, y puedes ver que algunas lineas son muy claras y otras un tanto mas borrosas, donde se nota que las lineas PAL son una mezcla de la anterior y la siguiente, en diversa proporción, en una progresión que se repite cada 6 lineas.

Una excepción que encontré en su dia era Body Harvest, donde se podía ver este mismo tipo de fenómeno incluso en NTSC. No se me ocurrió ponerme a contar lineas para discernir el patron y calcular la resolucón origianl del framebufer, pero es inferior a 240 tanto en NTSC como PAL, lo cual, pone a ambas en igualdad de condiciones y claro, de puestos a escalar y emborronar, gana PAL porque escala a una rejilla de mayor resolución, igual que pasa con muchos juegos hi-res entrelazados, que no renderizan a 480 internamente, si no algo inferior, y por no mover el mapa de memoria, renderizan a la misma resolución interna tanto en PAL como NTSC, y siendo ambos escalados, gana PAL en nitidez por ofrecer mayor resolución de salida, dando mas granularidad al proceso de escalado.
Ni Turok 2, ni ningún STAR WARS, incluído el Ep1 Racer, que yo recuerde, ofrecían 480p 1:1 sin reescalado por VI en NTSC.

Mientras que casi todos los PAL a pantalla completa 288p estiran y emborronan un poco el framebufer interno 240p (SI, INCLUíDOS LOS DE NINTENDO, como en los Zeldas), y es una desventaja, los juegos PAL en alta resolución entrelazada, dado que ni los NTSC tienen relación 1:1 entre framebufer y salida de video, los PAL ganan algo en nitidez comparados con NTSC, al menos teóricamente, pero probablemente se note poco. Luego está la comparación de si se hizo bien la adaptación a 50Hz para mantener el rítmo temporal del juego o no, pero eso ya es otro tema.

Y luego están los juegos milagrosos que mencioné ya mil veces: GoldenEye, Perfect Dark, Diddy Kong Racing y la beta de 40 WInks, los únicos ejemplos que encontré donde los desarrolladores (británicos en ambos casos, claro, Rare y EUROCOM) se preocuparon de hacer una adaptación PAL con renderizado interno a 288p para tener relación 1:1 con la salida de video PAL 50Hz y no tener que escalar y emborronar con el VI.

No recuerdo si investigué bien los juegos de Factor 5, que son también de tierra PAL, en Alemania (no?), para ver si renderizaban a 288p o no. Tras darme cuenta de que GoldenEye no mostraba el emborronamiento del reescalado 240p a 288p, me puse a buscar mas juegos desarrollados por grupos europeos, que tenían mas posibilidad de que los programadores se hubieran preocupado de darnos amor a los PALetos. No se si por entonces era consciente de que Fator 5 eran alemanes. De todas formas tengo un vago recuerdo de que esos también escalaban en PAL, pero ahora no estoy seguro.

EMaDeLoC escribió:El VI saca 640x480i o 320x240p.
Cuando es una resolución horizontal menor de 640, el VI puede meter una fusión leve entre un pixel horizontal y el siguiente, lo que da un efecto de desenfoque. Los cacharros que hacen deblur como el RGB de Tim alargan el primer pixel hasta el segundo, quitando esa fusión o desenfoque. Eso hace la imagen nítida.
Si no me equivoco esa fusión se puede desactivar, y creo que la información que ha aportado Conker64 lo respalda.


El VI siempre genera lineas con area visible de 640 horizontal. Cuando el framebuffer es de 320, o, en cualquier caso, inferior a 640, obviamente hace interpolación de valores, a lo que llamas "fusión leve". O sea, que los valores de color del pixel 1 y 2 en el frambufer pasan a ser los pixels 1 y 3 en la salida digital, y el VI genera un nuevo pixel 2 con un valor de color calculado como la media de los valores del 1 y el 3.
O sea, que cuando está estirando los 320 horizontales a los 640 fijos del bus de video, hace lo siguiente:
-Para el pixel 1 de la pantalla, cojo el valor del pixel 1 del framebufer y lo pongo tal cual
-para el pixel 2 de la pantalla cojo el valor del pixel 1 y el pixel 2 del framebufer, calculo la media y lo saco como pixel 2 de pantalla
-para el pixel 3 de pantalla cojo el pixel 2 del framebufer y lo paso tal cual.
Y así sigue hasta el final
Obviamente el proceso no es tan facil de descibir para "encajar", digamos, 400 de framebufer en los 640 de pantalla.

La cosa se complica cuando hay que hacer escalado vertical también, porque entonces hay que calcular combinaciones de colores entre lineas para generar los nuevos pixels de pantalla a partir del framebufer.

Mientras escribo esto me acabo de acordar de otra curiosidad que os animo a comprobar:
Uno de los ejemplos mas raros de salida de video que vi en N64 es la versión PAL de Automobili Lamborghini: El juego saca 288p a pantalla completa con estirado... Pero en vez de escalar con suavizado hace escalado INTEGER.
La relación sigue siendo 5:6, o sea, que cada 5 lineas renderizadas salen 6 en pantalla, pero en vez de hacer interpolación gradual como la mayoría de juegos, saca las 5 lineas originales en 5 lineas PAL directamente y para la 6 repite la 5 y punto pelota.
Eso se puede apreciar facilmente en pantalla como que cada pocas lineas hay una mas gruesa, doble.

EMaDeLoC escribió:@Señor Ventura Que yo sepa todo lo que hace el VI es inmediato y sin gastar recursos.
Piensa que hacer una fusión o media entre dos pixeles es muy sencillo matematicamente: sumas el valor de cada color y lo divides entre dos. En binario es aún más sencillo: sumas el valor y luego haces shift hacia la derecha (shift es desplazar los bits a un lado, descartando el último).
El VI es bastante tocho dentro del RCP, no me extrañaría que tuviese un pequeño circuito que hiciera esta operación directamente, además de cualquier otra como reescalar.


Come un poquito de tiempo extra porque tiene que interpolar entre lineas, lo cual supone aumentar el acceso a memoria, que ya sabemos que es un tanto... cabrona la RDRAM esta.

EL VI va leyendo de la RAM y serializando los datos e interpolando según sea necesario. Mientras que la interpolación horizontal la hace casi al vuelo porque ya tiene el pixel anterior y el siguiente en el registro interno, interpolar verticalmente implica leer de dos lineas del framebufer para generar la actual, y eso implica aumentar el número de accesos a RAM. Lamentablemente no es totalmente gratis. Aunque bueno, la diferencia de rendimiento es mínima
Lo que si es indudable es que al ser un componente independiente que funciona en paralelo, no depende de la CPU ni del RDP para sus procesos internos, O sea, no es escalado por software, que sería lentísimo, pero 100% gratis no es por culpa de los accesos a memoria unificada. Otra cosa sería si fuese un framebufer de RAM dedicada. Pero bueno,el impacto es muy pequeño
Entonces, se pueden obtener los postprocesos sin emborronamiento, a costa de:

-Resolución horizontal.
-Menos polígonos en pantalla, y menos texturización.


¿He entendido que la interpolación son solo pixels de cada scanline, y no scanlines entre si?.
Señor Ventura escribió:Entonces, se pueden obtener los postprocesos sin emborronamiento, a costa de:

-Resolución horizontal.
-Menos polígonos en pantalla, y menos texturización.


¿He entendido que la interpolación son solo pixels de cada scanline, y no scanlines entre si?.


No acabo de entender lo que planteas ni lo que preguntas. perdona.
radorn escribió:
Señor Ventura escribió:Entonces, se pueden obtener los postprocesos sin emborronamiento, a costa de:

-Resolución horizontal.
-Menos polígonos en pantalla, y menos texturización.


¿He entendido que la interpolación son solo pixels de cada scanline, y no scanlines entre si?.


No acabo de entender lo que planteas ni lo que preguntas. perdona.


Que a pesar de aplicar postprocesos, no obtienes emborronamiento de imagen si renderizas a 640 pixeles porque no hay interpolación.

¿Y que la interpolación es solo dentro de los píxeles de cada scaline, y no entre scanlines? (si renderizas usando solo 100 scanlines, ¿que pasa con la imagen?, ¿se estira e interpola?, o quedan bandas negras y ya).
@Señor Ventura Como digo, el VI es configurable, programable. Puedes decirle qué región de memoria leer y de qué manera, si usar interpolación o no, o, mas correctamente, qué tipo de interpolación (la técnica de poner un valor entre otros dos valores) usar. Porque interpolación de enteros es simplemente volver a usar el mismo valor anterior para el siguiente pixel, mientras que otros tipos calculan el valor que se "interpola" a partir de los valores adyacentes.

Cuando conviertes una linea de 320 a los 640 necesarios para llenar el bus de video, lo habitual que se hace es calcular el valor intermedio entre los dos, como explicó EMaDeLoC. Pero igualmente que haces eso puedes simplemente repetir el mismo valor durante 2 pixels en vez de solo uno y eso también es "interpolación" de tipo INTEGER / ENTERO, también llamado zero-hold o nearest-neighbor. Obviamente esto requiere muchos menos pasos y da una imagen con un aspecto mucho mas nítido a costa de la suavidad. Aquí ya cada uno decide qué le gusta mas en cada situación.

En el caso de los famosos parches anti-AA, de una misma pasada se cargaban dos o tres procesos de la consola.
El Antialiasing de la N64 se hace en dos pasadas: una pasada para los aristas "internas", que son donde dos triángulos adyacentes comparten vértices a nivel de modelo (no solo que estén en el mismo lugar, si no que sean el mismo vértice, usado para dos triángulos adyacentes). Este antialiasing lo calcula el RDP y lo dibuja al framebuffer, y una segunda pasada para aristas externas, que se habrían de "anti-aliasear" (aliasinar? aliasianar? hmmmm...) contra el entorno que tengan detrás. Esta segunda pasada la calcula el RDP en forma de 2 bits por pixel (4 posibles valores de 0 a 3) almacenados en el bit extra de la RDRAM de 9 bits porque normalmente los juegos renderizan en color de 16 bits, o sea 2 bytes de 8 bits por pixel, que nos da esos 2 bits extra. Estos valores representan una proporción de mezcla de color con el/los pixels adyacentes (nunca acabé de entender el proceso exacto). O sea, que cuando el VI está pasando por ese pixel, lee los bits extra y según el valor, mezcla la cantidad de color correspondiente de el/los pixel/s que rodean a ese en el actual, logrando un efecto antialiasing un tanto cutre a costa de mas borrosidad.
Si alguna vez os habeis preguntado por qué cuando se cruzan cosas en pantalla, hay una especie de hormigueo raro al rededor, es por esto. Por ejemplo, cuando algo queda cortado por el limite negro de la pantalla y parece que hay un hormigueo ahí, es por esta segunda mano de antialiasing..
Toda esta explicación viene a cuenta de que los parches anti-AA se basan en desactivar una configuración que desactiva a la vez, si no recuerdo mal, TODO el antialiasing (interno y externo) y la interpolación de video
A diferencia del de-blur de los mods de video digital actuales, que toman la imagen con AA interno y externo y substituyen los pixels impares resultado de la interpolación del VI con el color del pixel anterior.

Pero de vuelta a ese tema. Como te digo, tu puedes interpolar o no (o, como expliqué, interpolar de una forma o de otra), según programes el VI. No es una función fija del VI. No tengo confirmación de esto que voy a decir ahora, pero creo que puedes seleccionar independientemente el proceso de interpolado para la dimensión vertical y la horizontal.

En esta configuración también entra de donde hasta donde "proyectas" el framebuffer en pantalla, y como interpolas y qué haces el resto de las lineas... SI las dejas en negro, pues quedan las famosas barras. Imagino que se podrían llenar de algún color, o incluso crear marcos como los del SuperGameBoy. Pero esto ya es especulación por mi parte.

Con el VI puedes especificar el origen de los datos que toma de cualquier región de memoria. Cuantos pixels de origen por linea, como escalarlos/interpolarlos a los 640. Desde qué linea y pixel de pantalla empezar y donde terminar, Todo.
Es muy flexible, aunque posiblemente dificil de configurar. Recuerdo interesarme por los parámetros del VI para tratar de conseguir in efecto determinado y no logré deducir cómo funcionaban

Señor Ventura escribió:si renderizas usando solo 100 scanlines, ¿que pasa con la imagen?, ¿se estira e interpola?, o quedan bandas negras y ya

Por responder específicamente a esto. Puedes mapear esas cien lineas en la región que quieras de la pantalla y escalarla como quieras. El VI es flexible
El VI no impone una relación directa entre el framebuffer y la pantalla. Puede hacer lo que te de la gana. Algún límite habrá, imagino, pero en principio, lo que quieras. Podrías renderizar 123 x 456 y mapearlo a una región de 150x69 en la esquina inferior derecha de una pantalla entrelazada, por ejemplo. Por qué querrías hacer algo así? NO TENGO NI IDEA, pero creo que poder se puede.

AÑADO: Creo que otro ejemplo de uso del VI para escalar el framebuffer sobre la pantalla es cuando suenan las campanadas del Majora's Mask y se va reduciendo la imagen en pantalla. Creo que el juego sigue renderizando la escena 3D a un framebuffer 240p y usan el VI para hacer el efecto zoom. Una pista de que esto es lo que está pasando es que el aspecto de la imagen va cambiando con cada nivel de zoom ganando en nitidez pero con algunos defectillos raros. No es que cambie el tamaño de la ventana de renderizado.
radorn escribió:Yo nunca había oído eso de los 42 modos de video soportados por el VI. Yo entendía que era programable. Quizá esos 42 modos de video son las combinaciones documentadas, y que no está necesariamente limitado a ellas ni es que las tenga integradas dentro.


Sí, eso es, se refieren a presets disponibles en la librería en el momento de ese documento, luego a partir de ahí podrías tomarlo como referencia y crear uno que se adapte al juego.

radorn escribió:Cuando tenía el hardware e investiqué estas cosas, nunca vi un solo juego que tuviese 640x480 (o 640x576 para PAL) "reales" o sea, que el framebuffer no era de ese tamaño si no menor y luego el VI lo estiraba.
Y al colación de esto mencionto también que si que creo que el VI puede estirar cualquier resolución de freimbúfer arbitraria a la pantalla, y no está limitada a "algunos modos fijos", y lo deduzco por mi esperiencia usando una funcionalidad que tiene el ActionReplay / GameShark v3.3.


También es cierto, a VI de hecho le podrías mandar un framebuffer de 2x2 como de 1024x1024 (entero), que también sería capaz de adaptarlo a la salida de imagen, puede estirar como estrechar.

Hace unos años estuvimos tratando el tema para libdragon, resoluciones y el bug del modo NTSC al quitar el AA resample:
Imagen

Al final lo dejé, porque no tenía las herramientas para trabajar de forma segura, quizás en la nueva todo eso esté actualizado.
@Conker64 gracias por las confirmaciones [oki]

¿Sabrías decir si con el VI se puede hacer un mosaico en pantalla repitiendo el framebuffer? es una tontería que se me acaba de ocurrir, pero hasta podría tener utilidad para algún efecto
¿Y la idea del marco? Se puede definir un relleno para las áreas de pantalla que no quedan cubiertas por el mapeado del framebuffer, digamos que un color sólido diferente al negro, o quizá algo mas elaborado como un marco? Imagino que lo segundo será que no porque añadiría demasiada complegidad al VI y a la configuración para hacerlo funcionar, y requiriendo doble acceso a memoria para el marco y el FB.

¿Nadie tiene un GameShark Pro / Action Replay Pro (v3.3) para mostrar lo del visor de graficos?
Molaría ver la demostración de los framebufers, el zbufer y el escaladoextremo en tiempo real.
radorn escribió:¿Sabrías decir si con el VI se puede hacer un mosaico en pantalla repitiendo el framebuffer? es una tontería que se me acaba de ocurrir, pero hasta podría tener utilidad para algún efecto


Creo que el problema sería horizontal, verticalmente puedes hacer cambios a mitad de frame, con algunas limitaciones.

He encontrado un texto en n64brew sobre el bug de arriba (que repite horizontalmente):

If AA_MODE = 11 (resampling disabled), TYPE = 10 (16-bit), X_SCALE is 0x200 or lower, and H_START is less than 128, the VI generates invalid output, consisting of the first 64 pixels from the framebuffer from the current line, then 64 pixels of garbage, and these two repeat for the rest of each scanline. A common case where this can happen is NTSC units (where H_START is usually 96) with a standard framebuffer of 320x240 (X_SCALE=0x200). For this very common situation, the simplest workaround is to activate resampling.


No sabría decirte si trabajando con esos valores podrías conseguir el efecto, o si se me ha pasado por alto cualquier otro registro, hay todo tipo de detalles imprevisibles según como combinen los valores, pero lo dejo como duda.

radorn escribió:¿Y la idea del marco? Se puede definir un relleno para las áreas de pantalla que no quedan cubiertas por el mapeado del framebuffer, digamos que un color sólido diferente al negro, o quizá algo mas elaborado como un marco? Imagino que lo segundo será que no porque añadiría demasiada complegidad al VI y a la configuración para hacerlo funcionar, y requiriendo doble acceso a memoria para el marco y el FB.


Podrías dibujar bandas arriba y abajo, un marco completo no creo, según parece puedes cambiar de origen en pantalla activa, pero mantendría el incremento del scanline, hay que jugar con la posición de memoria del siguiente frame buffer.

bit 23-0 ORIGIN[23:0]: RDRAM base address of the video output Frame Buffer. This can be changed as needed to implement double or triple buffering.

Extra Details:

ORIGIN must be a multiple of 8 (i.e. ORIGIN[2:0] must be 0). Otherwise the VI output may be noisy, shifted, or weirdly interleaved.
You can change ORIGIN mid-frame during horizontal blank. Notice however that VI internally keeps the running offset in the framebuffer since the frame started (accumulating VI_V_SCALE for each scanline) and that offset is *not* reset when ORIGIN changes. So the new framebuffer will be sampled starting from the same byte offset that the previous framebuffer would have sampled at.


Igual lo mejor sería hacerlo directamente desde el RDP, con la escena 3D recortada en el centro.
@radorn Que barbaridad, me va a costar asimilar todo eso. Por el motivo que sea, nunca me empapo sobre nada de n64.

Es todavía mas compleja de lo que pensaba.
@Señor Ventura la versión simplificada del VI es que puede mapear el framebufer a una región de la pantalla con total libertad de dimensiones, posición, modos de escalado, etc...
No puedo hablar con total conocimiento de causa de cómo funcionaban otros sistemas contemporáneos como PS1, SAT, 3DO, etc, pero imagino que operaban de una forma bastante mas directa, donde el homólogo del par VI-DAC tendría una serie de modos fijos de funcionamiento y un lugar específico de una memoria de video dedicada donde poner el framebufer que tendría que ser de las dimensiones exactas para el modo de video seleccionado.
Repito que en estos casos tengo muy poca información y tengo que especular bastante y ante mi falta de hardware no me voy a poner a investigarlo, pero lo mas probable es que no sean tan flexibles como el VI de N64.
@radorn a ver si termino de pillarlo: el VI es una suerte de escalador del Framebuffer, y otras movidas, pero principalmente "agrandador" o "achicador" con precisión por pixel de la imagen que la N64 escupe en pantalla, totalmente bajo el control del programador, aunque también puede ir en modo "automático".

¿Progreso adecuadamente, profe? [360º]

Señor Ventura escribió:Es todavía mas compleja de lo que pensaba.


Pues el día que te metas a estudiar la CPU de Ps2 te da 1 yeyo xD
@Sexy MotherFucker El VI es el encargado de producir la señal digital de video a partir del contenido de la memoria (preferentemente el framebuffer actual :cool: ), y siempre tiene que estar configurado/programado para leer de donde sea que el juego almacene el FB en la memoria unificada, ya que se puede poner en cualquier lugar y no hay una localización por defecto definida por el hardware.
Teniendo en cuenta además que la mayoría de juegos usan double-buffering (y se supone que alguno triple?) algún mecanismo tiene que haber para que el VI lea del FB terminado y no del que aún se está cocinando. No se si es que hay que darle configuración nueva encada refresco o se puede informar al VI de donde están ambos FBs y simplemente indicarle cuando cambiar de uno a otro. Quizá @Conker64 tenga la respuesta.

El escalado (estirar y achicar) se hace al vuelo durante cada "escupitajo" (por usar tu terminología xD). No se almacena el resultado otra vez en RAM para luego ser leido otra vez para salir por pantalla, si no que va saliendo directamente al DAC a medida que el VI procesa el FB.

Las funciones de escalado siempre están en uso, incluso cuando parecería que no hace falta. Consideremos el caso del tipico juego 320x240 NTSC (no PAL, para saltarnos el escalado vertical de 240 a 288). Aún en este caso, en la gran mayoría de juegos, el escalado suavizado está activo para adaptar los 320 horizontales del FB a los 640 visibles del bus de video, INTERPOLANDO pixels nuevos entre los originales, haciendo la media entre ellos.
También se podría hacer interpolación de enteros y simplemente repetir un miso pixel dos veces, sin hacer medias ni suavizados ni nada (interpolación "sin interpolación", por usar lenguage de andar por casa), pero la mayoríade juegos hacen lo primero, y por eso los mods de video modernos incluyen el famoso DeBlur, pensado para juegos con 320 horizontales que hacen interpolación, que son la mayoría.
En otras situaciones hace tareas de escalado mas cercanas a lo que tipicamente se considera escalar, como es el caso de estirar los 240p de framebuffer de la gran mayoría de juegos PAL a los 288p necesarios para la pantalla (un paso que no sucede en las versiones NTSC, claro). O como Body Harvest, que como ya dije varias veces, renderiza bastante por debajo de 240 tanto en NTSC como PAL y encarga al VI que llene la pantalla con eso.

Viendo cómo os está costando asimilar esto, ahora entiendo porque a pesar de que muchas veces señalé lo de los juegos PAL superadaptados (GE, PD, DKR, 40W), a casi nadie parecía importarle xD

O sea, que el VI no es que sea un escalador: Es la Video Interface, Interfaz de Video, se encarga de producir la señal de video en digita que luego el DAC la "analogiza". Como parte de ese proceso, tiene la capacidad de hacer escalado al vuelo con parámetros arbitrarios a elección del programador. Estira, achica, interpola... trocea, pica, muele, bate...

Con lo de "ir en modo automático" no tengo claro del todo qué quieres decir. Si te refieres a que si el hardware tiene una configuración por defecto si no le das una tu, lo dudo. Asumo que el hardware siempre va a requerir que se le de una configuración de manera explicita. El único "automatismo" que se me ocurre sería que el SDK con el que programes la consola traiga una configuración por defecto para el VI sin que tengas que definir una nueva. Pero en este caso estaríamos hablando de un atajo práctico para el programador, no de algo inherente al hardware.
Es curioso y vídeo lo que habéis explicado que algún juego no ocupe pantalla completa, como por ejemplo el Beetle aventure, salvo por o bien desconocimiento de los desarrolladores o bien problemas de rendimiento.
No es que sea inabarcable entenderlo, pero que van saliendo detalles con los que no contaba.
sgonzalez escribió:Es curioso y vídeo lo que habéis explicado que algún juego no ocupe pantalla completa, como por ejemplo el Beetle aventure, salvo por o bien desconocimiento de los desarrolladores o bien problemas de rendimiento.

Si pudiera le echaría un vistazo, pero solo puedo hablar de lo que recuerdo. El BAR tenía un área visible con marco negro todo al rededor, verdad? Seguramente los desarrolladores redujeron el area de pantalla por rendimiento, y no quisieron llenar la pantalla mediante escalado por VI para no indicir en la borrosidad. Si hubieran reducido mas las dimensiones de renderizado probablemente habrían hecho lo mismo que Body Harvest, estirando a pantalla completa desde un framebuffer tan reducido que sería inaceptable usarlo a escala 1:1 en pantalla porque dejaría mucho espacio vacío
Yo diría que encontraron un punto medio para obtener un rendimiento aceptable sin reducir la resolución tanto como para tener que recurrir a estirados borrosos por VI.

Por cierto que el BH no hace estirado para todo. La intro y la pantalla de título van a 320x240 nativos sin escalado extra (bueno, al menos la versión NTSC... no recuerdo si la PAL hacía 288p nativos o 240p estirados), pero une vez inicias el juego, la resolución de renderizado se reduce considerable y el VI la estira a pantalla completa. Es un juego muy borroso gracias a esto. Si además usase el extraño estilo de renderizado de StarFox y MIssion:Impossible (y algún otro) ya sería el acabose.


-----------------------------------------------------------------------------------------

@Conker64 @EMaDeLoC @Sexy Motherfuker @Señor Ventura
Spooky Illuha respondió: https://www.youtube.com/watch?v=xQ2lsyH ... ZGt4AaABAg

@radornkeldam
What do you do when you miss a screen refresh? Reuse the last field-frame corresponding to the other group of lines causing spatial judder? Reuse the previous field-frame that matches the odd or even field that's currently on screen, avoiding special judder, but causing temporal judder? You interpolate the previous field-frame to fill the current field to simulate a progressive frame? Something else?

@Spooky Iluha
It uses the previous field frame that matches the oddness, I haven't seen any issues with it on CRT

@radornkeldam
Thanks for taking the time to answer
I guess it may not be too bad for such a small playfield and more or less 60fps. Did you try interpolating between lines to create a false opposite-oddness field? I don't know how the VI is programmed, so I don't know if it will easily acommodate this, or at all, but sounds like it might be the best solution. But if nobody has noticed any judder, I guess it's OK, at least for this particular game.
It might have been more noticeable in a game with more sweeping camera movements and ampler playfields.

-------

This just occurred to me:
Let's say you are trying to render the next field-frame for the odd lines, and you miss the vsync, so you drop that and display the previous odd-line buffer you had from before (I guess this means you keep double buffer odd and even separatelly too? four buffers overall? or maybe three: one of last odd, another for last even, and one for rendering). Now you've wasted the whole last refresh trying to render a field-frame that won't fit the next refresh because the screen will be asking for the even-line field-frame again. What if you also miss that vsync? I guess at some point you have to preemptively skip rendering for the next field-frame and go for the one after to try not to miss it again? Do you do that right away the first time you miss a vsync? Or something else entirely?


Así que básicamente renderiza campos de XXXx240 y si se retrasa y pierde la ventana de vsync antes de completar el nuevo cuadro-campo, usa el buffer anterior que corresponda al campoo par o impar que haya de ser mostrado en pantalla en ese momento... Supongo que eso significa que mantiene al menos tres bufers en memoria, uno para cada campo (dos en total) y uno donde renderiza, y el rol de cada búfer va rotando según sea necesario.

También me pregunto, como le cuento a Spooky Illuha, qué pasa si pierde dos vsync consecutivos. con un framebuffer progresivo, si pierdes un vsync, o dos, o tres, lo único que pasa es que acumulas retraso, pero no tienes problema en mostrar el framebuffer en cualquier refresco de pantalla una vez termines de renderizar, porque es progresivo. Pero si pierdes un vsync en renderizado entrelazado... la cosa se complica.
Digamos que se está mostrando en pantalla el campo par, mientras renderizas un cuadropara el campo impar, pero no llegas a tiempo. Ahora el cuadro que estabas renderizando ya no te vale para el siguiente refresco porque es para el campo opuesto. OK Spooky Illuha dice que reusa el framebuffer anterior para ese campo, que asumo por contexto que aún conserva en RAM y, según él dice, no supone ningun problema apreciable en un CRT. OK... pero entonces qué hace con el campo que estaba renderizando? sigue renderizándolo y lo muestra en el siguiente refresco aunque no corresponda con el tipo de campo? lo deshecha y vuelve a empezar con un campo que corresponda al siguiente refresco? y si pierde ese también? Quizá si pierde un refresco, desista de intentarlo para el siguiente y apunte directamente al de después?
Renderizar en entrelazado es una complicación...
Quizá me esté liando y no sea capaz de ver la obvia solución sencilla con precio aceptable, pero por lo pronto, el padre de la criatura ya me ha confirmado que, efectivamente, no tiene una solución perfectamente limpia para el supuesto de perder un refresco de pantalla.
@radorn Si que es bastante lioso, pero tiene pinta que precisamente se busca el objetivo de 30fps mínimo para evitar problemas.
El juego parece tener la geometría bien medida para evitar exceso de polígonos y de fillrate, aprovechando al máximo el ancho de banda de la memoria. Por ejemplo si varios polígonos comparten textura, se envía todos esos polígonos de una vez, cargando así la textura en la TMEM solo una vez. Por supuesto eso requiere de maña diseñando el escenario de forma que los polígonos de textura compartida se puedan agrupar (suelo, pared, etc).
Si procuras que tu peor escenario de renderizado, es decir ver todo el mapa más los jugadores más efectos, etc, te permita renderizar un poco por encima de 30fps, en teoría te puedes olvidar de perder la vsync dos veces (equivaldría a ir a 15fps).

Lo he probado un poco, va muy fluido. Excepto un momento puntual al principio rinde los 60fps. El entrelazado es notorio por HDMI, no me he puesto a toquetear opciones del mod ni tampoco conectarlo a un CRT, que seguro que lo disimulan mucho.
El sistema de ajuste de exposición me parece que no funciona bien o falta algún ajuste. Va saltando un poco según el contenido del frame. Cuando acaba de cargar el mapa todo se ve blanco hasta que lo ajusta. A veces el suelo, de roca negra, parece brillar. Yo no me habría complicado tanto poniendolo para obtener resultados irregulares, pero claramente esto es más una demostración técnica más que un juego completamente pulido.
La verdad que es bastante impresionante el resultado. Le falta algo de complejidad poligonal pero es normal para poder trabajar a 60fps.
@radorn [tadoramo]

Gracias por tu esfuerzo trayendo información de calidad. Con el tiempo me estoy planteando hasta coger apuntes de todo este hilo y hacerme una carpeta.

Realmente de los mejores hilos del subforo en toda la vida de EOL.
@Sexy MotherFucker Estas informaciones era bueno ordenarlas y ponerlas en el wiki, este o algún otro, pero yo no se editar wikis y la verdad es que da pereza. No se tampoco si el wiki de EOL recibe mucho uso.
radorn escribió:@Sexy MotherFucker Estas informaciones era bueno ordenarlas y ponerlas en el wiki, este o algún otro, pero yo no se editar wikis y la verdad es que da pereza. No se tampoco si el wiki de EOL recibe mucho uso.


¿Y si se acude a la IA?, ¿esas cosas leer un hilo entero página a página?.
@Señor Ventura Ni se cómo ni tengo ganas de meterme en algo así. Si tu sabes del tema, adelante y a ver qué sale, pero sospecho que el resultado dejará bastante que desear, con alucinaciones y conclusiones dudosas por todas partes, y habrá que revisarlo de arriba a abajo. Quizá me equivoque, pero en fin, esa es mi predicción.
radorn escribió:@Señor Ventura Ni se cómo ni tengo ganas de meterme en algo así. Si tu sabes del tema, adelante y a ver qué sale, pero sospecho que el resultado dejará bastante que desear, con alucinaciones y conclusiones dudosas por todas partes, y habrá que revisarlo de arriba a abajo. Quizá me equivoque, pero en fin, esa es mi predicción.


Es que no todas las ias sirven para lo mismo, yo ni idea tampoco... pero de momento la información ahí está, que no es poco.
3736 respuestas
171, 72, 73, 74, 75