Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Color Lab::findColor(Ray* ray, int iteration) {
- if (iteration == MAX_ITERATIONS)
- return Color(0, 0, 0, 1);
- Color color = scene->background;
- Object* obj = findClosest(ray, iteration == 0);
- // Calculate color
- if (obj) {
- Material* mat = obj->mesh->material;
- // Fetch surface properties (position, normal, texture coordinates)
- obj->mesh->raySurface(ray, obj->position);
- // Init colors
- Color totalDiffuse, totalSpecular, reflectCol, refractCol;
- totalDiffuse = totalSpecular = reflectCol = refractCol = Color(0, 0, 0, 1);
- // Find vector to eye
- vec3 toEye = normalize(camera->position - ray->hitPos);
- // Go through every light and calculate diffuse and specular components
- for (uint i = 0; i < scene->lights.size(); i++) {
- Light* light = scene->lights[i];
- vec3 incidence = normalize(light->position - ray->hitPos);
- // Cast rays to area light
- float inLight = 0;
- float shadowSize = 50;
- float shadowDetail = 5;
- float invDetail = 1.f / shadowDetail;
- for (float x = -0.5; x < 0.5; x += invDetail) {
- for (float z = -0.5; z < 0.5; z += invDetail) {
- vec3 lightDir = normalize(light->position + vec3(x + random() * invDetail, 0, z + random() * invDetail) * shadowSize - ray->hitPos);
- Ray toLight(ray->hitPos + ray->hitNorm * EPSILON, lightDir);
- Object* blocker = findClosest(&toLight, false);
- if (blocker && toLight.hitDis < length(light->position - ray->hitPos))
- continue;
- inLight += 1.f / (shadowDetail * shadowDetail);
- }
- }
- if (inLight == 0)
- continue;
- // Diffuse factor
- float diffuse = max(dot(ray->hitNorm, incidence), 0);
- // Specular factor
- if (mat->shininess > 0.0) {
- vec3 reflection = reflect(-incidence, ray->hitNorm);
- float specular = pow(max(dot(reflection, toEye), 0.0), 1.0 / mat->shininess);
- totalSpecular += specular * light->color * inLight;
- }
- totalDiffuse += diffuse * light->color * inLight;
- }
- // Reflection!!
- if (mat->reflective > 0.0) {
- // Calculate reflected ray
- vec3 reflectDir = reflect(ray->direction, ray->hitNorm);
- Ray reflectRay(ray->hitPos + ray->hitNorm * EPSILON, reflectDir);
- // Calculate color recursively
- reflectCol = findColor(&reflectRay, iteration + 1) * mat->reflective;
- }
- // Refraction!!
- if (mat->transparency > 0.0) {
- // Enter the object
- vec3 refractDirEnter = refract(ray->direction, ray->hitNorm, 1.0, mat->refractIndex);
- Ray refractRayEnter(ray->hitPos - ray->hitNorm * EPSILON, refractDirEnter, true);
- Object* hit = findClosest(&refractRayEnter, false);
- if (hit == obj) {
- hit->mesh->raySurface(&refractRayEnter, obj->position);
- // Leave the object
- vec3 refractDirLeave = refract(ray->direction, ray->hitNorm, mat->refractIndex, 1.0);
- Ray refractRayLeave(refractRayEnter.hitPos + refractRayEnter.hitNorm * EPSILON, refractDirLeave);
- // Calculate color recursively
- refractCol = findColor(&refractRayLeave, iteration + 1) * mat->transparency;
- } else // For flat surfaces
- refractCol = findColor(&refractRayEnter, iteration + 1) * mat->transparency;
- }
- // Calculate final color
- Color matColor = mat->texture->getPixel(ray->hitTexCoord);
- color = refractCol + reflectCol + matColor * (scene->ambient + totalDiffuse) + totalSpecular;
- }
- return color;
- }
Advertisement
Add Comment
Please, Sign In to add comment