DavidNorgren

Untitled

Jun 2nd, 2015
141
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.33 KB | None | 0 0
  1. Color Lab::findColor(Ray* ray, int iteration) {
  2.     if (iteration == MAX_ITERATIONS)
  3.         return Color(0, 0, 0, 1);
  4.  
  5.     Color color = scene->background;
  6.     Object* obj = findClosest(ray, iteration == 0);
  7.  
  8.     // Calculate color
  9.     if (obj) {
  10.         Material* mat = obj->mesh->material;
  11.  
  12.         // Fetch surface properties (position, normal, texture coordinates)
  13.         obj->mesh->raySurface(ray, obj->position);
  14.        
  15.         // Init colors
  16.         Color totalDiffuse, totalSpecular, reflectCol, refractCol;
  17.         totalDiffuse = totalSpecular = reflectCol = refractCol = Color(0, 0, 0, 1);
  18.  
  19.         // Find vector to eye
  20.         vec3 toEye = normalize(camera->position - ray->hitPos);
  21.  
  22.         // Go through every light and calculate diffuse and specular components
  23.         for (uint i = 0; i < scene->lights.size(); i++) {
  24.             Light* light = scene->lights[i];
  25.             vec3 incidence = normalize(light->position - ray->hitPos);
  26.  
  27.             // Cast rays to area light
  28.             float inLight = 0;
  29.             float shadowSize = 50;
  30.             float shadowDetail = 5;
  31.             float invDetail = 1.f / shadowDetail;
  32.  
  33.             for (float x = -0.5; x < 0.5; x += invDetail) {
  34.                 for (float z = -0.5; z < 0.5; z += invDetail) {
  35.                     vec3 lightDir = normalize(light->position + vec3(x + random() * invDetail, 0, z + random() * invDetail) * shadowSize - ray->hitPos);
  36.                     Ray toLight(ray->hitPos + ray->hitNorm * EPSILON, lightDir);
  37.                     Object* blocker = findClosest(&toLight, false);
  38.  
  39.                     if (blocker && toLight.hitDis < length(light->position - ray->hitPos))
  40.                         continue;
  41.  
  42.                     inLight += 1.f / (shadowDetail * shadowDetail);
  43.                 }
  44.             }
  45.  
  46.             if (inLight == 0)
  47.                 continue;
  48.  
  49.             // Diffuse factor
  50.             float diffuse = max(dot(ray->hitNorm, incidence), 0);
  51.  
  52.             // Specular factor
  53.             if (mat->shininess > 0.0) {
  54.                 vec3 reflection = reflect(-incidence, ray->hitNorm);
  55.                 float specular = pow(max(dot(reflection, toEye), 0.0), 1.0 / mat->shininess);
  56.                 totalSpecular += specular * light->color * inLight;
  57.             }
  58.  
  59.             totalDiffuse += diffuse * light->color * inLight;
  60.         }
  61.        
  62.         // Reflection!!
  63.         if (mat->reflective > 0.0) {
  64.             // Calculate reflected ray
  65.             vec3 reflectDir = reflect(ray->direction, ray->hitNorm);
  66.             Ray reflectRay(ray->hitPos + ray->hitNorm * EPSILON, reflectDir);
  67.  
  68.             // Calculate color recursively
  69.             reflectCol = findColor(&reflectRay, iteration + 1) * mat->reflective;
  70.         }
  71.        
  72.         // Refraction!!
  73.         if (mat->transparency > 0.0) {
  74.             // Enter the object
  75.             vec3 refractDirEnter = refract(ray->direction, ray->hitNorm, 1.0, mat->refractIndex);
  76.             Ray refractRayEnter(ray->hitPos - ray->hitNorm * EPSILON, refractDirEnter, true);
  77.             Object* hit = findClosest(&refractRayEnter, false);
  78.  
  79.             if (hit == obj) {
  80.                 hit->mesh->raySurface(&refractRayEnter, obj->position);
  81.  
  82.                 // Leave the object
  83.                 vec3 refractDirLeave = refract(ray->direction, ray->hitNorm, mat->refractIndex, 1.0);
  84.                 Ray refractRayLeave(refractRayEnter.hitPos + refractRayEnter.hitNorm * EPSILON, refractDirLeave);
  85.  
  86.                 // Calculate color recursively
  87.                 refractCol = findColor(&refractRayLeave, iteration + 1) * mat->transparency;
  88.             } else // For flat surfaces
  89.                 refractCol = findColor(&refractRayEnter, iteration + 1) * mat->transparency;
  90.         }
  91.  
  92.         // Calculate final color
  93.         Color matColor = mat->texture->getPixel(ray->hitTexCoord);
  94.         color = refractCol + reflectCol + matColor * (scene->ambient + totalDiffuse) + totalSpecular;
  95.     }
  96.  
  97.     return color;
  98. }
Advertisement
Add Comment
Please, Sign In to add comment