Skip to main content
gamedev.net
🔒 Locked

classical ray tracing

Started by Quat 2 replies 1k views
Original Post
Quat
Quat
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.
-----Quat
rapso
rapso
I think what u need is to add the "fresnel term" to your raytracer to get the right blending between ur refracting and the diffuse+specular colors.
jbarcz1
jbarcz1

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.

JB
Joshua Barczak3D Application Research GroupAMD
playmesumch00ns
playmesumch00ns
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 equationfloat eta = 1.34;float kr = fresnel( wo, n, eta );// Get a reflection vector and trace for reflections. This should include reflections of the light sourceV3f wi = reflect( wo, n );Col3f Lrefl = traceRelfection( wi );// Get a refraction vector and trace for transmissionwi = refract( wo, n, eta );Col3f Ltran = traceRefraction( wi );// Blend between reflection and transmission using the coefficient of reflection calculated earlier to get the final colourCol3f 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.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.