2 puntos por GN⁺ 2025-05-19 | 1 comentarios | Compartir por WhatsApp
  • La demo de Nintendo 64 para Revision 2025 logra efectos cercanos a normal mapping, iluminación bakeada y especular en tiempo real al actualizar solo la paleta, sin recalcular toda la textura
  • Cuando la CPU lee la normal y el color difuso en cada índice de paleta y crea una nueva paleta RGB, la textura paletizada reacciona como si hubiera recibido iluminación por texel
  • La textura difusa y el normal map comparten los mismos índices de paleta, generados agrupándolos como si fueran una imagen de 6 canales mediante K-means clustering de scikit-learn
  • La iluminación de los edificios combina el color ambiente en RGB de vértice, la visibilidad del sol en el alfa de vértice, un irradiance map gris y dot(N, sun_dir) para la luz solar direccional
  • Funciona bien para luz difusa direccional, pero tiene fuertes limitaciones con sombras, luces puntuales, especular precisa y modelos grandes con texturas repetidas, por lo que hay que ocultar sus límites con preprocesamiento

Sombrear actualizando solo la paleta

  • La demo de Nintendo 64 fue creada para Revision 2025 y usa efectos cercanos a iluminación bakeada, normal mapping y sombreado especular en tiempo real
  • En N64, el normal mapping ya era conocido como posible gracias a experimentos homebrew previos, y esta demo optó por calcular en runtime no la textura, sino la paleta con el resultado de iluminación
  • Sin soporte de hardware dedicado, se puede ejecutar código de shading arbitrario en la CPU, pero la velocidad de cálculo es baja
  • En una textura paletizada, basta con cambiar solo la paleta, no todos los texels, para que toda la textura parezca haber recibido el cálculo de iluminación
    • La paleta original se reemplaza por una paleta sombreada
    • La textura paletizada se aplica al objeto como una textura normal
    • Incluso con una simple luz difusa dot(N,L), el resultado se ve bastante bien
  • El ejemplo inicial deshacía la corrección gamma de la textura de color para sombrear en espacio lineal, pero en la demo final no se pudo aplicar porque los términos de ambiente y luz directa debían separarse y componerse por hardware en la unidad RDP del N64

Normal mapping en espacio de objeto

  • El normal mapping habitual se realiza en espacio tangente
    • Permite usar texturas repetidas
    • Puede corregir normales de vértice que varían suavemente mediante normales de detalle
    • Un normal map en espacio tangente de un solo color representa una superficie lisa
  • Las normales en espacio de objeto simplifican el cálculo, pero imponen muchas restricciones
    • Los texels del normal map representan la normal absoluta de la superficie, no una desviación respecto de la normal de vértice
    • El cálculo en runtime se reduce a algo tan simple como leer un color de la textura
    • Cada punto de la superficie necesita un texel único, como en un lightmap

Paleta compartida entre textura difusa y normal map

  • El objeto tiene tanto una textura difusa basecolor * ao como un normal map
  • Ambas texturas comparten los mismos índices de paleta, generados con K-means clustering de scikit-learn
    • Las imágenes se interpretan como una sola imagen de 6 canales
    • Con un único índice se pueden obtener tanto la normal como el color difuso de la superficie
  • En el momento de carga, o en cada frame, se recorre el color de la paleta
    • El código de shader en CPU crea un nuevo color RGB para cada índice
    • El resultado del bucle se convierte en la nueva paleta con iluminación aplicada
  • En la práctica, este enfoque encaja mejor con la iluminación direccional
  • Como solo con la paleta es difícil representar efectos como sombras, debe combinarse con iluminación bakeada

Ambiente direccional bakeado y luz solar

  • Para dar una iluminación más realista a los edificios de la demo, se guardan por separado el ambiente y la luz solar directa en los colores de vértice
    • RGB de vértice: color ambiente
    • Alfa de vértice: visibilidad del sol
  • El término ambiente se divide en intensidad direccional y color
    • La intensidad direccional es un irradiance map en escala de grises
    • El color es el RGB de vértice con mayor saturación
  • El sol es una luz direccional, y la visibilidad se transmite mediante el alfa de vértice
  • La fórmula de sombreado es la siguiente
ambient = vertex_rgb      * grey_irradiance_map(N)
direct  = vertex_alpha    * sun_color * dot(N, sun_dir)
color   = diffuse_texture * (ambient + direct)
  • Los colores de vértice sucios de visibilidad solar quedan enmascarados por el cálculo N.L, por lo que aparecen más limpios en el resultado final de luz directa
  • El ambiente direccional puede verse sofisticado gracias al detalle de la textura, aunque la iluminación bakeada sea tosca
  • Para el mapa de entorno borroso se usa equirectangular projection por su simplicidad
    • Los HDRI de Polyhaven ya usan esta proyección
    • Como el sombreado se precalcula en el momento de carga, la matemática compleja de muestreo no resulta un problema

Manejo de modelos grandes con texturas repetidas

  • El algoritmo de sombreado original fue diseñado para un solo objeto, y al principio solo se probó con potato_rock.obj
  • La malla del castillo de la demo tenía texturas repetidas, lo que generó problemas
  • La solución alternativa consiste en dividir la malla grande en varios submeshes y hacer que cada submesh comparta conceptualmente el mismo normal map en espacio de objeto
    • En Blender se agrupó manualmente la geometría según el material y la orientación de la superficie
    • Se calculó una matriz world-to-model a partir de las normales de los polígonos de cada grupo
    • Esta matriz se aproxima a un espacio tangente rudimentario
  • Como cada grupo comparte la paleta, la iluminación total solo es correcta en un sentido promedio
  • El espacio tangente no se interpola en runtime, por lo que se ve como iluminación por cara, y ese es uno de los mayores defectos de la técnica

Aproximación del sombreado especular

  • Como varios puntos de superficie comparten el mismo color de sombreado, es difícil calcular con precisión luces puntuales o sombreado especular
  • El enfoque en espacio de paleta encaja bien con la iluminación difusa direccional, que no necesita el vector to camera V
  • El efecto especular se intentó aproximando el objeto como una esfera
    • Se toma el punto a sombrear p como p = radius * normal
    • Como muchos puntos de la superficie comparten el mismo índice de paleta, el resultado inevitablemente se ve facetado
  • Los highlights especulares de la demo se veían algo raros, pero funcionaban lo suficiente como para engañar a la mayoría

Limitaciones y material relacionado

  • En la demo se intentó ocultar las limitaciones principales mediante preprocesamiento y composición de la escena
    • Discontinuidades de iluminación y rango de representación

      • Solo se admiten texturas en escala de grises
      • No hay luces puntuales
      • Esta técnica solo es práctica con un preprocesamiento cuidadoso
      • La técnica de Spooky Iluha no tiene problemas de discontinuidad de iluminación, pero no se sabe si puede resolver el mismo problema conservando tanto el ambiente como la luz directa
    • ROM e investigaciones anteriores

1 comentarios

 
GN⁺ 2025-05-19
Opiniones de Hacker News
  • Ver gráficos realistas en la N64 es realmente impresionante, y esta demo me recuerda a "ICO" de PS2.
    Desde hace tiempo me preguntaba si sería posible crear un SDK que abstraiga el hardware gráfico de la N64 y ofrezca primitivas modernas, iluminación, sombreado y herramientas para precalcular la iluminación, como en esta demo.
    La N64 tenía un hardware bastante único para su generación, y hay más detalles en Copetti.org: https://www.copetti.org/writings/consoles/nintendo-64/

    • La N64 fue diseñada por SGI, y considerando la influencia de SGI en los gráficos 3D, diría que la N64 probablemente era lo más cercano al hardware estándar de esa generación.
      De hecho, me sorprendería un poco si no tuviera una biblioteca OpenGL.
      Pero hay una salvedad importante: 1) este sistema debe verse como una tarjeta gráfica con una CPU pegada, y 2) el sistema gráfico está expuesto directamente.
      La arquitectura de los chips gráficos al final tiende a convertirse en un desastre sucio e incompatible, así que los fabricantes de aceleradoras suelen preferir publicar APIs intermedias como OpenGL, DirectX, CUDA o Vulkan, en vez de documentación de referencia.
      Eso les permite mantener la implementación interna en una estructura incompatible. Si no publican documentación de referencia, tampoco necesitan preservar compatibilidad hacia atrás a nivel de hardware; la ventaja es que pueden crear diseños nuevos, pero la desventaja es que casi nadie puede usarlos directamente.
      Por eso, cuando se obtiene acceso directo como en las consolas de esa generación, la reacción instintiva es espantarse.
      Además, OpenGL salió de SGI, y Nvidia también fue fundada por exingenieros de SGI.
    • También me recuerda a Shadow of the Colossus: https://www.youtube.com/watch?v=xMKtYM8AzC8
  • Me gusta que un artículo sobre trucos gráficos de la N64 termine con la pregunta "Is this the future?".

    • Hoy en día, la escena de desarrollo indie para N64 ha crecido de forma absurda, y la plataforma está muy activa.
      Una docena de juegos populares fueron descompilados a archivos fuente legibles [1], lo que facilitó hacer ports a PC sin emuladores y permitió muchísimos mods que corren en el hardware original.
      También hay varios remakes de fans de Zelda [2], e incluso juegos completos con nuevos calabozos e historia.
      El lado de Mario 64 está especialmente encendido: Kaze optimizó el juego a fondo [3] y también está creando su propio motor y una secuela. Si te gustan los análisis técnicos retro profundos, su canal es una verdadera mina de oro.
      También han aparecido demos disparatadas como Portal [4], que lamentablemente atrajo la atención del equipo legal de Valve.
      Juegos perdidos como Dinosaur Planet de Rare también, tras filtrarse, fueron pulidos hasta quedar casi listos para lanzarse, descompilados y están viviendo su propio renacimiento indie [5].
      [1] https://wiki.deco.mp/index.php/N64
      [2] https://m.youtube.com/watch?v=bZl8xKDUryI
      [3] https://m.youtube.com/channel/UCuvSqzfO_LV_QzHdmEj84SQ
      Todo el canal es excelente, y tiene decenas de análisis profundos como este: https://m.youtube.com/watch?v=DdXLpoNLywg
      Su juego y su motor también son hermosos: https://youtu.be/Drame-4ufso
      [4] https://m.youtube.com/watch?v=yXzoZ2AfWwg
      [5] https://m.youtube.com/watch?v=s0QSiPRmWaI
  • Cada vez que veo lo ingeniosos que eran estos ingenieros de juegos, me sorprendo.
    Con restricciones enormes, lograban soluciones imaginativas y excelentes.

    • Las restricciones exigen y generan una creatividad extraordinaria.
      Ese es el secreto de pico8, Animal Well y muchísimos juegos sorprendentes.
      Ojalá no se me hubiera ocurrido este fin de semana una estructura mucho mejor para mi herramienta de creación de juegos 2D con pixel art. Ahora parece que el lanzamiento se va a retrasar otro mes :(
    • Esto no es una técnica usada en la época dorada de la N64, sino un trabajo nuevo.
    • Los ingenieros de entonces seguramente también eran increíbles, pero esto, como se indica, es trabajo de 2025 y está más cerca de la demoscene que del desarrollo de juegos.
  • Me alegra que ahora tengamos sistemas más rápidos, pero en los juegos antiguos había algo divertido en tener que esquivar las limitaciones, y cuando salía bien la satisfacción era enorme.
    Los lectores de HN seguramente estarán familiarizados con las interrupciones de raster (https://en.wikipedia.org/wiki/Raster_interrupt) y el beam racing. Personalmente, siempre lo asocié con la Atari 800.
    En teoría no debería poder hacerse algo como https://youtu.be/GuHqw_3A-vo?t=33, pero gracias a las Display List Interrupts era posible.
    Lo que no sabía hasta hace poco era cuánto dependían los juegos de Atari 2600 de este tipo de locura: https://www.youtube.com/watch?v=sJFnWZH5FXc
    Ver cosas así me hace pensar que, aunque el avance del hardware se detuviera, podríamos seguir descubriendo cosas más interesantes durante décadas.

  • La demoscene y este tipo de trabajos son impresionantes, pero en general parecen tender hacia escenas más simples y vacías
    Se acercan más a algo que podría formar parte de un fondo de juego o de una mecánica de juego. Con la mayoría de las técnicas, se siente como si no hubiera recursos suficientes para crear una experiencia completa
    Lo más impresionante es el trabajo de exprimir mucho mejor rendimiento de hardware antiguo, como FastDoom o varios proyectos de optimización de Mario 64
    A veces lo hacen incluso agregando contenido y funciones. Me pregunto si habrá algún punto de conexión entre los desarrolladores de la demoscene y estos trabajos más integrales

  • En los juegos shareware de los 90 se usaban técnicas similares de iluminación basada en paleta
    Básicamente, al configurar la paleta VGA de 256 colores, se incluía para cada color soportado un gradiente de N niveles de brillo de ese color
    Así se podía cambiar fácilmente el brillo de cada color con solo sumar o restar al índice de color

  • Extraño la optimización de la época de PS1 y PS2
    La mayoría se ve increíble si los subís por emulación a 1080p, 4K o más. En lo personal, con ver gráficos de la época de Halo 2 en 4K me alcanza
    Claro que Halo 2 es un juego de Xbox, pero si jugás Halo 2 en Halo MCC con los gráficos clásicos, todavía se ve sorprendente
    El efecto de reverberación por calor de GT3 lo resume bien
    "En la demo de GT3 mostraban el circuito de Seattle al atardecer, y había una escena en la que el calor subía desde el suelo y ondulaba. En PS3 no se puede recrear ese efecto de reverberación por calor. Es porque read-modify-write no es tan rápido como cuando se usaba la PS2. Hay cosas así."
    https://old.reddit.com/r/ps2/comments/1cktw88/gran_turismos_...
    https://youtu.be/ybi9SdroCTA?t=4103
    No intentaba emular ondas de calor reales como los motores nuevos tipo UE5, sino que lo resolvía con un truco para no destrozar la tasa de cuadros. Sinceramente, viendo cómo RTX recorta mucho el framerate, prefiero estos trucos baratos
    Un MIPS a 299MHz corre esto
    Shadow of the Colossus: https://www.youtube.com/watch?v=xMKtYM8AzC8
    GoW2: https://youtu.be/IpKLwIIdvuk?si=TjifKmlYsUuvhk0F&t=970
    FFXII: https://youtu.be/NytHoYOs_4M?si=jE1Fxy40khEvV6Bn&t=51
    GT4: https://www.youtube.com/watch?v=F6lZIxk_h9g (me emocioné al ver la pantalla de arranque)
    Black, RenderWare era un motor demencial: https://youtu.be/bZBjcwyq7fQ?si=Pev5ifpksJm4X6Oi&t=356
    Valkyrie Profile 2: https://youtu.be/9ScjO4NuUtA?si=Z29cR-hLsT2pnP2I&t=38
    Rouge Galaxy: https://youtu.be/iR1evzyl-7Q?si=fldm3-NnuFxOITMn&t=624
    Burnout 3: https://www.youtube.com/watch?v=_r5r0nE1sA4
    También están Jak and Daxter y Ratchet
    Del lado de GC, RE4, Metroid, los Zelda, etc., obviamente se ven tremendamente bien
    Te dejan de rodillas

    • Sobre PS2 tenés razón, pero con PSX es más discutible
      Podía competir con un Pentium 90, casi 100, pero un Pentium MMX con 3DFX habría aplastado a PSX y habría sido igual o mejor que N64
      La CPU MIPS es excelente y logra cosas sorprendentes incluso con clocks bajos. Basta ver la PSP o SGI Irix
      Además, la "GPU" de la PS2 no es lo mismo que una CPU R4k
      De paso, el port de Deus Ex para PS2 era pésimo comparado con la versión de PC y no podía manejar del todo el motor Unreal
      Es cierto que la PS2 lograba efectos increíbles, pero en ese port los niveles eran realmente chicos. También hay que tener en cuenta que una gran parte de Deus Ex era casi de mundo abierto
    • Todavía pienso que Halo 3 se ve mucho mejor que algunos juegos modernos
      El blur, el bloom y el pop-in del pasto y la vegetación en realidad no se ven bien; se ven peor que simplemente desactivarlo todo
      En un shooter en primera persona de ritmo rápido, tampoco entiendo qué sentido tiene usar modelos con muchos polígonos si ni siquiera hay tiempo para apreciarlos
      Para mis ojos, la resolución de texturas de Halo 3 es suficiente. No creo que notara si las texturas fueran 2 o 4 veces más grandes; lo único que se notaría serían los requisitos de hardware
    • Decir "un MIPS a 299MHz corre esto" solo es cierto hasta cierto punto
      El video de GoW2 fue capturado en PCSX2, y es muy probable que en ese clip se beneficiara del escalado y de otras funciones de comodidad
      No vi todos los demás videos, pero de todos modos lo que GoW2 logró en PS2 fue impresionante