2 pontos por GN⁺ 2 시간 전 | 1 comentários | Compartilhar no WhatsApp
  • Um renderer de software é implementado do zero, sem bibliotecas gráficas externas, para entender como OpenGL, Vulkan, Metal e DirectX funcionam por dentro
  • Ele converte um modelo 3D em imagem a partir de uma malha de triângulos e texturas, sem abordar implementação de GUI ou aplicações para GPU
  • O código final tem cerca de 500 linhas, e os alunos normalmente começam a criar um renderer funcional em 10 a 20 horas
  • São fornecidos apenas uma classe para manipulação de TGA com suporte a RGB, RGBA e tons de cinza, além da função de definir um único pixel; o desenho de linhas e triângulos deve ser implementado manualmente
  • Em vez de copiar o código pronto, é preciso escrevê-lo por conta própria para entender os conceitos de renderização e também o funcionamento interno de bibliotecas 3D

O processo de criar o pipeline de renderização por conta própria

  • Aprende-se o funcionamento do pipeline de renderização seguindo de forma solta a estrutura das bibliotecas modernas de gráficos 3D
    • Em vez de ensinar a escrever aplicações para GPU, o funcionamento interno é reproduzido com um renderer de software
    • A entrada é um modelo 3D composto por malha de triângulos e texturas, e a saída é uma imagem renderizada
    • O programa gera um arquivo de imagem sem interface gráfica
  • Para reduzir dependências externas, usa-se o formato de imagem simples TGA
    • As únicas funções fornecidas no início são carregar e salvar imagens, além de definir a cor de um único pixel
    • Como não há função embutida para desenhar linhas ou triângulos, tudo precisa ser escrito manualmente
  • O exemplo inicial cria um framebuffer RGB 64x64, define como brancos os pixels de três coordenadas e depois salva em framebuffer.tga
    • Os valores de cor são especificados na ordem BGRA

Build e execução do código

git clone https://github.com/ssloy/tinyrenderer.git &&
cd tinyrenderer &&
cmake -Bbuild &&
cmake --build build -j &&
build/tinyrenderer obj/diablo3_pose/diablo3_pose.obj obj/floor.obj
  • O resultado da execução é salvo em framebuffer.tga
  • Embora o código final tenha cerca de 500 linhas, não é recomendado usar o código fornecido como está, porque o processo de implementar por conta própria é essencial para compreender os conceitos

1 comentários

 
GN⁺ 2 시간 전
Opiniões no Hacker News
  • Alguns meses atrás, implementei por conta própria, sem LLM, um renderizador por software em Rust, e ainda adicionei um jogo simples, um shader pixelado e até um efeito de aberração cromática nas bordas da lanterna
    https://github.com/kshitijl/tinyrenderer-rs
    O repositório tem muitas capturas de tela do processo de desenvolvimento e de bugs visuais engraçados. Aprendi bastante não só sobre os princípios de renderização, mas também que CPUs modernas são muito rápidas e que mesmo um renderizador de CPU single-thread consegue rodar um jogo 3D interativo com efeitos especiais chamativos
    • Fico curioso por que ele depende de wgpu se é um renderizador por software
    • Fico curioso se, ao escrever a lógica do jogo em Rust, é necessário chegar ao ponto de adicionar até ECS
  • Este material e Mathematics for Computer Graphics, de John Vince, foram essenciais para criar meu renderizador por software
    Foi antes das LLMs, então levou pelo menos dois meses, e passei a maior parte do tempo entendendo a matemática de computação gráfica e rastreando erros de segmentação em C
    • Fico curioso quantas horas por dia, ao longo desses meses, você trabalhou nisso
  • Fico curioso se o livro de Foley e Van Dam ainda é a principal referência da área. Ele foi revisado em 2013, mas estou mais familiarizado com a edição de 1982, mais centrada em 2D; na época, era praticamente a bíblia da computação gráfica
    • Faz muito tempo que não o abro; para mim, ele é mais uma enciclopédia singular com valor histórico
      Estas notas de aula no GitHub foram melhores para revisar os conceitos. Não gosto do estilo de código do repositório, e o rasterizador antigo também é simples e ineficiente demais, mas ainda assim acho mais agradável de ler do que o livro de Foley
    • Eu também aprendi pela 2ª edição e tenho a edição mais recente, de 2013; ela é razoável
      Com as mudanças de edição, a linguagem usada também evoluiu de Pascal para C, depois C e C++, e a edição mais recente inclui um pouco de C#. Vários conceitos novos ficaram de fora, mas acho que ainda há muito conteúdo valioso
  • Gostaria que pelo menos um tutorial de renderizador por software tratasse direito de clipping de triângulos. Em um renderizador prático, mesmo em cenas básicas, é obrigatório lidar com geometria que cruza o frustum de visualização, mas, para mim, essa é a parte mais difícil
    • Este tema é abordado em um capítulo inteiro: https://gabrielgambetta.com/computer-graphics-from-scratch/11-clipping.html
    • Clipping de triângulos só é necessário quando a interpolação de atributos de triângulos muito grandes é importante, e há duas abordagens: descartar rapidamente ou sintetizar primitivas
      O clipping contra o frustum pode ser tratado pela seleção de pontos em tiles locais, e a síntese de primitivas é mais fácil quando se trabalha com o retângulo de clipping transformado inversamente no sistema de coordenadas baricêntricas. É possível controlar erros de arredondamento com dupla precisão ou ponto fixo, e a principal dificuldade é regenerar os valores de Z e 1/Z dos novos vértices. Em um rasterizador com síntese tardia de atributos, o restante passa naturalmente pelo pipeline, e há exemplos na implementação open source do OpenSWR.org
    • Eu também sempre travava na etapa de “preciso implementar clipping”, mas no fim escrevi um código que funcionava sem grande dificuldade e só depois descobri que tinha redescoberto de forma independente o algoritmo de Sutherland–Hodgman
      A maior barreira psicológica é a estranheza do espaço projetivo e das coordenadas homogêneas. Os seis planos do espaço de clipping são simples: x = ±w, y = ±w, z = ±w; basta percorrer cada aresta do polígono, determinar se seus dois extremos estão dentro ou fora, e interpolar linearmente a posição da interseção com a borda e os atributos dos vértices. Aplicando esse processo a todos os planos em sequência, o triângulo vira um polígono convexo de até 9 vértices e pode ser facilmente triangulado de novo. Se você pré-calcular o outcode, pode pular o clipping de triângulos que estejam completamente dentro ou completamente fora
      Artigo: https://dl.acm.org/doi/10.1145/360767.360802
  • Em ambientes modernos, praticamente não existe C++ puro. Não dá para escrever diretamente em registradores e na VRAM para emitir imagem como nos computadores dos anos 1980; no fim, você depende de muito código sobre camadas espessas de APIs, drivers e firmware
  • Estou tentando fazer renderização por software de novo por nostalgia dos anos 1990, misturando bancos CLUT no estilo 2D com técnicas modernas de triângulos classificados por intervalos e coordenadas baricêntricas
    Mantendo uma forma de pipeline fixo, dá para processar uma quantidade surpreendente de triângulos com funções de desenho bem simples
  • Descobri um bug no tratamento de OpenMP no macOS e enviei meu primeiro PR para este repositório depois de muito tempo