Giter Site home page Giter Site logo

asmilex / raytracing Goto Github PK

View Code? Open in Web Editor NEW
8.0 2.0 0.0 540.01 MB

Path tracer en tiempo real implementado sobre Vulkan KHR basado en Ray Tracing In One Weekend Series de Peter Shirley. Trabajo de fin de grado para el doble grado en Ingeniería Informática y Matemáticas de la UGR.

Home Page: https://asmilex.github.io/Raytracing/

License: Apache License 2.0

CMake 0.72% C 14.17% C++ 8.76% Dockerfile 0.05% GLSL 1.35% Python 0.08% Jupyter Notebook 74.76% R 0.10%
raytracing tfg ugr dgiim

raytracing's Introduction

🔦 Los fundamentos de Ray Tracing en tiempo real 🔦

🔹 PDF: Descargar 🔹


 

🔰 Tabla de contenidos 🔰

Sobre el proyectoInstalaciónEstructuraContribuyendoEnlaces de interés

💡 Y esto, ¿de qué va exactamente?

Este repositorio contiene el desarrollo de un path tracer en tiempo real implementado en Vulkan con extensiones de Ray Tracing (KHR) basado en el de Ray Tracing In One Weekend, de Peter Shirley. Se incluye una memoria y varias utilidades relacionadas con el proyecto.

Es el trabajo de fin de grado de mi doble grado en Ingeniería Informática y Matemáticas 🎓.

⚙️ Instalación

Requiere tener Vulkan instalado, un driver de Nvidia compatible con Vulkan, Cmake.

Para compilar y ejecutar el proyecto, haz lo siguiente:

git clone --recursive --shallow-submodules https://github.com/Asmilex/Raytracing.git
cd .\Raytracing\application\vulkan_ray_tracing\
mkdir build
cd build
cmake ..
cmake --build .
..\..\bin_x64\Debug\asmiray.exe

Cuando se haya ejecutado, deberían haber aparecido los makefiles necesarios. Si abres VSCode, en la pestaña de Run and Debug, deberías tener una opción para lanzar Asmiray. Debería ir.

🌲 Estructura del repositorio

A fecha 2022-01-31, el repositorio está compuesto por los siguientes directorios:

  • ./docs: Documentación del proyecto. Toda la documentación está basada en markdown. Para convertirla en PDF y desplegarla en la web, se utiliza Pandoc. Tienes más información en el README correspondiente.
  • ./RT_in_one_weekend: Código del ray tracer de la serie de libros de Shirley original en CPU.
  • ./application: El futuro ray tracer en GPU se ubicará aquí. Ahora mismo está en pañales.

Visualización de la codebase

🤝 Contribuyendo

📖 Github Projects

Puedes acceder a Github Projects para ver la gestión de las tareas. Resulta especialmente útil para saber en lo que se está trabajando actualmente.

👓 Guía de estilo

Cada commit debería ir identificado con un emoji antes del mensaje, así como terminar en un issue enlazado. Por ejemplo, [📓] Descripción de función de densidad (#71)

Estos son los iconos usados, así como su significado:

Tipo de commit Emoji Cómo se escribe rápidamente
Documentación 📓 :notebook:
Archivo de configuración 🔧 :wrench:
Integración continua 👷 :construction_worker:
Commit de Actions 🤖 :robot:
Quitar archivos 🔥 :fire:
Nuevas características :sparkles:
Test ⚗️ :alembic:
Refactorización ♻️ :recycle:
Bugfix 🐛 :bug:

Los issues también deberían seguir el mismo estilo. Tienes un ejemplo aquí

🔗 Enlaces de interés

En esta sección se recopilan enlaces útiles para el desarrollo del motor. Se irá actualizando conforme avance.

(Y, seguramente, desaparezca en el futuro)

Implementaciones y tutoriales

Conocimiento

raytracing's People

Contributors

asmilex avatar balrrach avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

raytracing's Issues

[✨] Fuentes de luz de área

Necesitamos fuentes de luz de área para el path tracer. Nos proporcionarán la base de nuestro estudio de la varianza.

Es suficiente con que esta implementación sea básica.

[📓] Feedback del capítulo del Path Tracer

  • Decidir si escribimos el cálculo de la entrada de la Shader Binding Table. La página usada es esta

Feedback de Carlos (05/05/2022):

  • Cuando se habla de las BRDFS, se proporciona el código que las evalúa (para una dirección de entrada y de salida), pero esto no queda explicito en la memoria, aclararlo. Lo digo ya que también se podría hablar del código que las "muestrea" (obtener direcciones aleatorios con la pdf igual o aproximadamente igual a la BRDF).
  • Añadir pseudo-código en español (no código en un lenguaje concreto) de un path-tracer sin y luego con "next event estimation", recursivo simple, relacionarlo con la ecuación de rendering. Usar las transparencias del curso "RIG" (pdf: rig-t3b-monte-carlo-1.pdf), aquí hay ejemplos de lo que yo entiendo por "pseudo-código"
  • La parte que describe la implementación (5. ¡ construyamos un path tracer!) hay apartados (5.7 y 5.8) que deberían moverse a después de la ecuación de rendering, antes de hablar en concreto de como se construye un path-tracer.

[👷] El action del PDF no funciona

Probablemente falte alguna biblioteca o la instalación de LaTeX del contenedor no es la correcta.

Log:

Compilando TFG.pdf
Terminado.
pandoc --from markdown --listings --top-level-division="chapter" --bibliography ./chapters/bibliography.bib --citeproc --template ./headers/eisvogel.tex --pdf-engine=xelatex -o TFG.pdf ./headers/meta.md ./chapters/00-dedicatoria.md ./chapters/01-introduccion.md ./chapters/02-notacion.md ./chapters/03-fundamentos.md ./chapters/04-sampling.md ./chapters/05-APIs.md ./chapters/06-motores.md ./chapters/07-rendimiento.md ./chapters/08-posibles-mejoras.md ./chapters/09-metodologia.md ./headers/pdf.md
Error producing PDF.
! LaTeX Error: File `scrbook.cls' not found.

Type X to quit or <RETURN> to proceed,
or enter new name. (Default extension: cls)

Enter file name: 
! Emergency stop.
<read *> 
         
l.53 \usepackage

make: *** [Makefile:66: pdf] Error 43

[📓] Las citas no tienen un formato consistente

Trabajo restante:

  • En vez de tener un apartado de referencias al final de cada capítulo, las citas deberían aparecer al lado del texto correspondiente.
  • Usar citas también en las URLs.

(Nota para el Andrés del futuro: mira el correo de Carlos del 01/04/2022. Ahí tienes más info)

[:notebook:] Correcciones finales

Colección de tareas finales necesarias para la entrega.

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64

Notas de Carlos (1 de junio de 2022)

Versión de PDF: 31 de Mayo de 2022, 11:22

(1) Título:

El título del TFG debe ser el que se usó para registrarlo el verano pasado, es el siguiente:

"Métodos de Monte-Carlo para síntesis de imágenes: análisis teórico e implementaciones basadas en path-tracing acelerado por hardware"

Debes cambiarlo donde proceda en la memoria y en el repositorio en github.

(2) Sinopsis, página 1

donde dices "modernas de informática gráfica físicamente realistas basadas en ray tracing en tiempo real", debería decir "modernas de síntesis de imágenes físicamente realistas basadas en Path-Tracing en tiempo real"

(3) A brief overview, página 2

En el párrafo que comienza con "Path tracing" se debe al menos decir que la diferencia fundamental entre Path-Tracing y Ray-Tracing es que el primero calcula Iluminación Global (emplear este término exactamente)

(4) A brief overview, página 3

Nombras "Nvidia DesignWorks’ nvpro-samples framework", incluir referencia a la entrada de la bibliografía con el enlace a la Web del framework.

(5) Nota histórica, página 9

Escribes "En 1986 Kajiya introdujo la denominada rendering equation (Pharr, Jakob, and Humphreys 2016)", aquí citas un artículo de Pharr y otros, pero deberías citar el artículo original de Kajiya, este:

James T. Kajiya. 1986. The rendering equation. In Proceedings of the 13th annual conference on Computer graphics and interactive techniques (SIGGRAPH '86). Association for Computing Machinery, New York, NY, USA, 143–150. https://doi.org/10.1145/15922.15902

(6) Nota histórica, página 9 y siguientes

Aquí, y en otros sitios, usas el término Ray-Tracing cuando yo creo que deberías usar Path-Tracing. Ray-tracing es la técnica que se basa en calcular que se ve en cada pixel, usando rayos, mientras que path-tracing es la extensión de ray-tracing para cálculo de iluminación global. Cuando escribes, por ejemplo "A diferencia del uni- verso, nosotros no podemos permitirnos el lujo de usar un elevado número de fotones, ni hacer rebotar la luz tantas veces como queramos. Nos pasaríamos una eternidad esperando. Y para ver una imagen en nuestra pantalla necesitaremos estar vivos, claro. En la práctica, esto su- puso que no todos los medios pudieron pasarse a ray tracing" te estás refiriendo a la capacidad de path-tracing de calcular iluminación global, pero luego simplemente mencionas ray-tracing, no path-tracing, que es lo correcto aquí IMHO.

(7) Nota histórica, página 10

En esta nota histórical debes al menos citar los primeros artículos sobre implementación de ray-tracing por hardware en GPUs, son estos dos:

Timothy J. Purcell, Ian Buck, William R. Mark, and Pat Hanrahan. 2002. Ray tracing on programmable graphics hardware. ACM Trans. Graph. 21, 3 (July 2002), 703–712. https://doi.org/10.1145/566654.566640

Nathan A. Carr, Jesse D. Hall, and John C. Hart. 2002. The ray engine. In Proceedings of the ACM SIGGRAPH/EUROGRAPHICS conference on Graphics hardware (HWWS '02). Eurographics Association, Goslar, DEU, 37–46. PDF: https://www.csee.umbc.edu/~olano/s2005c37/ch08.pdf

(8) Objetivos del trabajo, págin 10

Usar "los fundamentos del ray-tracing y path-tracing en tiempo real", en lugar de únicamente "ray-tracing".

(9) Sobre esta memoria, página 11

Usar "describen como se reflejan los fotones cuando impactan con una superficie" en lugar de "describen cómo cambian los fotones cuando impactan con una superficie"

(10) Sobre esta memoria, página 12

De nuevo, incluir enlace al repositorio en github de nvidia-pro samples cuando se cita aquí.

(11) 1. Las bases, página 14

Cambiar "origin" por "origen". Decir que el origen 'o' es un punto del espacio (de un espacio afin) y 'd' un vector libre. Usar una notación en las fórmulas para distinguir valores reales (como 't') de vectores o puntos (como 'd' o 'p'), lo usual es usar negrita para los vectores o puntos.

(12) 1. Las bases, página 15

Un párrafo comienza por "cuando un rayo impacta", pero "cuando" debe ir en mayúscula

(13) 1. Las bases, página 16

ídem que el anterior, el párrafo empieza con "como" en minúscula.

(14) 1.2. Intersecciones rayo - objeto, página 16

El primer párrafo empieza en minúscula.

(15) 1.2. Intersecciones rayo - objeto, página 16

Lo de separar un poco el inicio no es exactamente por errores de redondeo, es para evitar que se detecte intersección de un rayo en el origen del mismo, con t==0, esa intersección debe ignorarse, por ejemplo para rayos de sombra. Por tanto, en realidad se buscan intersecciones en el intervalo abierto en 0. La forma de implementar esto numéricamente, con precisión finita, es usar el epsilon del que hablas, pero falta describir este motivo.

(16) 1.2.1 Superficies implícitas, página 17

Debes decir que las superficies definidas de forma implícita se pueden usar para calcular intersecciones rayo-superficie de forma numérica iterativa por lo general, aunque en algunos casos hay expresiones analíticas sencillas (como el plano, o la esfera, por ejemplo)

(16) 1.2.1 Superficies implícitas, página 18

Un párrafo comienza con "consideremos" en minúscula. Además, usas Q_0 y q_0 para un punto conocido del plano, es mejor usar minúsculas (aunque también hay que tener en cuenta la nota número 11 aquí arriba, se deben distinguir puntos y vectores de valores escalares). En la fórmula "F(Q)=(q-q_0)\cdot.." usas Q y q, lo correcto es q. Finalmente, debes añadir que d y n son paralelos, entonces se considera que no hay intersección.

(16) 1.2.2 Superficies paramétricas, página 19

Dices que es "sencillo" encontrar intersecciones rayo-superficie paramétrica, pero en realidad es al revés, es decir, las ecuaciones paramétricas de un superficie, por regla general, no permiten calcular esas intersecciones, y por tanto no se usan directamente en ray-tracing (a no ser que se puedan convertir a implícitas, al respecto hay mucha literatura en matemáticas). Lo que sí es fácil es obtener una malla de triángulos a partir de las ecuaciones paramétricas, y luego calcular intersección rayo-malla usando indexación espacial.

(17) 1.2.3. Intersecciones con esferas, página 21

Donde dices "pegaría con el borde" deberías decir "es tangente a la esfera"

(18) 1.2.3. Intersecciones con esferas, página 24

El primer párrafo de esa página empieza en minúscula. Además, has puesto "cramer" en minúscula, pero es un nombre propio, va en mayúscula.

(19) 2.1.1. Potencia, página 26

En la definición de potencia escribes simplemente que la potencia es "la tasa de producción de energía", pero debes de aclarar que se trata de la cantidad de energía por unidad de tiempo que atraviesa un área o región determinada de una superficie.

(20) 2.1.1. Irradiancia, página 26

donde dice "flujo radiante que recibe una superficie", debes decir "potencia por unidad de área que recibe una región de una superficie o un punto de la misma", y luego, en lugar de "dada un área A", debes decir, "si A es el área de dicha superficie"

(21) 2.1.3 Ángulos sólidos, página 29

Para definir el ángulo sólido, es mucho más fácil no usar un esfera de radio arbitrario 'r', sino una de radio unidad, es lo más común en la literatura. Así, el ángulo sólido de un trozo de esfera de radio unidad es directamente su área. Además, lo usual en la literatura es usar \sigma para significar la medida de ángulo sólido, no 'w', me resulta raro. La frase "Debido a la forma en la que se trabaja con ellos, es costumbre usar 'w' como un vector dirección unitario en la esfera." me parece algo confusa, ya que en la literatura de iluminación global se suele usar 'w' para significar vectores unitarios, es cierto, pero eso no tiene nada que ver con el ángulo sólido, una cosa es la medida de ángulo sólido y otra un vector de longitud unidad. Por eso veo mejor usar otro símbolo para el ángulo sólido. Usar A puede ser confuso, ya se usa para la medida de área. El símbolo \Omega lo usas para subconjuntos de la esfera como dominio de alguna integral. Usar 'w' es confuso, como ya he dicho. Por todo esto, creo que sería bueno usar \sigma, esto es habitual en la literatura sobre iluminación global (Peter Shirley lo usa bastante). Además, para las integrales, el diferencial de ángulo sólido entorno a un vector 'w' se puede poner como d\sigma(w), en lugar de dw, eso hace explícito en la notación cual es la medida de que se está usando en la integral, junto con la variable de integración.

(22) 2.1.3 Ángulos sólidos, página 30 y 31

Hablas sobre como se relacionan los diferenciales de los ángulos \theta y \sigma con en el diferencial de ángulo sólido. En matemáticas esto es una relación o tasa entre funciones de medida aplicadas a regiones de tamaño diferencial (es una generalización del concepto de derivada en teoría de la medida, relacionado con el "Jacobian") y efectivamente puede usarse para hacer cambios de variable en integrales. No se si tiene mucho sentido intentar explicarlo aquí, puedes simplemente introducir la relación entre los diferenciales y ya está (puesto que luego lo usas)

(23) 2.1.5 Radiancia, página 32

Aquí creo que habría que escribir el párrafo que sirve para definir la radiancia, de otra forma el lector no puede hacerse una idea de a qué te refieres. El párrafo es:

"La radiancia L(p,w) es la potencia o flujo radiante que pasa por un punto 'p' y viaja en una dirección 'w', por unidad de área (perpendicular a 'w') entorno a ese punto 'p', y por unidad de ángulo sólido entorno a esa dirección 'w'"

El ejemplo del espejo no es adecuado, creo que aquí debes referirte a un superficie de un cristal que refracta la luz, en ese caso del cristal la luz reflejada hacia un lado es distinta de la luz refractada hacia el otro, si no lo entiendo mal.

Lo de distinguir entre L+ y L- creo que es innecesario, y me resulta muy confuso. Lo importante es distinguir entre radiancia saliente L_o(p,w) (viaja en la dirección de 'w') y entrante L_{in}(p,w) (viaja en la dirección contraria a 'w', por definición). Estas radiancias se pueden definir para cualquier 'w' en la esfera, no solo en la semiesfera "por encima" del punto (en el lado de la normal). Por tanto, eso cubre los cuatro casos posibles, es decir, la radiancia saliente y entrante, por la parte superior y por la parte inferior de la superficie.

(24) 2.1.6.1. Una nueva expresión de la irradiancia y el flujo, página 35

Donde dices "Haciendo el mismo juego con el flujo emitido de un cierto objeto al hemisferio" creo que lo adecuado sería "Si integramos esta expresión para todos los puntos de una superficie A, obtenemos la potencia total saliente de esa superficie en todas las direcciones"

Según el libro PBRT (que es el que sigues aquí), en la expresión (2.12) se usa el término \Omega para significar cualquier región (subconjunto) de la esfera S^2, debes aclararlo aquí, como lo tienes no se sabe a que te refieres con \Omega.

(25) 2.2. Dispersión de luz, página 36 y 37.

Lo que denominas "dispersión en superficie" o "surface scatering" incluye la reflexión (reflection), deberías decirlo explícitamente, y quizás sería mejor decir "Dispersión y reflexión de la luz".

(26) 2.2.1. La función de distribución de reflectancia bidireccional (BRDF), página 38

En la igualdad de la reciprocidad, donde pones "f_r(p,w_i,w_o)" debes poner "f_r(p,w_i <-- w_o)", (con una flecha en lugar de una coma) en coherencia con la notación que vienes usando, como lo tienes resulta confuso. Esto ayuda a entender que es la reciprocidad de la brdf (no cambia si se intercambian w_i y w_o).

(27) 2.2.3. La función de distribución de dispersión bidireccional

(BSDF), página 39

En la fórmula 2.14 has usado 'S' para significar la esfera (el dominio de integración), pero en fórmulas anteriores has usado \Omega para significar también la esfera completa (mira, por ejemplo, la fórmula 2.12 de la página 35). Creo que es más "estándar" usar S^2 para la esfera y H^2 u \Omega para la semiesfera. De cualquier forma, debes usar un notación coherente en todo el texto e introducir los símbolos en el primer uso.

(28) 2.2.4. Reflectancia hemisférica, página 40

"Algo" en mayúscula en mitad de una frase. La frase "describe la reflexión total sobre un hemisferio debida a una fuente de luz que proviene desde la dirección w_o :" es incorrecta, debería ser "describe la radiancia saliente en la dirección 'w_o'", supuesto que la radiancia entrante desde cualquier dirección es constante e igual a la unidad.".

(29) 2.3.1. Tipos de dispersión, página 42

El párrafo que describe la diferencia entre reflexión isotrópica y anisotrópica es incorrecto. Los materiales que se ven con el mismo color desde todas las direcciones (es decir L(p,w_o) no depende de 'w_o') son los materiales difusos (ya que w_o no aparece en la expresión de la BRDF difusa). Los materiales isotropicos son aquellos cuya BRDF f_r(p,w_o,w_i) no cambia cuando se rotan ambos vectores 'w_o' y 'w_i' un ángulo cualquiera (el mismo para ambos) entorno a la normal a 'p'. La mayoría de los materiales son isotrópicos. Si la BRDF f_r sí varía ante esa rotación, entonces hablamos de materiales anisotrópicos. Los materiales anisotrópicos típicos son materiales pulidos que tiene surcos pequeños, invisibles a simple vista, como un disco de vinilo o una superficie metálica pulida en una dirección. La anisotropía viene de que el comportamiento de la reflexión depende de la orientación de los surcos en la superficie.

(30) 2.3.2.1. Reflexión especular perfecta, página 42

Aquí aparece (1er párrafo de 2.3.2.1) una cita a la primera entrada de la bibliografía, la cita es a un capítulo de un libro que tiene un ISBN y que está publicado en Open Access. Este tipo de referencias bibliográficas debe ponerse en la bibliografía incluyendo la información del autor y nombre del capítulo, junto con los editores, nombre e ISBN del libro completo, en este caso el autor es del capítulo es Eric Haines, debe quedar así:

Eric Haines. 2021. "Reflection and Refraction Fórmulas", en Adam Marrs, Peter Shirley, and I. Wald, (editores). "Ray tracing gems II.", pp.104-108. Editorial Apress, 2021. ISBN: 978-1-4842-7187-2. DOI: https://doi.org/10.1007/978-1-4842-7185-8

(revisa otras referencias parecidas para adaptarlas a este estándar, he puesto el DOI aunque el enlace a http://www.realtimerendering.com/raytracinggems/rtg2/ también es correcto).

Aquí debes usar la notación que vienes usando para los vectores ('w_o','w_i','w_r' en lugar de 'o', 'i', 'r'), además debes usar el convenio de que los vectores w_o,w_i,w_r apuntan desde el punto 'p' hacia afuera, no al revés, como en la figura 2.5 de Eric Haines. De hecho, esa notación (w_o,w_i y w_r apuntando hacia fuera) es lo que usas a continuación en la siguiente sección (y en muchos más sitios). Ten en cuenta que al cambiar el sentido de i y r la expresión de 'r' cambia de signo (se intercambian los operando de la resta).

La expresión k_r(|i·n|) es un poco confusa, puede interpretarse de dos formas:

  1. k_r es una función que se evalua con |i·n| como argumento,
  2. k_r es un coeficiente que multiplica a |i·n|,

en cualquier de los dos casos, debes aclarar cual de las dos opciones es la que tienes en mente y explicarla: si es una función ¿como y pq ocurre esa dependencia? si es un producto ¿pq se multiplica por i·n?

(30) 2.3.2.2. Reflexión difusa o lamberiana, páginas 42 y 43

En el título pones "lamberiana" en lugar de "lambertiana". El símbolo k_d que usas aquí es muy estándard, pero creo que debe aparecer dividido por \pi en la expresión de la BRDF f_r, de esta forma, el rango de valores de k_d es [0,1] y así k_d coincide con el albedo (fración de energía reflejada de forma difusa), que es lo usual (1/\pi es la constante normalización de esta BRDF, aqui abajo te pongo los coeficientes correspondientes para Phong y Blinn-Phong.

(31) 2.3.2.3. Reflexión especular no perfecta, página 43 y 44.

Aquí introduces el modelo de iluminación local de Phong (o Blinn-Phong) usual para rasterización, que es un modelo sencillo que incluye una componente ambiental, otra difusa, y otra pseudo-especular. Pero eso es un modelo aproximado y en esta parte estás hablando de BRDFs basadas en física y normalizadas, así que creo que debes de incluir las BRDFs de la parte pseudo-especular únicamente, ignorando la parte ambiental (no tiene sentido en este contexto) e ignorando la parte difusa (esa BRDF ya la has introducido). Respecto a las expresiones de la parte pseudo-especular, son correctas, pero si estamos definiendo una BRDF realista y normalizada, deben llevar adicionalmente los factores de normalización, para Phong es (n+2)/(2·pi) y para Blinn-Phong es ((n+2)·(n+4))/(8·pi·(2^(-n/2)+n) (ver: http://www.farbrausch.de/~fg/stuff/phong.pdf)

Aquí incluyes dos trozos de código que evaluan estas BRDFs, pero estos trozos de código aparecen un poco 'fuera de contexto', ya que no aparecen para otras BRDFs y no se dice en que lenguaje de programación están escritos.

(32) 2.3.3.2. Ecuaciones de Fresnel, página 47

Escribes "Generalmente en los ray tracers la polarización se ignora, promediando ...", pero lo correcto sería decir "Generalmente en los ray tracers se simula luz no polarizada, así que se deben promediar ambos valores, es decir, se debe usar el valor 'R' definido así: "

Aquí sería coherente incluir cómo se calcula el vector refractado y poner explícitamente una fórmula que indique como depende la radiancia refractada y la reflejada de la radiancia incidente.

(33) 2.3.5.1. Oren - Nayar, página 48

la referencia al "White furnace test" no tiene mucho sentido, no lo entiendo. Además, sería lógico poner la expresión de la BRDF, como has hecho para todas las demás, así como algún texto que describa las características de esta BRDF (que diferencia tiene con las anteriores?)

(34) 2.3.5.2. GGX, página 48

Sería mejor titularlo "BRDFs basadas en modelos de microfacetas. La BRDF GGX", sería conveniente si tienes tiempo al menos poner la expresión de la BRDF y explicar sus parámetros (la rugosidad principalmente), de otra forma no se justifica incluir esta sección en la memoria.

(35) 2.4. La rendering equation, página 49

Introduces la ecuación (2.19) sin más, habría que explicarla en al menos una frase "la radiancia total saliente de p en la dirección de w_o es L_o(p,w_o), y se obtiene como la suma de la radiancia emitida (L_e), más la reflejada (L_r). A su vez, la radiancia reflejada (L_r) es la integral, para todas las posibles direcciones de entrada, de la radiancia incidente (L_i), multiplicada por la BRDF (f)"

En la ecuación siguiente a la 2.19 has puesto L_o a la izquierda de la igualdad (igual que en 2.19), pero las partes derechas de 2.19 y la siguiente no coinciden. Por tanto, en la ecuación siguiente a la 2.19 debes usar L_r (radiancia reflejada) en lugar de L_o (que es la radiancia total saliente, de acuerdo con 2.19).

En la segunda ecuación de la página 50, de nuevo usas L_o cuando deberías usar L_r.

En la tercera ecuación de la página 50, deberías usar L_o en lugar de L a secas, aunque lo mejor (lo usual) es que la radiancia total saliente sea L a secas (entonces habría que cambiarla en las 5 ecuaciones de las página 49 y 50, no usar L_o en ningún sitio).

La ecuación 2.19 y la tercera ecuación de la página 50 son casi iguales, a diferencia que en la ultima ya no aparece L_i, solamente la radiancia saliente. Sin embargo, dices que la 2.19 es la "rendering equation", aunque luego hablas de la "ecuación de reflexión". Debes aclarar la terminología, quizás querías decir que la ecuación 2.19 es la "reflection equation" ??

(36) 3. Métodos de Monte Carlo, páginas 51 a 81

Respecto a esta sección, no voy a revisarla pues esta parte es la que te ha revisado la co-tutora y creo que no debo interferir en lo que te haya dicho ella, únicamente te comento algo de la sección 3.3.3.2 ya que toca temas directamente relacionados con el rendering y la ecuación de rendering. Además, te hago una sugerencia para añadir algo sobre cadenas de markov para solución de ecuaciones integrales, que es la base matemática del Path-tracing y todas las técnicas asociadas (lo pongo en los siguientes dos puntos).

(37) 3.3.3.2. Next event estimation, o muestreo directo de fuentes de luz.

La radiancia directa y la indirecta no tienen como parámetro 'w_i', por tanto donde pones w_o<-w_i en la última ecuación de la página 71, debes poner simplemente w_o. Además, donde dices "Siendo, .... , L_{directa} la radiancia proporcionada por las fuentes de luz" sería mejor decir "Siendo, ... L_{directa} la radiancia reflejada debida únicamente a radiancia incidente directamente de las fuentes de luz".

En la segunda ecuación de la página 72, donde pones L_i en la integral, debería ser L_r, la radiancia reflejada (sin la parte emitida, que ya se incluye en la radiancia directa). Igualmente, en el párrafo de debajo, donde dices "Al aparecer la radiancia incidente .. L_i ", debes decir, "Al aparecer la radiancia reflejada, ... L_r "

Por cierto, en la bibliografía citas mis apuntes de RIG, así:

Carlos Ureña. 2021. “Realismo e iluminación global.” 2021. https://lsi2.ugr.es/curena/.

Deberías poner:

Carlos Ureña. 2021. “Apuntes del curso: Realismo e Iluminación Global (Máster en Desarrollo de Software de la Univ. de Granada)” 2021.

me doy cuenta ahora mismo que has ordenado alfabéticamente las citas usando el nombre de pila del 1er autor en muchos casos (como este), esto no es para nada lo usual, debes usar ordenación por el 1er apellido, no el nombre de pila.

(38) (para insertar una nueva sección entre las actuales secciones 3.2 y 3.3 de este documento)

Como te he escrito, los métodos de Monte-Carlo para aproximar la rendering equation son variantes de una técnica general que se conoce con el nombre de "Markov Chain" o "Cadenas de Markov". Las técnicas basadas en Markov Chains sirven en general para aproximar ecuaciones integrales, y la "Rendering Equation" es una variante de un tipo de ecuación integral. En esta memoria hablas de los métodos de Monte-Carlo para aproximar integrales, pero no para aproximar funciones que son soluciones de ecuaciones integrales. Así que creo que habría que insertar una nueva seción donde en general hables de cadenas de markov y de como se pueden usar para solucionar ecuaciones integrales. Esto es la base formal matemática de Path-tracing. Afortunadamente, he encontrado un paper no muy complicado ni muy largo que da las claves de este tema, y en el que tu puedes basar para escribir esta sección. No tienes que entrar a fondo, ni tiene que ser muy largo, simplemente introducir lo que es una Cadena de Markov, una ecuación integral (en concreto una ecuación integral de Fredholm de 2 tipo, "Fredholm Integral Equation of the second kind"), y como se pueden obtener estimadores para la función solución de la ecuación integral. Creo que puede caber todo en un par de páginas. El artículo al que me refiero es este :

R. Farnoosh, M. Ebrahimi, Monte Carlo method for solving Fredholm integral equations of the second kind, Applied Mathematics and Computation, Volume 195, Issue 1, 2008, Pages 309-315, ISSN 0096-3003, https://doi.org/10.1016/j.amc.2007.04.097.
(https://www.sciencedirect.com/science/article/pii/S0096300307005541)

En el paper se trata un caso sencillo genérico en el cual la ecuación integral que resuelve tiene como dominio el intervalo [0,1] en R, en lugar del dominio de la función de radiancia (que es el espacio multidimensional de todos los puntos y direcciones). Pero el paper da las ideas clave generales de como se aproxima una función que es solución de una ecuación integral con métodos de Monte-Carlo, usando cadenas o "paths" de puntos del dominio. No entiendo muy bien como este paper se publica como en 2008 como un trabajo original con revisión por pares, ya que lo que dice son cosas conocidas desde los años 60 por lo menos (ver: https://physicstoday.scitation.org/doi/10.1063/1.3022338, año 69, o mejor https://epubs.siam.org/doi/pdf/10.1137/0704029, del 67), pero el caso es que nos viene de perlas.

En el paper, en la ecuación (1):

  • 'u' es la función desconocida (en la rendering equation (RE) 'L', la radiancia, cumple el papel de 'u', ya que 'L' es la función que no conocemos y queremos calcular),
  • 'k' es el 'kernel' (en la RE la BRDF 'f_r' cumple el papel de 'k'), y
  • 'f' es la función conocida (en la RE es la radiancia emitida, L_e, conocida).

El paper muestra como construir secuencias de puntos aleatorios en [0,1] para aproximar el producto escalar de 'u' y otra función, al igual que en rendering aproximamos el valor promedio de la radiancia en un pixel (es el producto escalar de la radiancia y la función de pertenencia al pixel). Las secuencia de valores del paper se corresponden con las secuencia de puntos que forman un path en rendering. De todas formas, en esta nueva sección no es necesario que hagas mención a nada de rendering, solo contar como se puede estimar el producto escalar de 'u' y otra función 'h' (en particular, si usamos una delta Dirac en lugar de 'h', se pueden estimar valores puntuales de la función 'u').

Asumo que una vez que los escribas, probablmente quieras que lo vea la co-tutora, ya que forma parte de la parte "matemática" de la memoria. Si tienes cualuquier duda, me escribes.

Notas de Carlos (7 de junio de 2022)

Versión del PDF: descargada el 2 de junio

(39), sección 4, página 82

Donde dices "La implementación estará basada en Vulkan, junto a ...." habría que incluir una referencia al repositorio y carpeta concreta que has usado como base. El repositorio se llama 'nvpro-samples', pero además la carpeta concreta con el ejemplo se llama 'ray_tracing_gltf', si no me equivoco, es esta URL la que se debe incluir:

https://github.com/nvpro-samples/vk_raytracing_tutorial_KHR/tree/master/ray_tracing_gltf

(en la sección 4.1 tienes una cita a "Nvidia 2022a", pero eso tiene la URL del repositorio completo, creo que sería bueno señalar este ejemplo concreto).

(40) secc. 4.1.1, página 82

En la ecuación de esta página cos\theta_i debe aparecer en valor absoluto, al igual que en la ecuación 2.14, ya que estás integrando en la esfera. Donde dices "recordemos que Lo es la radiancia emitida ...", deberías usar "reflejada" en lugar de "emitida", ya que esa integral solo incluye la radiancia reflejada.

(41) secc. 4.1.1, página 83

En la 1a ecuación de esa página, llamas 'L_o' a otra cantidad distinta de la que has usado en la página 82. Lo usual es llamar a esto de la página 83 simplemente "L". Sería conveniente decir que este "L" es la radiancia total saliente (emitida más reflejada) desde p en la dirección de w_o. En esa ecuación, a la izquierda del '=' sobra la flecha y la variable 'w_i'

(42) secc. 4.1.1, página 83

En la fórmula 4.1, inmediatamente después), habría que aclarar o recordar al lector que cosa es la función 'p' del denominador (es la pdf correspondiente a la selección aleatoria de una dirección de salida 'w_j') y que cosa es L_i. Ahora que lo veo, en estas fórmulas estás usando 'p' para dos cosas y puede ser confuso, quizás el punto 'p' podría renombrarse como 'x', es lo usual, y dejar la pdf como 'p'.

(43) secc. 4.1.1, página 83

En la última frase de esa página, donde dices "no será necesario", creo que lo correcto es decir que "no será posible", es decir, para otros tipos de BRDFs, distinta de la difusa, algunas veces no podemos encontrar una forma de hacer muestro por importancia tan simple, en el cual la PDF sea exactamente proporcional a la BRDF.

(44) secc. 4.1.2, página 84

El listado de la página 84 parece más código concreto en algún lenguaje de programación, que pseudo-código, el pseudo-código suele escribirse en estos textos usando el package latex 'algoritmic' o 'algoritmicx', y no debe hacer mención a funciones o tipos de datos que no aparecen explicados en el código o en el texto. En tu caso usas 'hit_info', 'siguiente_direccion' y cosas así. Además, no queda claro en que contexto se ejecuta la función 'pathtrace', que cosa devuelve, etc...Creo que puedes usar directamente o basarte en el pseudo-código de un path-tracer básico que aparece en las transparencia 35 y 36 del archivo 'rig-t3b-monte-carlo-1.pdf' que te envié por mail el pasado 5 de mayo, es un pseudo-código de un path-tracer básico que no hace muestreo directo de fuentes de luz. En este punto se trata simplemente darle al lector una idea de la estructura del algoritmo de path-tracing, sin que todavía hayas introducido nada sobre shaders en ray-tracing (hit, miss shader, etc...).

Una cosa a aclarar en algún sitio es que en la fórmula 4.1 aparece una sumatoria, pero en este código se usa N=1, ya que en path-tracing cuando se genera un camino, cada rayo (distinto del último) solo da lugar a otro rayo, no N de ellos.

En el último párrafo de esa página hablas del "closest hit shader", pero no has introducido antes que cosa es el closest hit shader. Como te he comentado, el pseudo-código no debe usar nada de shaders, lo de los shaders es algo que introduces más tarde, cuando hablas de como ese pseudo-código se implementa en Vulkan ray-tracing.

Puedes introducir aquí código genérico (pseudo-código) y pasar este código concreto a un punto posterior de la memoria donde ya hayas hablado de la estructura de un path-tracer y hayas introducido que cosa son los shaders.

(45) secc 4.1.3, página 85

Este listado y el texto tienen el mismo problema que el de la página anterior, hablas, por ejemplo, de "hit payload" cuándo al lector le falta información para entender qué cosa es esa.

En estas página 84 y 85, hablas de que la versión recursiva es más lenta, supongo que la gestión de la pila en la GPU no es tan eficiente como en la CPU, pero si eso es cierto deberías aclararlo.

(46) sección 4.2, página 87

Dices que un sistema de rendering en tiempo real tiene hasta 16 milisegundos por cuadro, pero en realidad eso corresponde obviamente a 62 cuadros por segundo, pero creo que en realidad un juego o aplicación a 30 fps (33 ms por cuadro) ya va bien.

(47) sección 4.2.1, página 87

Aquí enumeras las tarjetas que dices que son necesarias para hacer ray-tracing en tiempo real, pero en mi opinión esa afirmación debe ser matizada, se puede hacer ray-tracing en tiempo real a 30 fps o 60 fps usando una GPU mucho más antigua que esas, con el ray-tracing implementado en GLSL en el fragment shader (usando el cauce de rasterización), siempre y cuando la complejidad de la escena (en términos de número de triángulos o primitivas) sea baja. Por tanto, yo cambiaría la afirmación "tajante" por otra mas matizada en la que hables simplemente de que con esas GPUs se puede hacer real time ray-tracing es escenarios muy complejos.

(48) sección 4.3, página 90

Como te he comentado antes, creo que, dentro del repositorio 'vk_raytracing_tutorial_KHR' te has basado principalmente en el ejemplo en la carpeta 'ray_tracing_gltf', si eso es cierto, debes referenciar aquí esa carpeta en concreto (si te has basado principalmente en otro ejemplo, indica cual es la carpeta concreta)

(49) sección 4.3.1, página 91

Donde dices "La estructura final del proyecto", creo que lo correcto sería decir "La estructura final de las carpetas del repositorio con el código fuente del proyecto..."

(50) sección 4.5, página 95

La frase "son similares a los grafos de escena en rasterización" no es correcta, en realidad el grafo de escena constituye el modelo de escena tanto en rasterización como en ray-tracing. Lo que pasa es que la indexación espacial en ray-tracing se puede hacer tomando como base el propio grafo de escena, y en este caso no hay grafo de escena sino simplemente una secuencia (un array de objetos)

Donde dices "resulta más eficiente hacer la intersección", deberías indicar se trata de eficiencia en tiempo y explicar brevemente (un párrafo) a qué se debe esto (las cajas englobantes permiten evitar muchas intersecciones rayo-triángulo si el rayo no interseca un volumen que engloba a un conjunto de triángulos, explicarlo).

Sería conveniente citar el artículo de Kay & Kajiya, este:

Timothy L. Kay and James T. Kajiya. 1986. Ray tracing complex scenes. In Proceedings of the 13th annual conference on Computer graphics and interactive techniques (SIGGRAPH '86). Association for Computing Machinery, New York, NY, USA, 269–278. https://doi.org/10.1145/15922.15916

(51) sección 4.5.1, página 96

donde dices "almacenan la geometría de un objeto individual" debería aclarar que se entiende por un "objeto individual" en este contexto, supongo que se refiere a una malla de triángulos almacenada en la GPU usando un buffer de vértices y atributos, si es así hacerlo explícito (creo que es así por lo que leo aquí: https://nvpro-samples.github.io/vk_raytracing_tutorial_KHR/)

(52) sección 4.6.2, página 99

en la explicación de la figura 4.6, se debe indicar para que sirve el "intersection shader", ¿ es el código que se encarga de calcular intersecciones de un rayo con un triángulo ? ¿ o con un grupo de ellos ? (aclararlo). Como te comento a continuación, sería mejor explicar los distintos tipos de shaders (subsección 4.6.2) antes de hablar de la "shader binding table".

(53) sección 4.6.2, página 100

Aquí mencionas los tipos de shaders que todavía no has explicado, esto no es lógico, creo que sería mejor reorganizar para que, en primer lugar, introduzcas los tipos de shaders (sección 4.6.3) y luego hables de la "shader binding table". Esta relacionado con el punto (41), donde también se habla de que no se deben usar conceptos clave, como el de un shader, si no se han explicado antes.

¿ Qué es "Callable group record" ? (no lo explicas, si es un concepto importante, explícalo, en otro caso, si no es importante, quita eso).

No entiendo la frase "En particular, resulta problemático de los índices en los hit groups."

La figura 4.7 no está explicada y no se puede entender, creo que sería conveniente explicarla o bien quitarla, si los enlaces que indicas te parecen suficientes.

(54) sección 4.6.3, página 101

Donde dices "Idealmente, solo se invocan rayos desde aquí", no queda nada claro que cosa es "invocar un rayo".

Donde dices "cuando un rayo impacta con la geometría por primera vez", creo que te refieres a la intersección rayo-objeto más cercana al origen del rato ¿ es así ? (si es así aclararlo).

Creo que no es necesario la frase "pega con el infinito"

Donde hablas de los "callable shader", me da la sensación de que estos shader simplemente contienen funciones que se pueden invocar desde otros shaders ¿ es así ? (si es así, escribirlo explícitamente, más o menos es lo que dices, pero creo que debes mencionar que se trata de llamar a funciones).

(55) sección 4.6.4, página 101

Dices que son necesarios mecanismos para pasar información de un shader a otro, pero hablas entre otras cosas de las "push constants", que permiten pasar parámetros desde la aplicación en la CPU a los shaders en la GPU (no de un shader a otro).

(56) sección 4.7, páginas 103 y 104

no me queda claro cómo se asocian los parámetros a cada objeto del archivo wavefront, es decir, ¿ cada objeto tiene un conjunto de valores para K_a, K_d, K_s, etc.... ? o bien ¿ cada objeto tiene un entero 'illum' y luego hay un catálogo, el cual, para cada entero, se proporcionan los valors de 'K_a', 'K_d', 'K_s', etc....?

Otra cosa: en la tabla de la 103, no se en qué se diferencian el "cristal" de la "refracción" en la última columna (el cristal refracta la luz), y en la columna penúltima, tampoco entiendo la diferencia entre 'Ray traced' y 'Sí'.

En la página 104 aparece la última entrada y pone "sombras arrojadizas" donde debería poner "sombras arrojadas". De todas formas no entiendo muy bien esa entrada ¿que significa "sombras arrojadas" ahí en ese contexto ? (las entradas anteriores de la tabla describen tipos de materiales, pero "sobras arrojadas" no es un tipo de material...)

(57) sección 4.8, página 104

"fuentes de luces" debería ser "fuentes de luz"

(58) sección 4.8, páginas 104 y 105

Dices que se preparó el pipeline para fijar la etapa de los rayos de sombra, pero no se muy bien donde en el texto describes esto (me suena que no está, pero puedo equivocarme), si está ya descrito, incluye una referencia, si no está descrito antes, incluye una explicación de la frase o incluye un texto al respecto donde introduces el "pipeline" de ray-tracing.

(59) sección 4.9, páginas 107 y 108

En esta sección describes dos cosas independientes: por un lado el uso de supersampling antialiasing (SSAA) con jittering (promediar 'nb_samples' muestras por pixel por cada cuadro), y por otro el uso de acumulación temporal (promediar el valor calculado en cada pixel a lo largo de los ultimos cuadros desde que se paró la camara). La primera caja de código de la página 108 tiene, en las líneas 4 a 6, el SSAA, y en las líneas 10 a 22, la acumulación temporal.

El primer párrafo de la página 107 describe el "supersampling antialiasing mediante jittering", al final dices "A este proceso lo llamamos acumulación temporal", pero no es así, por un lado debes nombrar explicitamente lo de "supersampling antialiasing" (es necesario ya que hay otras formas de antialiasing, distintas de supersampling), y por otro lado te falta describir la "acumulación temporal".

Supongo que lo sabes, pero en cualquier caso la acumulación temporal consiste en promediar el color calculado para un pixel a lo largo de varios cuadros, en concreto desde que se paró la cámara, es decir, desde que el color objetivo o real del pixel no ha cambiado por permanecer la cámara en el mismo sitio. La gran ventaja es que de esta forma, cuando la cámara se para, la imagen va mejorando en calidad, ya que con cada nuevo cuadro se promedian más muestras por cada pixel, al tener en cuenta, para cada pixel, no solo las del cuadro actual, sino también las de los otros cuadros (en total usas 'nb_samples*nf', donde nf es el número de cuadro desde que la camara está quieta). Todo esto debe aparecer reflejado explícitamente en tu texto.

Viendo el código de la página 108, veo que cuando 'pcRay.cuadro' vale 0 (en la línea 7 de la caja de abajo), siempre se muestrea el punto central al pixel, es decir, las llamadas a 'sample_pixel' de la línea 5 (de la caja de arriba) van a devolver todas el mismo valor, luego en ese 1er cuadro se está haciendo trabajo repetido sin mejora de calidad. En realidad, siempre puedes usar los valores aleatorios r1 y r2, incluyendo el 1er cuadro.

(60) sección 4.10, páginas 108 a 111

En el 1er párrafo introduces el problema del rango dinámico (no acotado 'a priori', fuera de [0,1]) de los valores que produce el cálculo de iluminación, y luego dices que "esto lo arreglamos con la correción gamma", pero el problema de los valores fuera de rango (mayores que uno) no se soluciona con la correción gamma. Puedes ver esto que digo sin más que pensar que cualquier valor 'x' mayor estricto que uno, al elevarlo a una potencia positiva cualquiera, te va seguir dando un valor mayor que uno (y si es menor antes, también lo será después). Luego si un valor R,G o B es superior a la unidad y debe ser truncado, después de la correción gamma va a seguir siendo superior (o inferior) y debe ser truncado

En realidad estás hablando aquí dos dos cosas distintas: por un lado de como se soluciona el problema de los valores fuera de rango [0,1], y por otro lado de como se mapean los valores RGB al monitor (usando una función no lineal como la correción gamma). Para el primer problema usas simplemente un truncamiento, para el segundo usas la corrección gamma con exponente 1/2.2

En el código entre las páginas 110 y 111 parece que usas la corrección gamma antes de hacer la suma (el 'mix') de la acumulación temporal, creo que esto no es correcto, la corrección gamma se debe hacer al final, cuando ya has calculado el valor RGB del pixel. Obviamente la suma no conmuta con la exponenciación, por eso únicamente se puede hacer la corrección gamma como ultimo paso de cálculo de la imagen.

Yo creo que sería mejor aplicar la corrección gamma después de normalizar (dividir por el máximo valor), en lugar de después de truncar (creo que ya te he hablado de eso), el problema es que en este cuadro de Vulkan quizás calcular ese valor no sea sencillo (habría que mirar todos los pixels de la imagen en cada cuadro), aunque podría hacerse con un compute shader específico que haga ese cálculo (los compute shaders se pueden combinar en un programa de ray-tracing, aquí hay un ejemplo en el cual se usan para ray-tracing: https://nvpro-samples.github.io/vk_mini_path_tracer/#computeshaders/usingcomputeshadersforraytracing, aquí no haría falta usarlos para ray-tracing, simplemente sería para calcular el máximo de una imagen en paralelo). De todas forma entiendo que esto es complicado teniendo en cuenta el tiempo que queda para la entrega.

Por ultimo, sería conveniente usar la misma cámara y la misma escena en las figuras 4.8 y 4.9, ahora mismo las imágenes son diferentes, por ejemplo la esfera de la derecha aparece proyectada mucho más grande en la 4.8 que la 4.9, además los bordes de las sombras no van igual (no me refiero a diferencias de intensidad por diferencias en la corrección gamma, me refiero a que las sombras van por distintos sitios).

(61) sección 5 páginas 112 y siguientes

En esta sección aparecen imágenes (por ejemplo, la 5.1, 5.2, 5.27) las cuales parecen estar iluminadas con una luz de área rectangular del techo, como es habitual en esta escena en la literatura ¿ implica esto que el programa es capaz de hacer path-tracing con fuentes de área ? me ha parecido leer antes que no es así, esto se debe aclarar. Otro ejemplo es la imagen 5.25, en la cual hay una fuente puntual que produce sombras arrojadas, pero es que además la esfera especular proyecta una sombra de borde suave en el suelo que parece estar creada por la fuente de luz en el techo .... perdón, ya caigo: el programa gestiona fuentes de área (en la escena) y fuentes puntuales (o direccionales, en las push-constants), lo que pasa es para las fuentes de área no se hace muestro directo de las fuentes de luz y para las otras sí. Por tanto, en todas las escenas donde aparece la fuente rectangular del techo, se está teniendo en cuenta correctamente la luz de esa fuente, ya que en cada impacto sumas L_e ¿ no es así?. Quizás esto debe ser aclarado en la sección 4.8, página 104.

La verdad es que el muestreo directo de las fuentes de luz se puede extender muy fácilmente a una o unas pocas fuentes de luz de área, sin más que pasar los atributos de esas fuentes de luz como push constants, igual que haces con los otros tipos de fuentes. En ese caso, bastaría con no añadir L_e en los puntos de impacto (excepto los de los rayos primarios). De todas formas entiendo que es un poco tarde para esto.

(62) sección 5.3.1, página 128

Respecto a la dependencia del tiempo medio por cuadro 't' respecto del numero de muestras por pixel 'n', supongo que será de la forma t=an+b, para dos valores a y b que dependen de la escena. Se pueden calcular los valores de 'a' y 'b' para alguna escena, 'a' representa los costes fijos por cuadro y 'b' los costes por path. Si esto es así, la frase donde dices que el coste medio por cuadro es 2 milisegundos es incorrecta (divides t por n), ya que eso solo sería correcto si 'a' es 0 (o casi 0 comparado con 'b'), pero probablemente no lo sea ¿ o si ? (sería interesante medir 'a' y 'b' para alguna escena y aclarar esto)

(63) sección 5.3.1, página 131

El mismo análisis que he hecho en el punto anterior (59) se aplica a la dependencia del tiempo respecto de la profundidad o longitud de los caminos, cuando esta se elige de forma fija.

(64) General

Un cosa que veo en este texto, en general, es que usas palabras del inglés que tienen una traducción fácil y bien establecida a nuestro idioma, este ejemplo está tomado de la página 106 (al final) y 107 (al inicio), escribes:

"Al preparar la pipeline fijamos el stage de los shadow rays"

Pero en mi opinión, se debería escribir:

"Al preparar el cauce fijamos la etapa de los rayos de sombra"

esto se debe revisar en todo el texto y para muchas palabras. Algunas veces no te queda más remedio que usar una palabra en inglés de todas formas, en esos casos creo que queda mejor si las pones en cursiva para reflejar que es una palabra de otro idioma.

[👷🏼] La integración continua se ha roto

El commit fe92817 arregla el problema. Tengo la sensación de que el error viene al clonar actions@checkout por HTTPS para evitarse problemas con las claves y similares. Pero si quieres hacer commits, la cosa se complica un poco más. Habrá más formas de arreglar esto, como decirle que utilice SSH o indicar que el repositorio es seguro.

No me he parado mucho a leer, pero he visto este issue: actions/checkout#766

Copio el mensaje que he escrito con respecto al tema en un grupo de chat:

Andrés Millán, [20/05/2022 12:06]
Buenos días! Acabo de solucionar un problema de integración continua que quizás os pueda afectar a varios de aquí, así que os lo comento:

Parece ser que en un parche de seguridad de git han cambiado cómo funciona el clonado por HTTPS. Esto afecta a algunos servicios de integración continua. En mi caso, un Action dejó de funcionar. Al intentar hacer un commit al repo desde el Action daba el error fatal: not in a git directory. Resulta que si haces un git status, te dice

fatal: unsafe repository ('/__w/Raytracing/Raytracing' is owned by someone else)
To add an exception for this directory, call:

  git config --global --add safe.directory /__w/Raytracing/Raytracing

No he visto ninguna información sobre esto en el repositorio de actions@checkout aparte de un issue suelto. Quizás el error venga porque el action intenta utilizar el git del contenedor. En cualquier caso, haciendo lo que dice el output se arregla (usando vuestro repo, claro).

El nombre del repositorio es algo confuso

Unas cuantas letras aleatorias no aportan mucho.

Aunque TFG sobre RT en VkRay sea más correcto, entorpece a los usuarios que quieran visitarlo. Hasta yo me confundo a veces.

Algo más sencillo como Raytracing sería lo suyo.

[📓] La memoria no cumple con los requisitos

Enlace a los requisitos

La memoria debe tener...

  • Resumen y palabras clave. Al menos, 5 palabras clave que definan el trabajo a criterio del autor.
  • Resumen extendido en inglés, con una longitud mínima de 1500 palabras. Deben aparecer las palabras clave también.
  • Introducción
    • Contextualizar el trabajo, explicando antecedentes importantes para el desarrollo realizado y efectuando un estudio de los progresos recientes
    • Describir el problema abordado, de forma que el lector tenga desde este momento una idea clara de lo que se quiere resolver; así como una visión de la solución.
    • Exponer con claridad las técnicas y áreas matemáticas, así como los conceptos de ingeniería informática empleados.
    • Sintetizar con claridad las técnicas y áreas matemáticas, así como los conceptos y herramientas de la informática.
    • Sintetizar el contenido de la memoria.
    • Citar principales fuentes consultadas.
  • Objetivos del trabajo:
    • Exponer los objetivos inicialmente previstos en la propuesta del TFG y los que se han alcanzado, indicando dificultades y cambios.
    • Si procede, conectar lo anterior con los apartados de la memoria correspondientes.
  • Desarrollo del trabajo
    • Debe tener dos subapartados como mínimo: uno matemático, otro informático.
  • Conclusiones y vías futuras.
    • Indicar si se han conseguido los objetivos, solo parcialmente, o no.
    • Vías futuras.
  • Bibliografía final
    • Se recomienda un breve comentario de las referencias.
    • En el caso de incluir URLs de páginas web, deberán ir acompañadas de título, autor y fecha de último acceso entre otros datos.
  • En el caso en el que se desarrollo software...
    • Planificación temporal (con sus fases y tareas), y posterior comparación los datos reales tras realizar el proyecto.
    • Presupuesto del trabajo.
    • Análisis y diseño: especificaciones de los requerimientos y metodología de desarrollo, así como los planos del proyecto que contendrán las historias de usuario o casos de uso, diagrama conceptual, de iteración, de diseño, esquema arquitectónico y bocetos de las interfaces de usuario. Se describirán las estructuras de datos no fundamentales y algoritmos no triviales.
    • Implementación y pruebas.
    • Incluir código junto a la memoria y un manual de instalación.

[📓] Creación de comandos para LaTeX

Sería conveniente crear algunos comandos para facilitar la escritura. Por ejemplo, barras verticales de evaluación para integrales:

  • \newcommand*\Eval[3]{\left.#1\right\rvert_{#2}^{#3}} (ver)
  • Valor absoluto (link)
  • $\set{}{}$.
  • $\norm{}$.
  • $\set{}$.
  • $\Prob{}$, $\E{}$, $\Var{}$

[📓] Feedback del capítulo de Monte Carlo

En este issue se recogerá el feedback provisto por diferentes personas. Este comentario se actualizará poco a poco.

  • Repetición de palabras: Una variable aleatoria puede clasificarse en discreta o continua, dependiendo de cómo sea su rango (...): discretas o continuas.
  • El ejemplo de discreta no está suficientemente claro image
  • Superíndice no tiene sentido image
  • La introducción al estimador necesita trabajo (mira el correo del 25/04/2022 de Mari Carmen)
  • El párrafo de la memoria que describe "next event estimation" no es muy exacto.
    El nombre "next event estimation" ignora el trabajo previo donde se explican estas cosas, ya Peter Shirley lo llama "explicit direct lighting calculation" (ver: http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.8.6793&rep=rep1&type=pdf, figura 2, página 7)

[👷] Falta Python en Dockerfile

build-web da el siguiente fallo:

Run cd docs
Compilando index.html...
Terminado.
pandoc --from markdown --listings --top-level-division="chapter" --filter ./headers/pandoc_eqnos.py --citeproc --bibliography ./chapters/bibliography.bib -s --toc --mathjax --lua-filter ./headers/standard-code.lua  --pdf-engine=xelatex -o index.html ./headers/meta.md ./chapters/00-dedicatoria.md ./chapters/01-introduccion.md ./chapters/02-notacion.md ./chapters/03-fundamentos.md ./chapters/04-montecarlo.md ./chapters/09-metodologia.md ./chapters/10-cheatsheet.md ./headers/web.md
Error running filter ./headers/pandoc_eqnos.py:
Could not find executable python
make: *** [Makefile:72: web] Error 83
Error: Process completed with exit code 2.

Esto viene por el arreglo de #36

[✨] Path tracer básico

Esta es una decisión importante.

Ahora mismo (2022/02/18, v. 0.2) solo tenemos un ray tracer básico, que implementa ray traced shadows. En resumidas cuentas, una plantilla para trabajar.

Los shaders están adaptados para tratar materiales lambertianos muy básicos. Además, no muestreamos diferentes fuentes de iluminación. Debemos tomar una decisión sobre cómo proseguir.

El mejor camino parece usar la extensión del nvpro-tutorial, que implementa un path tracer básico. Juntándolo con oclusión ambiental + reflejos, podríamos tener un buen punto de partida. Esto permitiría desembocar en el repositorio vk-raytrace, que añade materiales más complejos.

Otra opción sería adaptar el mini path tracer. Quizás podamos tomar prestadas algunas ideas cuando tengamos el anterior listo.

[📓] Definir productos mínimamente viables

Aunque más o menos se ha seguido una idea fija de desarrollo, sería conveniente formalizar unos milestones. Ayudaría a centrar la atención a las partes específicas del proyecto.

Estado de la aplicación

En este issue detallaré lo que se ha implementado, y algunos detalles que creo que se deben perfeccionar.

Lo que tenemos

Con respecto a las escenas, actualmente se visualiza lo siguiente:

Cornell Box original

Cornell Box original, sin luz:

Cornell Box original, con luz puntual:

image

Cornell Box original, con luz direccional:

image

La iluminación global funciona como es debido en este caso:

image

Cornell Box con esferas reflectantes y refractantes

Sin luz:

image

La pelota de la derecha utiliza las ecuaciones de Fresnel para la refracción

image

Las luces funcionan de manera análoga al anterior caso

image

Cornell Box mirror

image

Cornell Box glossy

Para los materiales glossy, he decidido usar una pequeña jugarreta con el exponente especular para hacerlos similares a materiales metálicos:

image

Medieval building

Las texturas también cargan correctamente

image

Cube reflective

Los espejos tienen limitados el número de rebotes mediante la profundidad del rayo. Tengo un bug en la BRDF que no soy capaz de acertar, pero estoy bastante seguro que es debido al cálculo de la iluminación directa en el closest hit shader

image

Cornell Box saturada

Para comparar el ruido de la foto, podemos usar los parámetros de acumulación temporal y número de muestras por píxel:

100 frames de acumulación, 5 muestras/píxel 200 frames de acumulación temporal, 20 muestras/píxel:

Lo que falta:

  • Luces de área: implementación a medias (#32).
    • Para evitar reimplementar toda la interfaz de iluminación estática, he decidido suponer que las luces de área tienen ciertas propiedades constantes (como radio, área o similares) y jugar con eso.
    • Utilizan las push constants como las otras luces.
    • Uso la normal al plano para indicar hacia dónde apuntan. Por motivos de alineamiento de las PC, no puedo usar vectores, así que se pasan como 3 floats.
    • Tengo problemas para generar un punto aleatorio en el área correspondiente al plano de la fuente.
    • No sé si dará tiempo a terminarlas.
  • Light sampling hecho y derecho: para calcular la iluminación directa, la implementación actual utiliza un híbrido entre BRDF sampling y light sampling. No guardo información de los materiales emisivos de la escena, por lo que sigue habiendo acumulación para la iluminación global. Por ello, hay presencia de zonas con mucho ruido a la vez que existen otras zonas de la imagen nítidas.
  • Los materiales especulares no son del todo fieles (#35).
  • No hay muchos ejemplos de importance sampling.
  • Habría que revisar los materiales especulares y transmisivos.

[✨] Antialiasing

Seguir tutorial de Jitter camera para tener antialiasing y acumulación de frames.

Necesitaremos este último concepto para otros tutoriales.

[🐛] El modelo de la Cornell Box es incorrecto

Ahora que el código ha sido refactorizado, es fácil encontrar el fallo. El modelo actual tiene los siguientes parámetros para la luz:

newmtl light
Ka 20 20 20
Kd 1 1 1
Ks 0 0 0

Lo cual no tiene sentido. ¡Falta la componente emisiva Ke! Eso explica por qué ha costado tanto la implementación de diversos materiales.

Podemos sacar varios modelos de CB de este repositorio, el cual utiliza las extensiones para PBR. Además, añade diferentes tipos de materiales, lo cual vendrá de perlas para hacer pruebas.

Para que funcione correctamente, hará falta modificar el closest hit para calcular correctamente el color. Esto debería solucionar problemas varios.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.