Sign in to follow this  

classical ray tracing

Recommended Posts

I'm following the book "Object-Oriented Ray Tracing in C++" by Nicholas Wilt. His lighting model includes the sum of ambient, diffuse, specular, reflective, and refractive light. This seemed to be working okay until I tried to model shallow water. Since the water is very shallow, I mainly made it refractive. The problem is that it also needs to have some diffuse or else you can't make out the shallow waves. But this is a problem because as I increase the diffuse, the color adds in to the refractive color, making it look less refractive. It seems what I really want to do is mutliply the refractive color contribution by dot(L,N) (N is normal, L is light vector) so that I still get the light and dark shape of the waves. But according to Wilt's model, the refractive component isn't multiplied by dot(L,N). Any advice appreciated.

Share this post

Link to post
Share on other sites

You should never have diffuse at all on something like water. What you want to do is fade between reflected and refracted rays, depending on the fresnel term (maybe with phong highlights thrown in so the light sources show up in the reflections). The 'diffuse' appearance will come from the reflection of the sky and surrounding geometry.


Share this post

Link to post
Share on other sites
Water is a dielectric (it doesn't conduct electricity), meaning its appearance is a fresnel blend between reflection and transmission (no diffuse!)

For shallow water you want to do exactly that:

// Calculate coefficient of reflection using fresnel equation
float eta = 1.34;
float kr = fresnel( wo, n, eta );
// Get a reflection vector and trace for reflections. This should include reflections of the light source
V3f wi = reflect( wo, n );
Col3f Lrefl = traceRelfection( wi );
// Get a refraction vector and trace for transmission
wi = refract( wo, n, eta );
Col3f Ltran = traceRefraction( wi );
// Blend between reflection and transmission using the coefficient of reflection calculated earlier to get the final colour
Col3f L = lerp( Ltran, Lrefl, kr );

You'll also probably want to use beer's law to attenuate the transmissive light over distance to get that "murky" feeling.

For deep water, there's little point casting refraction rays, since the attenuation due to the water means you'll never see anything (unless you want to put in fish etc), The deep blue/green colour comes from scattered light beneath the surface. You could either acccount for this by tracing a refraction ray, then tracing rays back up to the surface towards the light source and accounting for attenuation, or just use a dot(n,wi) diffuse term as a kind of cheap hack.

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this