2 puntos por GN⁺ 2 시간 전 | 1 comentarios | Compartir por WhatsApp
  • Se implementa desde cero un renderizador de software sin bibliotecas gráficas externas para entender cómo funcionan internamente OpenGL, Vulkan, Metal y DirectX
  • Convierte un modelo 3D en una imagen a partir de una malla de triángulos y texturas, sin abordar la implementación de una GUI ni de una aplicación para GPU
  • El código final tiene alrededor de 500 líneas, y los estudiantes suelen dedicar entre 10 y 20 horas para empezar a crear un renderizador funcional
  • Solo se proporciona una clase para manejar TGA compatible con RGB, RGBA y escala de grises, además de una función para establecer un píxel individual; el dibujo de segmentos de línea y triángulos debe implementarse directamente
  • Para entender los conceptos de renderizado y también cómo funcionan internamente las bibliotecas 3D, conviene escribir el código uno mismo en lugar de copiar el código final

Proceso para construir directamente el pipeline de renderizado

  • Se aprende cómo funciona el pipeline de renderizado siguiendo de forma aproximada la estructura de las bibliotecas modernas de gráficos 3D
    • En lugar de aprender a escribir aplicaciones para GPU, se reproducen sus mecanismos internos con un renderizador de software
    • La entrada es un modelo 3D compuesto por una malla de triángulos y texturas, y la salida es una imagen renderizada
    • Sin una interfaz gráfica, el programa genera un archivo de imagen
  • Para reducir dependencias externas, se usa TGA, un formato de imagen sencillo
    • Las únicas funciones iniciales proporcionadas son cargar y guardar imágenes, y establecer el color de un solo píxel
    • No hay funciones integradas para dibujar segmentos de línea ni triángulos, así que todo debe escribirse directamente
  • El ejemplo inicial crea un framebuffer RGB de 64x64, establece en blanco los píxeles de tres coordenadas y luego lo guarda como framebuffer.tga
    • Los valores de color se especifican en orden BGRA

Compilación y ejecución del 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
  • El resultado de la ejecución se guarda en framebuffer.tga
  • Aunque el código final tiene unas 500 líneas, el proceso de implementarlo directamente es esencial para entender los conceptos, por lo que no se recomienda usar el código proporcionado tal cual

1 comentarios

 
GN⁺ 2 시간 전
Opiniones en Hacker News
  • Hace unos meses implementé yo mismo un renderizador por software en Rust sin usar LLM, y hasta le añadí un juego simple, un shader pixelado y un efecto de aberración cromática en el borde de una linterna
    https://github.com/kshitijl/tinyrenderer-rs
    El repositorio tiene muchas capturas del proceso de desarrollo y de bugs visuales graciosos. Aprendí mucho no solo sobre los principios del renderizado, sino también que las CPU modernas son muy rápidas y que incluso con un renderizador de CPU de un solo hilo se puede ejecutar un juego 3D interactivo con efectos especiales vistosos
    • Me pregunto por qué, siendo un renderizador por software, depende de wgpu
    • Me pregunto si al escribir la lógica del juego en Rust hace falta llegar al punto de añadir ECS
  • Este material y Mathematics for Computer Graphics de John Vince fueron esenciales para crear mi renderizador por software
    Fue antes de los LLM, así que me tomó al menos dos meses, y la mayor parte del tiempo la pasé entendiendo las matemáticas de gráficos por computadora y rastreando errores de segmentación en C
    • Me pregunto cuántas horas al día trabajaste durante esos meses
  • Me pregunto si el libro de Foley y Van Dam sigue siendo la referencia principal en este campo. Fue revisado en 2013, pero yo estoy más familiarizado con la edición de 1982, centrada en 2D, y en ese entonces era como el libro canónico de gráficos por computadora
    • Hace mucho que no lo vuelvo a abrir, y para mí se parece más a una enciclopedia única con valor histórico
      Estas notas de clase en GitHub me sirvieron más para repasar conceptos. No me gusta el estilo de código del repositorio y el rasterizador antiguo también es demasiado simple e ineficiente, pero aun así me parece más fácil de leer que el libro de Foley
    • Yo también aprendí con la segunda edición y también tengo la última edición de 2013; está bastante bien
      Con los cambios de edición, el lenguaje usado evolucionó de Pascal a C, y de C a C++, y la edición más reciente también incluye un poco de C#. Faltan varios conceptos nuevos, pero creo que todavía tiene mucho contenido valioso
  • Ojalá al menos uno de estos tutoriales de renderizadores por software tratara bien el recorte de triángulos. En un renderizador práctico, es obligatorio manejarlo cuando la geometría cruza el frustum de vista incluso en una escena básica, pero personalmente es la parte que más me cuesta
    • Este tema se cubre en un capítulo completo: https://gabrielgambetta.com/computer-graphics-from-scratch/11-clipping.html
    • El recorte de triángulos solo es necesario cuando importa la interpolación de atributos en triángulos muy grandes, y hay dos maneras: descartarlos rápido o componer primitivas
      El recorte del frustum puede resolverse seleccionando puntos de mosaicos locales, y para la composición de primitivas es más fácil tratar el rectángulo de recorte transformado inversamente en coordenadas baricéntricas. Los errores de redondeo se pueden controlar con doble precisión o punto fijo, y la dificultad clave es regenerar los valores Z y 1/Z de los nuevos vértices. En un rasterizador con composición diferida de atributos, el resto pasa naturalmente por el pipeline, y se pueden ver ejemplos en la implementación de código abierto de OpenSWR.org
    • Yo también siempre me atoraba en la etapa de “tengo que implementar el recorte”, pero al final logré escribir código que funcionaba sin demasiada dificultad, y solo después supe que en realidad había redescubierto por mi cuenta el algoritmo de Sutherland–Hodgman
      La mayor barrera psicológica es lo poco familiar que resultan el espacio proyectivo y las coordenadas homogéneas. Los seis planos del espacio de recorte son simplemente x = ±w, y = ±w, z = ±w; basta con recorrer cada arista del polígono, determinar si sus extremos están dentro o fuera, y luego interpolar linealmente la posición del cruce con el borde y los atributos del vértice. Si aplicas este proceso a cada plano en orden, el triángulo se convierte en un polígono convexo de hasta 9 vértices que se puede triangular de nuevo con facilidad. Si calculas de antemano los outcodes puedes saltarte el recorte de los triángulos completamente internos o externos
      Artículo: https://dl.acm.org/doi/10.1145/360767.360802
  • En entornos modernos, en la práctica no existe algo como C++ puro. Ya no puedes mostrar video escribiendo directamente en registros y VRAM como en las computadoras de los 80; al final terminas dependiendo de muchísimo código sobre gruesas capas de API, drivers y firmware
  • Estoy intentando volver al renderizado por software por nostalgia de los 90, mezclando bancos CLUT al estilo 2D con técnicas modernas de clasificación por spans de triángulos y coordenadas baricéntricas
    Si mantienes una forma de pipeline fijo, se puede procesar una cantidad sorprendente de triángulos incluso con funciones de dibujo bastante simples
  • Encontré un bug en el manejo de OpenMP en macOS y, después de muchísimo tiempo, envié mi primer PR a este repositorio