¿Es esta la forma correcta de implementar la Ley de Beer?

11

Cuando implemento la ley de Beer (absorción de color a distancia a través de un objeto), nunca se ve muy bien por alguna razón.

Cuando tengo el color detrás del objeto, calculo el color ajustado de esta manera:

const vec3 c_absorb = vec3(0.2,1.8,1.8);
vec3 absorb = exp(-c_absorb * (distanceInObject));
behindColor *= absorb;

Eso me dará algo parecido a esto (nota un poco de refracción aplicada): ingrese la descripción de la imagen aquí

Y aquí está sin refracción: ingrese la descripción de la imagen aquí

Tenga en cuenta que esto se implementa como un juguete de sombreador aquí .

Eso cumple con la descripción de lo que hace la ley de Beer, pero no se ve muy bien, no cuando se compara con disparos como este: ingrese la descripción de la imagen aquí

Dejando a un lado los detalles especulares, estoy tratando de descubrir la diferencia. ¿Podría ser que mi geometría es demasiado simple para mostrarla realmente bien? ¿O lo estoy implementando incorrectamente?

Alan Wolfe
fuente
2
Sin embargo, estás comparando un cubo con una malla más compleja. ¿Por qué no replicar el mismo escenario? El modelo Susan es fácil de conseguir.
Bart
¡No es tan fácil en una implementación sombreada! (:
Alan Wolfe
2
Tu cubo me parece correcto: consigue más transparente a medida que se acerca a los bordes. Si puedes hacer Suzanne en toda regla, una esfera al menos debería dar una mejor aproximación del aspecto en la otra imagen.
yuriks
1
No puedo separar la refracción de la atenuación. ¿Puedes renderizar el cubo con IOR = 1.0 por favor?
imallett
1
@AlanWolfe Su render IOR = 1 se ve exactamente como lo esperaría, y pasé por alto el sombreadoy impl y se ve bien.
imallett

Respuestas:

12

Su imagen definitivamente no se ve correcta, y parece que no está calculando correctamente la ruta interna de los rayos de luz a medida que viajan a través de su malla. Por lo que parece, diría que está calculando la distancia entre el punto donde el rayo de visión ingresa por primera vez al cubo y donde primero golpea la pared interior, y lo usa como su distancia de absorción. Esto supone esencialmente que la luz siempre saldrá del vidrio la primera vez que golpee una pared, lo cual es una suposición pobre.

En realidad, cuando la luz entra al vidrio desde el aire, a menudo no sale inmediatamente del vidrio. Esto se debe a que cuando la luz incide en la interfaz vidrio / aire, puede ocurrir un fenómeno conocido como reflexión interna total (TIR). La TIR ocurre cuando la luz viaja desde un medio con un índice de refracción más alto (IOR) a uno con un IOR más bajo, que es precisamente lo que sucede en el caso de que la luz golpee la pared interior de un objeto de vidrio. Esta imagen de Wikipedia es una buena demostración visual de cómo se ve cuando ocurre:

reflexión interna total

En términos básicos, lo que significa es que si la luz incide en un ángulo poco profundo, la luz se reflejará completamente en el interior del medio. Para dar cuenta de esto, debe evaluar las ecuaciones de Fresnelcada vez que su rayo de luz golpea una interfaz de vidrio / aire (también conocida como la superficie interior de su malla). Las ecuaciones de Fresnel le indicarán la relación entre la luz reflejada y la cantidad de luz refractada, mientras que será 1 en el caso de TIR. Luego puede calcular las direcciones apropiadas de luz reflejada y refractada, y continuar trazando el camino de la luz a través del medio o fuera de ella. Si asume una malla convexa simple con un coeficiente de dispersión uniforme, entonces la distancia a usar para la ley de Beer será la suma de todas las longitudes de camino interno antes de salir del medio. Así es como se ve un cubo con sus coeficientes de dispersión y un IOR de 1.526 (vidrio de cal sodada), renderizado usando mi propio trazador de ruta que tiene en cuenta las reflexiones y refracciones internas y externas:

cubo de vidrio trazado

En última instancia, los reflejos internos y las refracciones son una parte importante de lo que hace que el vidrio parezca vidrio. Las aproximaciones simples realmente no son suficientes, como ya lo ha descubierto. Se pone aún peor si agrega múltiples mallas y / o mallas no convexas, ya que no solo tiene que tener en cuenta los reflejos internos, sino que también debe tener en cuenta los rayos que salen del medio y entran en un punto diferente.

MJP
fuente
1
Here is what a cube looks like (...) using my own path tracer. ¿Por casualidad lo tienes de fuente abierta?
wip
2
No aún no. Estaba planeando terminar y lanzar esta variante en particular junto con una publicación de blog sobre renderizado de vidrio, pero ha estado en mi cartera por un tiempo.
MJP