Adding Reflection and Refraction Features

[ LiB ]

Adding Reflection and Refraction Features

Because this is a 3D book and you're developing a 3D environment, you should try to make all 3D functions as simple as possible. For example, the reflection and refraction code can be incorporated into the cVector3 class because it mostly deals with points. Let's add this extra functionality to the cVector3 class for reflection and refraction. Remember reflection can be broken into diffuse reflection and specular reflection. Diffuse reflections scatter light in arbitrary directions, whereas specular reflections reflect light in one particular direction. You must also write a method to refract light between two mediums (such as from air to water). You then add all of this logic to your reflection and refraction methods .

Diffuse Reflection

The code for diffuse reflection is extremely simple. All you need to do is generate a random number for each x, y, and z component for a vector in a unit sphere. This vector range is between 1 and 1. The function yields a vector pointing in some arbitrary direction in the unit sphere. The trick to implementing this method correctly is to remember that surfaces are flat and light can't diffusively reflect inside the surface. So all reflection must be done in front of the surface. This means the dot product determines whether the random vector is pointing below the flat surface and, if it is, it will invert it. Finally, the function returns with the new random diffusively reflected vector.

This method requires the normal of the surface to diffusively reflect light. The random X, Y, and Z directions are generated by using ((1 + 2*(float)rand() / (float)RAND_MAX)). It will reflect a vector around the normal and determine whether the vector is pointing in the wrong direction. If it is, it will be inverted.

 cVector3 cVector3::Diffuse_Reflection( cVector3 Normal ) {   cVector3 r;   // get x,y,z random numbers between -1 to 1 for float   r.x = (-1 + 2*(float)rand() / (float)RAND_MAX);   r.y = (-1 + 2*(float)rand() / (float)RAND_MAX);   r.z = (-1 + 2*(float)rand() / (float)RAND_MAX);   float dot = r * Normal;   if (dot < 0.0f)     return r = r*-1.0f;   return r; } 

Specular (Mirror) Reflection

The specular reflection formula works like this: For the incoming ray direction (given as a unit vector), and the point normal (or vector normal of surface), the reflected ray is given as R .

 Angle = - Find the Angle Between (Point Normal, Ray Direction)  R  = Ray Direction + (2.0  * Point  Normal * Angle) 

You can now upgrade the cVector3 class to accommodate vector mirror reflections. The method will pass the surface normal in as a parameter and will return with the new reflected vector. The function will return a reflected ray that is the opposite of the incident ray. This function can be used for mirror surfaces that reflect directly in the opposite direction.

 cVector3 cVector3::Vector_Reflection(cVector3 normal) {    float Angle;    cVector3 Me;    cVector3 reflected;    Me = *this;    Me.Invert();    Me.Normalize();    normal.Normalize();    Angle = Me * normal ;    if (Angle < 0)    {       normal.Invert();       Angle = Me * normal;    }    reflected.x = 2.0f * normal.x * Angle - Me.x;    reflected.y = 2.0f * normal.y * Angle - Me.y;    reflected.z = 2.0f * normal.z * Angle - Me.z;    reflected.Normalize();    return reflected; } 

Refraction

The refracted ray direction is a bit more complicated than the specular reflection method. The refracted method must change indexes between two mediums. This must be simulated in order to simulate refractions on many objects such as diamonds, glass, crystals, and water. The refracted ray direction is given as Ir .

 Angle  = - Find the Angle Between (Point Normal, Ray Direction) Medium1 = Index of refraction of the original medium (ex. Air) Medium2 = Index of refraction of the new medium (ex. Water) Ratio = Medium1 / Medium2 Delta = SquareRoot (1  Ratio_ * (1 - Angle_))  Ir  = (Ratio * Ray Direction) + (Ratio * Angle   Delta) * Point Normal- 

You can now upgrade the cVector3 class and add a new vector method that simulates vector refractions. The method will pass the surface normal, Medium1 , Medium2 , and a pointer to the reflected vector as parameters. The function will also return true or false based on the success of the algorithm.

 bool cVector3::Vector_Refraction( cVector3 Normal,      float Medium1, float Medium2, cVector3 *pOutput ) {    float Ratio, Angle, Delta;    cVector3 Refracted;    Ratio = Medium1 / Medium2;    Angle = -( *this * Normal );    Delta = 1.0f - Ratio * Ratio * ( 1.0f - Angle * Angle );    if( Delta < 0.0f )       return false;    Refracted  =  ( *this * Ratio ) + ( Normal *  Ratio *  Angle  (float)sqrt( Delta )));    Refracted.Normalize();    *pOutput = efracted;    return true; } 

NOTE

TIP

You can add other lighting effect methods to the vector class if you want to.

[ LiB ]


Focus On Photon Mapping
Focus On Photon Mapping (Premier Press Game Development)
ISBN: 1592000088
EAN: 2147483647
Year: 2005
Pages: 128
Authors: Marlon John

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net