# Is this the correct way to implement Beer's Law?

When I implement Beer's law (color absorption over distance through an object), it never looks very good for some reason.

When i have the color behind the object, I calculate the adjusted color like this:

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


That will give me something that looks like this (note a little bit of refraction applied):

And here it is without refraction:

Note that this is implemented as a shader toy here.

That fulfills the description of what Beer's law does, but it doesn't look very good, not when compared to shots like this:

Specular highlights aside, I'm trying to figure out the difference. Could it just be that my geometry is too simple to really show it off very well? Or am I implementing it incorrectly?

• You're comparing a cube with a more complex mesh however. Why not replicate the same scenario? The Susan model is easy to get. – Bart Aug 20 '15 at 15:15
• It's not so easy in a shadertoy implementation! (: – Alan Wolfe Aug 20 '15 at 15:16
• You cube looks correct to me: Get more transparent as it approaches the edges. If you can do full blown Suzanne the a sphere should at least give a better approximation of the look in the other picture. – yuriks Aug 20 '15 at 15:51
• I can't separate the refraction from the attenuation. Can you render the cube with IOR=1.0 please? – imallett Sep 1 '15 at 16:19
• @AlanWolfe Your IOR=1 render looks exactly as I would expect it, and I skimmed the shadertoy impl and it looks good. – imallett Sep 2 '15 at 1:26

• Here is what a cube looks like (...) using my own path tracer. Do you happen to have open-sourced it by any chance ? – wip Sep 3 '15 at 2:53