noviembre 16, 2021

Raytracing en Evergine

render evergine

 

Introducción

Raytracing es una tecnología que nos permite mejorar el realismo de nuestro render. La tecnología más extendida de render en tiempo real es la rasterización donde, desde hace mucho tiempo, se trabaja para simular todos los detalles imaginables, como diferentes superficies, la luz, la sombra, el reflejo… Por otro lado, raytracing había sido una tecnología que nos permitía simular todos estos detalles del mundo real con una mejor aproximación, pero era muy costosa de utilizar en tiempo real.

En el año 2018, Nvidia lanzó su nueva serie de tarjetas gráficas con tecnología RTX que utiliza el hardware para reducir el coste de computación de la tecnología de raytracing. Eso nos permite utilizar el raytracing en tiempo real y nos ofrece una buena alternativa a la tecnología de rasterización tradicional.

Algunos efectos visuales como sombras suaves, reflexión en tiempo real o la iluminación global son efectos difíciles de implementar con la tecnología de rasterización tradicional, mientras que es posible conseguirlos con una implementación relativamente más sencilla utilizando raytracing.

En los años posteriores (2019, 2020 y 2021), el raytracing se está extendiendo a través de otros proveedores de tarjetas gráficas como AMD o Intel, por lo que el objetivo es que el raytracing sea la tecnología estándar en el futuro.

La tecnología de Raytracing es soportada en Evergine como parte de su API de bajo nivel. La API de bajo nivel es una interfaz común con las APIs gráficas más importantes como DX12, DX11, Metal, Vulkan, u OpenGL. Aunque el soporte de raytracing sólo está disponible en DirectX12 y Vulkan backend por ahora.

El equipo de Evergine ha unificado las APIs de DirectX12 DXR y Vulkan Raytracing en una API común. Por lo que, puedes escribir un proyecto usando la API de bajo nivel de Evergine y ejecutarlo en los backends DX12 o Vulkan más tarde.

Para mostrar las posibilidades de la API de bajo nivel de raytracing de Evergine, junto con el lanzamiento de Evergine, hemos creado una demo de Path Tracer que puedes descargar desde GitHub. Esta demo incluye algunos efectos interesantes como sombras suaves, oclusión ambiental, iluminación global y antialiasing implementados utilizando la tecnología de raytracing.

La siguiente sección explica cómo se implementó cada uno de estos efectos:

effects evergine

En primer lugar, la cámara lanzará un solo rayo por píxel; cada rayo puede golpear una superficie o no. Si el rayo golpea una superficie, el resultado del color se obtendrá del material de la superficie y si el rayo no golpea nada el resultado será el color de fondo.

Sombra suave

Para implementar las sombras en raytracing es necesario lanzar un nuevo rayo desde cada punto de impacto de la superficie hacia la luz. Si este nuevo rayo colisiona con algo antes de llegar a la luz, el rayo devuelve el valor «en sombra» de lo contrario devuelve el valor «en luz”.

shadows evergine

Este es el caso más sencillo y produce sombras fuertes, pero, para producir sombras suaves, hay que añadir algunas cosas más. Nuestra implementación consiste en lanzar varios rayos desde cada punto de la superficie hacia la luz (en esta demo utilizamos sólo una fuente de luz). La luz es esférica para simplificar y los rayos serán lanzados desde el punto de impacto de la superficie a la luz formando un cono.

Entonces el color de la sombra depende del resultado de combinar todos los rayos. Las zonas de penumbra son el resultado de cuando algunos rayos devuelven «en sombra» mientras otros devuelven «en luz».

soft Shadow Cone

En la siguiente imagen es posible ver las zonas de penumbra comparando las sombras producidas por la luz utilizando diferentes radios de luz.

Soft Shadow

Oclusión ambiental

La oclusión ambiental simula zonas que tienden a bloquear u ocluir la luz por tener un objeto cercano, de ahí que aparezcan más oscuras.

Nuestra implementación de la oclusión ambiental consiste en lanzar varios rayos cortos desde el punto de impacto de la superficie, en una semiesfera alineada con la normal de la superficie. Al igual que los rayos de sombra, estos rayos detectan si algo está cerca del punto y ocluyen los rebotes de luz.

ambient occlusion

En la siguiente imagen se puede ver los resultados utilizando diferentes longitudes de rayos de oclusión ambiental:

AO3 evergine

Iluminación global

El comportamiento de la luz en el mundo real podría simularse emitiendo rayos desde la fuente de luz que chocarán con una superficie. Una parte de la energía de este rayo es absorbida por la superficie y otra parte se refleja, creando un nuevo rayo de forma recursiva hasta que toda la energía del rayo inicial sea absorbida.

global illumination

Con el parámetro bounces, podemos simular cuántas veces un rayo de luz puede ser reflejado por las superficies. El color resultante de un rebote se añade al color de la superficie, produciendo, por ejemplo, que un objeto rojo cercano a otro contribuya a teñir de rojo el objeto cercano.

En la siguiente imagen es posible ver la salida de la iluminación global donde algunas áreas son teñidas por los colores de los objetos cercanos.

GI2 evergine

Antialiasing

El antialiasing consiste en eliminar los jaggies de la imagen. Estos jaggies se producen por la limitada cuadrícula de píxeles de la imagen de salida.

Para conseguir este objetivo necesitamos lanzar varios rayos desde la cámara por píxel y obtener un color medio como resultado. Cuando se lanza un solo rayo por píxel, la cámara lanza un rayo alineado con el centro de éste. Para implementar el antialiasing se lanzan varios rayos por píxel en una dirección aleatoria dentro del espacio del píxel. En nuestra implementación, estamos utilizando una secuencia Halton comúnmente utilizada para estos propósitos.

Antiailasing evergine

El resultado de la combinación de varios rayos por píxel se muestra en la siguiente imagen:

Halton Sequence evergine

Próximos pasos

Hoy en día, el raytracing es una tecnología en continua evolución, pero el resultado actual es muy impresionante y superior al resultado del renderizado por rasterización. Todos los motores gráficos modernos están en proceso de actualizar su render para usar raytracing, pero el coste de integración es alto y con el objetivo de seguir soportando tarjetas gráficas antiguas, el uso de raytracing es solo una alternativa. Una buena parte de los motores modernos está implementando un render híbrido usando rasterización y raytracing en su render.

Evergine es el primer motor C# con integración de raytracing. Nuestro objetivo es ofrecer a nuestros usuarios las últimas tecnologías gráficas para utilizar en sus proyectos o productos industriales.

Por nuestro roadmap, seguiremos trabajando en el raytracing para añadirlo a nuestra API de alto nivel y ofrecer también integración con Evergine Studio.

Jorge Canton
Author
Jorge Cantón
Plain Concepts Research
Categories