Thursday, January 8, 2015

Distributed Ray Tracing (Soft Shadow)

DISTRIBUTED RAY TRACING :
Conventional ray tracing uses single ray to trace all the objects in the scene. In distributed ray tracing we will use multiple ray to render a scene. This concept will help us to produce more realistic images. This ray tracing method is also known as Stochastic ray tracing
Soft Shadow:This shadow have both umbra and penumbra.
Algorithm:

1. Light source in soft shadows is Area Light Source (Spherical, Cubic etc). Which can be easily made by using the point light source location as center and radius could be anything of your choice I prefer 2 or 3.

2. From the intersection point we will shoot multiple rays toward area light source and check all the shadow rays for the intersection with the objects in the scene. 

3. Creating multiple shadow rays using imaginary image plane: create similar u,v,w vector as we created for camera. Find the largest component in the primary light ray from intersection point to the center of area light source and treat it as w. If largest component is 'x' then take view up vector as (1,0,0) because mostly plane will be parallel to the largest component, else if y or z do the same.

4. Using view up vector and w we can find u and v 
   u = view up x w   (x is cross product)
   v = n x u   

5. Now we can easily perturb the shadow ray by shooting rays from randomly generated points on imaginary image plane. 

6. Find the intersection of these multiple shadow rays with all the objects in the scene. If intersection happens then color that point on image plane is black otherwise color it as white. Take the average color of all these points and shade the intersection point with that averaged color. 
C++ CODE:
if(normal.dot(L) < 0){
  inShadow = true;
}
else if(normal.dot(L) > 0){
  inShadow = false;
  SbVec3f nn = -L;
  SbVec3f v_up;
  SbVec3f otherL = L;
  float epsilon = 0.00000000009;
  if(otherL[0] >= otherL[1] && otherL[0] >= otherL[2])
     v_up.setValue(1,0,0);
  if(otherL[1] >= otherL[0] && otherL[1] >= otherL[2])
     v_up.setValue(0,1,0);
  if(otherL[2] >= otherL[0] && otherL[2] >= otherL[1])
     v_up.setValue(0,0,1);
  SbVec3f uu = v_up.cross(nn);
  SbVec3f vv = nn.cross(uu);
  inShadow = false;
  for(int di =0 ; di<25 data-blogger-escaped-b="" data-blogger-escaped-di="" data-blogger-escaped-du="rand()/float(RAND_MAX+1);" data-blogger-escaped-dv="rand()/float(RAND_MAX+1);" data-blogger-escaped-float="">SbVec3f shadowRayDirection = (lightSphere[j].getCenter() + uu *
     cos(3.0 * du) * 3.0 + vv * sin(3.0 * dv) * 3.0) - intersection point;
shadowRayDirection.normalize();
SbVec3f shadowRayStart = point + epsilon * shadowRayDirection;
if(normal.dot(shadowRayDirection) < 0){
inShadow = true;
}
else {
for(int z =0 ; z<(int)objects.size();z++) {
if(objects[z].getTransparency() > 0.0) { }
else {
inShadow = false; float shadowT = objects[z].intersection(shadowRayStart,shadowRayDirection);
if(shadowT >= 0) {
inShadow = true; break;
}
}
}
if(inShadow == true) {
value += 1/25;
}
}
}
}
NOTE: I am using 25 rays and light sphere radius is 3. Value is to average the colors on the imaginary plane

No comments:

Post a Comment