- Este texto explica as técnicas de iluminação baseada em paleta e normal mapping aplicadas durante o desenvolvimento de uma demo para Nintendo 64
- Em vez de aplicar iluminação diretamente na textura em tempo real, ele apresenta uma forma de iluminar a textura inteira alterando apenas a paleta
- Também são usados vários métodos de otimização, como compressão de paleta para diffuse/normal e normal mapping em espaço de objeto
- Esse método é eficiente apenas para iluminação direcional e tem desvantagens como descontinuidades de sombreamento
- Na demo, vários elementos como reflexos/luz direta/luz ambiente são combinados de forma criativa para mostrar visuais impressionantes dentro dos limites do N64
Introdução e objetivos
- Este texto é uma continuação de um thread que começou no Bluesky e compartilha técnicas avançadas de iluminação usadas em uma demo para Nintendo 64 (Revision 2025)
- A demo inclui vários efeitos, como normal mapping com reflexos e iluminação refletida em tempo real; a música foi composta por noby, e a guitarra foi tocada por Moloko
A possibilidade de normal mapping no Nintendo 64
- Com base em experimentos de desenvolvedores homebrew como WadeTyhon e Spooky Iluha, o autor verificou a viabilidade de implementar normal mapping no N64
- O método básico consiste em calcular a iluminação diretamente na textura pela CPU em tempo de execução
- Mesmo sem suporte de hardware, é possível executar código de sombreamento personalizado na CPU, mas a queda de desempenho é grande
Sombreamento baseado em paleta
- Em vez de aplicar o sombreamento diretamente no espaço da textura, basta atualizar apenas os dados da paleta de uma textura paletizada para que a textura inteira reflita mudanças de brilho em tempo real
- Como o uso de texturas paletizadas é comum no N64, essa técnica pode ser aplicada com frequência
- Só de atualizar a paleta, já aparece imediatamente um efeito como se a iluminação real tivesse sido aplicada a cada texel
- A paleta original é substituída por uma paleta com sombreamento aplicado, e a textura paletizada existente é mapeada no objeto como uma textura normal
- Mesmo aplicando apenas iluminação difusa (
dot(N,L)), o resultado já é bastante impressionante
Normal mapping em espaço de objeto
- Em geral, normal mapping é feito em espaço tangente, o que é adequado para suportar texturas repetidas e corrigir superfícies de forma natural
- Em mapas normais em espaço de objeto, cada texel contém informações precisas da normal da superfície, então o cálculo é simples, mas fica difícil aproveitar texturas repetidas
- Mesmo comprimindo um mapa normal de alta resolução em uma paleta de 32 cores, ainda é possível manter características semelhantes às do original
Projeto de paleta compartilhada entre diffuse e normal
- O objeto possui uma textura diffuse (
basecolor * ao) e um mapa normal - As duas texturas são configuradas para compartilhar os mesmos índices de paleta gerados por um algoritmo de clusterização K-means
- A clusterização é feita tratando a imagem como uma imagem de 6 canais
- No exemplo, o diffuse RGB + mapa normal são comprimidos em uma paleta de 16 cores, então os dados da imagem precisam registrar apenas 4bpp
- No sombreamento, para cada cor da paleta, as informações de normal e de cor da superfície são buscadas pelo índice para gerar uma nova cor RGB
- Esse método só consegue dar suporte adequado a luz direcional, e é difícil implementar sombras usando apenas a paleta
Luz ambiente direcional / luz solar pré-assadas
-
Para obter uma iluminação realista nos prédios, o RGB da cor de vértice e o canal alfa são usados respectivamente para luz ambiente e luz solar
-
A luz ambiente (ambient) é separada em intensidade direcional (environment map em escala de cinza) e cor (RGB, com saturação reforçada)
-
A luz solar (direct) é passada no alfa do vértice
-
A fórmula básica de iluminação é a seguinte
ambient = vertex_rgb * grey_irradiance_map(N) direct = vertex_alpha * sun_color * dot(N, sun_dir) color = diffuse_texture * (ambient + direct) -
Cada um desses termos se combina para formar a cor final
-
A luz ambiente direcional produz um efeito de luz natural encorpado e, mesmo sendo baseada em paleta, entrega uma aparência de alta qualidade
-
Para simplificar, o environment map usa projeção equiretangular
Sombreamento de modelos grandes com texturas repetidas
- O algoritmo inicial era para um único objeto, e uma grande malha de castelo apresentou problemas por usar texturas repetidas
- Para resolver isso, o autor usou o Blender para dividir a malha em submalhas de acordo com a direção da superfície e o material
- O computador calcula uma matriz world-to-model para cada grupo usando a normal do polígono, formando um espaço tangente aproximado
- Cada grupo compartilha uma única paleta, o que garante uma qualidade média de iluminação no conjunto
- Como o espaço tangente não é interpolado em tempo de execução, existe a desvantagem de aparecer uma iluminação com aspecto facetado
Sombreamento especular
- Como vários pontos da superfície compartilham a mesma cor de paleta, não é possível fazer sombreamento especular ou de point light com precisão
- A técnica em espaço de paleta é eficiente apenas para iluminação difusa direcional
- Ainda assim, assumindo um objeto esférico, o autor força um efeito de reflexo especular aproximando cada ponto como
p = radius * normal - O resultado é um tanto descontínuo, mas durante o uso real pode parecer bastante natural
Limites e futuro
-
Na demo, o autor escondeu o máximo possível limitações como descontinuidades de sombreamento, suporte apenas a texturas em preto e branco e falta de suporte a point lights
-
Um preprocessing elaborado é indispensável
-
Encontrar uma forma de suportar tanto luz ambiente quanto luz direta sem descontinuidades de sombreamento ainda continua sendo um desafio
-
O autor destaca o interesse das novas possibilidades e ideias reveladas pelo experimento
-
O arquivo ROM de N64 compatível com PAL também foi disponibilizado. Porém, é instável e trava com frequência
Outros
- O autor também considera escrever um livro; se houver interesse, é possível receber novidades aqui
1 comentários
Comentários do Hacker News
Comentário dizendo que ver gráficos “realistas” no N64 é uma experiência realmente impressionante, e que esta demo passa uma sensação que lembra "ICO" do PS2. Também compartilha curiosidade sobre a possibilidade de criar um SDK que abstraia o hardware gráfico do N64 e ofereça primitivas modernas, iluminação, sombreamento, ferramentas de baked lighting etc. Menciona ainda que o hardware do N64 tinha uma estrutura única, característica daquela geração, e fornece um link com informações detalhadas sobre o hardware
Menciona que o N64 foi projetado pela SGI e o quanto a SGI influenciou os gráficos 3D. Supõe que o N64 talvez tivesse, na verdade, o hardware mais padronizado da geração, e que seria até surpreendente se não existisse uma biblioteca OpenGL. Aponta como desvantagem o fato de que o console precisa ser visto como uma placa gráfica com uma CPU acoplada, com o sistema gráfico exposto de forma direta. Explica que as arquiteturas dos chips gráficos não são compatíveis entre si, que os fabricantes evitam divulgar essas estruturas internas e oferecem apenas APIs como OpenGL e DirectX, o que permite projetos criativos, mas torna muito difícil o acesso direto ao hardware. Como contexto adicional, lembra que o OpenGL se originou na SGI e que a nvidia também foi fundada por pessoas vindas da SGI
Menciona "Shadow of the Colossus..." e compartilha um link relacionado no YouTube
Expressa admiração pelo fato de o texto principal sobre truques gráficos do N64 terminar com a pergunta “Isso é o futuro?”
Expressa admiração pela genialidade dos engenheiros de jogos, que encontraram soluções criativas em hardware limitado
Compartilha o princípio de que, quando há restrições, surge o mais alto nível de criatividade. Diz que esse é o segredo de pico8, Animal Well e vários jogos impressionantes. Lamenta que neste fim de semana teve uma grande ideia para melhorar bastante a arquitetura do seu 2d-pixel-art-game-maker-maker, o que provavelmente vai adiar o lançamento em mais um mês
Esclarece que o conteúdo apresentado desta vez não é da época de ouro do N64, mas uma criação recente
Observa que isso não vem de um desenvolvedor do N64 daquela época, e sim de uma nova tecnologia ligada à demoscene em 2025
Recorda que, embora hoje existam sistemas mais rápidos e isso seja ótimo, havia algo especial na diversão de superar limites nos jogos antigos e na satisfação de conseguir fazer isso direito. Explica que usuários do Hacker News provavelmente conhecem os conceitos de "raster interrupts" e "racing the beam", e conta um caso em que, no Atari 800, foi possível fazer o que parecia impossível usando essas técnicas. Diz que só recentemente percebeu o quanto os jogos de Atari 2600 foram influenciados por esse tipo de abordagem maluca, e compartilha material no YouTube. Mantém a convicção de que, mesmo que o avanço de hardware pare no futuro, ainda poderemos descobrir novos truques interessantes por décadas
Recorda a experiência de ter usado, nos anos 90, uma técnica de iluminação baseada em paleta em seu jogo shareware. Explica que a paleta VGA de 256 cores era organizada para que cada cor tivesse variações graduais de brilho, permitindo criar efeitos de luminosidade com facilidade apenas somando e subtraindo índices de cor
Observa que a demoscene e trabalhos como esse são admiráveis, mas parecem tender mais a cenas simples e vazias. Analisa que essas técnicas normalmente serviriam para cenários de fundo ou funcionalidades limitadas em jogos. Considera muito mais impressionantes tentativas como FastDoom ou os projetos de otimização de Mario 64, que aumentam bastante o desempenho em hardware antigo e ainda adicionam conteúdo e funcionalidades. Sugere que talvez exista uma ligação entre a demoscene e esses projetos mais completos
Sente saudade das técnicas de otimização da era PS1 e PS2. Diz que, mesmo quando a maioria desses jogos é emulada e ampliada para 1080p ou 4k, eles ainda parecem incríveis. Opina que os gráficos de Halo 2 em 4k já são suficientes, e cita como exemplo uma demo do efeito de “onda de calor” realmente criado em GT3, junto de um comentário do criador de que no PS3 isso não poderia ser feito tão rapidamente quanto no PS2. Acha que, em vez do efeito de calor realista de engines atuais como a UE5, é melhor um truque que não pese tanto no desempenho. Afirma que prefere os truques do passado a sofrer queda de frames por causa de RTX. Menciona o fato de jogos impressionantes como Shadow of the Colossus, GoW2, FFXII, GT4, Black, Valkyrie Profile 2, Rouge Galaxy, Burnout 3, Jak and Daxter e Ratchet rodarem em uma CPU MIPS de 299 MHz, além de citar RE4, Metroid e Zelda no GameCube. Termina com uma expressão de admiração e respeito pela habilidade dos desenvolvedores de jogos tradicionais
Aponta que o vídeo de GoW2 foi capturado no emulador PCSX2 e provavelmente recebeu upscale e outros aprimoramentos. Ainda assim, considera GoW2 no PS2 uma conquista enorme
Concorda sobre o PS2, mas acha que o PS1 tinha desempenho apenas mediano. Opina que o desempenho do PSX ficava no nível de um Pentium 90~100, mas que um Pentium MMX com uma 3DFX se igualava ou superava o N64. Cita PSP, SGI Irix e PS2 como exemplos de CPUs MIPS entregando ótimo desempenho em clocks baixos. Explica que a GPU do PS2 era separada da CPU R4k, e compartilha a experiência real de que o port de Deus Ex para PS2 ficou aquém da versão de PC e não conseguiu dar conta completamente da Unreal Engine. Como contexto adicional, menciona que o PS2 mostrava efeitos especiais impressionantes, mas que em ports como Deus Ex os mapas eram muito pequenos
Defende a opinião de que os gráficos de Halo 3 parecem melhores do que os de jogos atuais. Acha que efeitos adicionados hoje, como blur, bloom e grama e folhas sendo lançadas para longe, acabam produzindo uma experiência visual pior. Diz que, em FPS de ritmo rápido, contagem fina de polígonos não importa muito, e que a resolução de textura apenas precisa ser suficiente. Compartilha a experiência pessoal de que, no fim, o que se percebe de verdade são as exigências de hardware