1 pontos por GN⁺ 2026-02-09 | 1 comentários | Compartilhar no WhatsApp
  • Um projeto que implementa sombreamento 3D em tempo real no Game Boy Color, no qual o jogador pode manipular a trajetória da luz e rotacionar o objeto
  • Com base no cálculo de vetores normalizados e sombreamento de Lambert (produto escalar / dot product), simplifica os cálculos usando coordenadas esféricas
  • Para superar as limitações da CPU SM83 sem instrução de multiplicação, usa transformação logarítmica e tabelas de consulta para realizar operações com precisão de 8 bits
  • Usando código auto-modificável (self-modifying code), alcança cerca de 10% de ganho de desempenho e renderiza 15 tiles por quadro
  • O uso de IA para geração de código falhou na maior parte, e o algoritmo principal e o shader foram concluídos com código manual escrito diretamente pelo autor

Visão geral do projeto

  • Criação de um jogo que renderiza imagens em tempo real no Game Boy Color
    • O jogador controla uma luz em órbita e gira o objeto
  • Todo o código está disponível no repositório do GitHub (nukep/gbshader)

Processo de criação em 3D

  • O desenvolvimento visual inicial (lookdev) foi feito com Blender, e como o resultado ficou visualmente satisfatório, o projeto seguiu adiante
  • Com Cryptomatte e um shader personalizado, foi gerado um normal map
    • No modelo do bule (teapot), a câmera foi rotacionada para exportar o normal map como uma sequência de PNGs
    • A parte da tela do modelo do Game Boy Color foi renderizada em uma cena separada e depois compositada

Base matemática

  • O normal map é usado como um campo vetorial que codifica o vetor normal de cada pixel
  • O sombreamento de Lambert é calculado como um produto escalar na forma v = N·L
  • Ao converter para coordenadas esféricas, isso é simplificado para v = sinNθ sinLθ cos(Nφ−Lφ) + cosNθ cosLθ
    • Assume-se raio r=1 para todos os vetores, reduzindo a quantidade de operações

Implementação no Game Boy

  • Lθ (ângulo vertical da luz) é fixado como constante, e apenas Lφ (ângulo de rotação da luz) é controlado pelo jogador
  • A ROM armazena cada pixel no formato (Nφ, log(m), b)
  • Para contornar a ausência de instrução de multiplicação, são usados transformação logarítmica e lookup tables (log, pow)
    • O bit de sinal é armazenado no bit mais alto para permitir operações com valores negativos
  • Todos os valores escalares são representados como frações de 8 bits no intervalo de -1.0 a +1.0
    • A soma é feita no espaço linear, e a multiplicação no espaço logarítmico
    • Usa-se 127 como denominador para permitir representar tanto +1 quanto -1

cos_log e a operação principal

  • cos_log é uma lookup table combinada na forma log(cos x), substituindo multiplicação por soma no espaço logarítmico
  • Operações por pixel
    • 1 subtração, 1 consulta a cos_log, 1 soma, 1 consulta a pow, 1 soma
    • Total de 3 somas/subtrações e 2 consultas

Desempenho

  • Processa 15 tiles por quadro, e algumas linhas vazias são calculadas mais rapidamente
  • Cerca de 130 ciclos por pixel, e linhas vazias levam 3 ciclos
  • Aproximadamente 89% da CPU é usada nas operações do shader, e o restante em entrada e I/O

Código auto-modificável (Self-Modifying Code)

  • Para otimizar o loop principal que processa cerca de 960 pixels por quadro, o código modifica as próprias instruções
    • Insere constantes diretamente no código para executar operações mais rápidas do que carregar variáveis
    • Ex.: sub a, 8 é 12 ciclos mais rápido do que sub a, variable
    • No total, há uma economia de cerca de 11.520 ciclos (10%)

Tentativas de usar IA

  • 95% de todo o projeto foi escrito manualmente
  • A IA teve dificuldade para escrever assembly de Game Boy (SM83)
  • Usos de IA
    • Python: leitura de camadas OpenEXR
    • Blender: scripts de automação da cena
    • SM83: alguns snippets de funcionalidade (ex.: VRAM DMA)
  • Tentativa malsucedida
    • Tentativa de gerar código assembly do shader com IA → ineficiente e com muitos erros
  • Tentativa de gerar assembly a partir de pseudocódigo com o modelo Claude Sonnet 4
    • Algumas partes funcionaram, mas eram lentas e continham erros, como confundir Z80 com SM83
    • O código final acabou sendo totalmente reescrito manualmente

Conclusão e lições

  • A IA é útil para scripts simples, mas precisão e validação são indispensáveis
  • No código de processamento OpenEXR, a IA causou um erro de alinhamento de canais (BGR vs RGB), gerando bugs por várias semanas
  • A experiência reforça a lição de que “ao usar IA, o mais importante é validar”
  • O projeto é avaliado como um caso experimental de implementação de shader que supera os limites de hardware legado

1 comentários

 
GN⁺ 2026-02-09
Comentários do Hacker News
  • Fico feliz de ver um texto com verdadeira vibe hacker no HN

    • Fiquei curioso se isso não tinha sido feito só com prompt de IA. Queria saber como foi implementado 😉
  • O resultado ficou realmente incrível. Pelo que entendi, isso é “parece 3D, mas na verdade é um shader que aplica iluminação sobre um normal map 2D pré-renderizado”
    Os frames estão neste link do GitHub

    • Na prática, não é tão diferente de um renderizador “3D de verdade”. Em um pipeline de renderização deferred, o shader também opera sobre buffers 2D como mapa de profundidade, normal map e color buffer.
      A parte de processamento dos triângulos 3D é mantida simples, e os shaders de iluminação mais caros são executados só uma vez sobre a imagem 2D, o que é eficiente
      Do ponto de vista do shader, se a entrada é um vetor 3D, então é um shader 3D. Ter ou não um rasterizador 3D é outra questão
      Jogos 3D modernos também usam esse tipo de abordagem de várias formas. A técnica de imposters, que usa modelos pré-renderizados de vários ângulos, também é uma técnica usada em engines 3D de verdade
    • É parecido com a forma como os jogos antigos de Mac aplicavam iluminação em texturas 2D sem hardware de aceleração 3D.
      Só que, desta vez, o impressionante é isso rodar em um Game Boy Color
  • Olá, sou o autor. Ouvi dizer que postaram isso aqui, então criei uma conta. Obrigado por compartilhar
    Também estou fazendo experimentos para simplificar ainda mais usando environment mapping, e dá para ver no link que compartilhei no Bsky

  • Projeto realmente interessante. Me lembrou da época em que eu programava em assembly de C64.
    Naquele tempo também não havia instrução de multiplicação, então era preciso encontrar maneiras criativas de contornar as limitações do hardware

  • Foi uma tentativa de usar IA, mas no fim acabou sendo um experimento fracassado.
    Como o setor está em polvorosa com IA, eu queria experimentar por conta própria, e acho importante divulgar com transparência se foi usada IA generativa.
    Se esconder isso, prejudica a confiança; se divulgar, dá para ter uma conversa aberta até com quem pensa diferente

    • Originalmente o tom era neutro, mas como as pessoas entenderam errado que eu estava exaltando IA, mudei para algo um pouco mais cético.
      Eu só queria registrar esse processo
  • Esse shader para GBC mostra a verdade de que “todo cálculo é uma aproximação dentro de restrições”.
    A multiplicação é substituída por consulta em tabela e adição, e a precisão é ajustada de acordo com o resultado visual

  • Realmente impressionante. Principalmente o fato de isso rodar em hardware real de Game Boy Color.
    Muitas vezes colocam um processador poderoso no cartucho e usam o GBC como simples terminal, mas isso não é esse tipo de hack

  • Sinceramente, eu queria que a Nintendo relançasse o GBC ou o GBA.
    Se vendessem em formato de cartucho com alguns jogos embutidos, eu compraria na hora

    • No mercado de usados dá para conseguir por um preço bem baixo. É só adicionar um flash cart.
      Mas hoje em dia um portátil Android no mesmo formato acaba sendo mais prático.
      Eu também tenho uma coleção de Game Boy, mas hoje em dia emulador é muito mais conveniente
    • É só comprar o ModRetro Chromatic, feito pelo fundador da Oculus VR.
      Mesmo que a Nintendo fizesse um novo, acho difícil ficar tão bom quanto esse
  • É para textos assim que o HN existe.
    Faz sentir de novo a diversão de folhear antigas revistas de tecnologia

  • Esse autor é um gênio maluco, no melhor sentido