Essa é a maneira correta de implementar a Lei de Cerveja?


11

Quando eu implemento a lei de Beer (absorção de cores à distância através de um objeto), ela nunca parece muito boa por algum motivo.

Quando tenho a cor atrás do objeto, calculo a cor ajustada assim:

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

Isso me dará algo parecido com isto (observe um pouco de refração aplicada): insira a descrição da imagem aqui

E aqui está sem refração: insira a descrição da imagem aqui

Observe que isso é implementado como um brinquedo shader aqui .

Isso cumpre a descrição do que a lei de Beer faz, mas não parece muito boa, não quando comparada a cenas como esta: insira a descrição da imagem aqui

Destaques especulares à parte, estou tentando descobrir a diferença. Será que minha geometria é muito simples para realmente mostrá-la muito bem? Ou estou implementando incorretamente?


2
Você está comparando um cubo com uma malha mais complexa. Por que não replicar o mesmo cenário? O modelo de Susan é fácil de obter.
21415 Bart Bart

Não é tão fácil em uma implementação shadertoy! (:
Alan Wolfe

2
Seu cubo parece correto para mim: fique mais transparente ao se aproximar das bordas. Se você puder fazer Suzanne completa, a esfera a deverá, pelo menos, dar uma melhor aproximação da aparência na outra foto.
yuriks

1
Não consigo separar a refração da atenuação. Você pode renderizar o cubo com IOR = 1.0, por favor?
imallett

1
@AlanWolfe Sua renderização IOR = 1 parece exatamente como eu esperava, e eu passei o dedo no shadertoy impl e parece bom.
precisa saber é o seguinte

Respostas:


12

Sua imagem definitivamente não parece correta e parece que você não está computando corretamente o caminho interno dos raios de luz enquanto eles viajam através da sua malha. Pela aparência, eu diria que você está calculando a distância entre o ponto em que o raio de visão entra primeiro no cubo e onde ele atinge a parede interior, e o usa como sua distância de absorção. Isso pressupõe essencialmente que a luz sempre sai do vidro na primeira vez que atinge uma parede, o que é uma suposição ruim.

Na realidade, quando a luz entra no vidro do ar, geralmente não sai imediatamente do vidro. Isso ocorre quando a luz atinge a interface vidro / ar, um fenômeno conhecido como reflexão interna total (TIR) ​​pode ocorrer. O TIR ocorre quando a luz viaja de um meio com um índice de refração mais alto (IOR) para um com um IOR mais baixo, que é precisamente o que acontece no caso de a luz atingir a parede interior de um objeto de vidro. Esta imagem da Wikipedia é uma boa demonstração visual de como é quando ocorre:

reflexão interna total

Em termos básicos, o que significa é que, se a luz atingir um ângulo raso, ela refletirá completamente no interior do meio. Para explicar isso, você precisa avaliar as equações de Fresneltoda vez que seu raio de luz atinge uma interface de vidro / ar (também conhecida como superfície interna da sua malha). As equações de Fresnel dirão a proporção da luz refletida para a quantidade de luz refratada, enquanto será 1 no caso de TIR. Em seguida, é possível calcular as direções adequadas da luz refletida e refratada e continuar a traçar o caminho da luz pelo meio ou fora dela. Se você assumir uma malha convexa simples com um coeficiente de dispersão uniforme, a distância a ser usada na lei de Beer será a soma de todos os comprimentos de caminho interno antes de sair do meio. Aqui está a aparência de um cubo com seus coeficientes de dispersão e o IOR de 1,526 (copo de soda), renderizado usando meu próprio traçador de caminho que é responsável por reflexões e refrações internas e externas:

cubo de vidro com traçado

Por fim, as reflexões e refrações internas são uma parte importante do que faz o vidro parecer vidro. Aproximações simples realmente não são suficientes, como você já descobriu. Fica ainda pior se você adicionar várias malhas e / ou malhas não convexas, pois você não só deve considerar as reflexões internas, mas também os raios que saem do meio e entram em um ponto diferente.


1
Here is what a cube looks like (...) using my own path tracer. Por acaso você tem código-fonte aberto?
Wip

2
Não, ainda não. Eu estava pensando em terminar e liberar essa variante em particular, juntamente com uma postagem no blog sobre renderização de vidro, mas ela está no meu backlog há um tempo.
MJP 03/09
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.