Incorporating Simple Scattering

[ LiB ]

Incorporating Simple Scattering

Developing an algorithm that scatters photons from a diffuse point light is your primary goal, and there are many ways to do it. One simple algorithm for scattering photons from a light source uses a center point with a unit radius and randomly generates outgoing vectors around the unit sphere. See Figure 11.3 for an example of simple scattering. The center point is the light source position.

Figure 11.3. Simple scattering uses a center point that gener ates random vectors in outgoing directions around a unit sphere.

graphic/11fig03.gif


NOTE

NOTE

There are a variety of light-scatter- ing algorithms available,and you can even implement your own.

This causes photons to be equally distributed outward from the light source. The power of each photon is randomly generated and should be scaled by the amount of emitted photons. This concept is very similar to how energy is released from a light bulb. Let's take a look at the logic required to scatter photons equally from a diffuse point of light.

Implementing a method to scatter photons from a diffuse point light is actually very simple. The first things you need to do are go through each light source and then emit n number of photons into the scene in random directions. This is done by emitting a photon using a random number for the individual X, Y, and Z components to find a random direction for the ray to travel. If an intersection has occurred in the scene, you process the photon and begin the whole procedure again until n photons are emitted from the light source. When you have completed emitting the desired photons from the light source, you scale each photon's power to a fraction of the light source total wattage. Now, let's take a look at the algorithmic description of simple scattering:

  1. For each light source in the scene.

  2. For the number of emitted photons from the light source.

  3. Pick a photon in a random direction and shoot it into the scene.

  4. Find the closest intersection.

  5. Process the photon at the point of intersection. This logic for the point of intersection is done by calling a special method called ProcessPhotonHit() .

  6. After releasing all photons for the light source, scale each photon to (1 / emitted photons).

As you can see, the algorithm is straightforward. Let's implement the method to scatter photons in a uniform fashion.

Let's take a detailed look at the code required to scatter photons in a uniform fashion. Two variables are created; one to count the number of emitted photons and the other to count the number of intersected photons. The maximum number of photons that are released from a light source is set up by the application. The random x, y, and z components of the direction vec-tor are in a range of 1 and 1. Remember that the unit vector randomly points in some direction in the unit sphere.

 void Create_Photons_For_Light (cLight light) {    int nShot = 0,        nHit  = 0;    float   x,y,z;    cRay    ray;  cVector3 vHit, vNormal; int iClosestObject; // shoot random directions while(nShot < max_photons){ do {   x = (-1 + 2*(float)rand() / (float)RAND_MAX);   y = (-1 + 2*(float)rand() / (float)RAND_MAX);   z = (-1 + 2*(float)rand() / (float)RAND_MAX); } while ( x * x + y * y + z * z > 1); 

Setting the Direction

The next step after you generate a random vector is to set up a photon and cast it into the scene. You do this using the ray structure. The ray's origin is the light source position and the ray's direction is the random vector. The ray is normalized and is ready to be launched into the scene.

 // set up ray ( light -> random dir) ray.origin = light.vPosition;     ray.direction = cVector3(x, y, z); ray.direction.Normalize(); 

Finding the Closest Intersection

The ray is cast into the scene by calling the Find_Closest_Object() method. If the ray has intersected a point on an object in the scene, the intersection point and the object index are returned.

 // find closest object  iClosestObject = Find_Closest_Object(ray, &vHit); 

Getting the Point Normal

The object normal is referenced for later use when processing photon intersections.

 // get object normal vNormal          = pObjectList[iClosestObject].Normal(vHit); 

If an intersection is found between the light source and an object in the scene, the photon is set to the total wattage of the light source. The hit counter is updated and the ProcessPhotonHit() method should be called to compute the photon's behavior. The emitted counter is updated and the process begins again.

 // if object is in the local array list  if( iClosestObject > -1 )  {   cout << "A photon has hit object:" << iClosestObject << endl;  // local photon   cPhoton p;  // strength of light source  float e = light.fWattage;  e  *= max_photons;  // attach it to photon  p.Power = color3(e, e, e);  // process photon hit  TODO: Call Process Photon Hit Function   //  ProcessPhotonHit();     nHit++;  }   nShot++; } 

NOTE

TIP

Remember each photon released from a light source must be scaled to carry a fraction of the emitted energy.

Scaling Each Photon's Power

The final step after all photons have been emitted from the light source is to give each photon a portion of the light source wattage. If you recall, you previously gave each photon the full wattage of the light source. In order to scale each photon appropriately, you use the following formula.

Photon Power = Light Source Wattage (1.0 full) / emitted photons

The following code shows how to do this:

 // scale power of stored photons with 1/emitted photons   float scale = 1.0f/(float)(nShot);   for(int i=0; i < lNumGlobalPhotons; i++)           pGlobalPhoton[i].Power *= scale ; } 

NOTE

The Problem with Simple Scattering

The problem with this simple scattering algorithm is that it randomly shoots photons in many directions.Scenes that have objects that are spaced apart may not receive enough photons using this technique.This algorithm works great using the Cornell box (the inside of a cube with one light and one face missing),but suffers if the objects are separated.Earlier tests involved shooting 1000 pho-tons towards two spheres spaced apart.They resulted in each sphere only receiving 30 hits.Too many wasted photons are created that do nothing but consume processor cycles. Rendered images look blotchy and ugly because there are too few photons intersecting each object.I had to increase the number of photons emitted for my light sources from 1000 to 100,000 just to accomplish reasonable results which resulted in a lot of wasted pho-tons,processing cycles,and time.This was unacceptable so I had to find another way of distributing photons towards objects in the scene with less work for the processor.I've decided to move away from this method and implement a smarter method of scattering photons.

[ 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