VEC3F rayColor(VEC3F* ray) { VEC3F colorRGB; VEC3F c(0, 0, 1); // sphere center VEC3F n; // normal vector VEC3F cr(1.0f, 1.0f, 1.0f); // surface color VEC3F cl(1.0f, 1.0f, 1.0f); // light color VEC3F light(1, 1, -1); // light location VEC3F l; // light direction if(!intersectScene(ray[0])) { //return black colorRGB = VEC3F(0.f, 0.f, 0.f); } else { // return color n = ray[0]-c; // calculate normal vector, p - c l = light-ray[0]; // calculate l vector, light - p // normalize n and l n.normalize(); l.normalize(); VEC3F crcl(cr[0]*cl[0], cr[1]*cl[1], cr[2]*cl[2]); float nlDotProd = n*l; colorRGB = crcl*(nlDotProd); } return colorRGB; // return vector with rgb values }
int createPath(const RTScene& scene, Rand& rand, int maxVerts, const float3& initialAlpha, const Ray& initialRay, bool includeLightIntersections, PathVertex vertices[]) { int numVerts = 0; Ray ray = initialRay; float3 alpha = initialAlpha; for(int i = 0; i < maxVerts; i++) { float3 woWorld = -ray.dir; IntersectionQuery query(ray); Intersection isect; Intersection lightIsect; intersectScene(scene, query, &isect, &lightIsect); if(hitLightFirst(isect, lightIsect)) { if(includeLightIntersections) { vertices[i] = PathVertex(lightIsect.normal, woWorld, lightIsect.position, lightIsect.material, alpha); return numVerts + 1; } else { return numVerts; } } if(!isect.hit) break; else numVerts++; vertices[i] = PathVertex(isect.normal, woWorld, isect.position, isect.material, alpha); if(i == (maxVerts - 1)) break; ShadingCS isectShadingCS(isect.normal); float3 wi; float3 weight; isect.material->sample(isectShadingCS.local(woWorld), rand.next01f2(), &wi, &weight); if(isBlack(weight)) { break; } float3 wiWorld = isectShadingCS.world(wi); ray.origin = isect.position; ray.dir = wiWorld; alpha *= weight; } return numVerts; }
/************************************************************************ * This is the recursive ray tracer ************************************************************************/ vec3 recursive_ray_trace(vec3 eye, vec3 ray,int ignore, int step) { Object* S = NULL; vec3 hit; S = intersectScene(eye, ray, &hit, ignore); if(S == NULL) return background_clr; vec3 color(0,0,0); vec3 viewDir = glm::normalize(eye - hit); vec3 surf_norm = S->GetNormal(hit); return phong(hit,viewDir, surf_norm, ray, S , step); }
/********************************************************************* * Phong illumination *********************************************************************/ glm::vec3 phong(glm::vec3 point, glm::vec3 viewDir, glm::vec3 surf_norm, Object *obj) { // ambient glm::vec3 mat_ambient; mat_ambient = obj->GetAmbient(point); glm::vec3 ambient = light1_ambient * mat_ambient ; // calc decay factor float dist = glm::distance(light1, point); float decay = 1 / ( decay_a + decay_b * dist + decay_c * dist * dist ); //printf("decay : %f\n",decay); // detect shadow glm::vec3 lightDir = glm::normalize(light1 - point); glm::vec3 hit; bool shadow = false; if( shadow_on ) { if ( intersectScene(point, lightDir, &hit, obj->index) != NULL ) shadow = true; else if( obj->Intersect(point,lightDir,&hit, false) > precision ) shadow = true; } // diffuse surf_norm = glm::normalize(surf_norm); //printf(" before GetDiffuse\n"); glm::vec3 mat_diffuse = obj->GetDiffuse(point); //printf(" after GetDiffuse\n"); glm::vec3 diffuse = decay * (light1_diffuse * mat_diffuse ) * max(glm::dot(surf_norm, lightDir),0) ; //printf(" after calc diffuse\n"); // specular //glm::vec3 reflectDir = glm::normalize(glm::rotate(lightDir, glm::radians(180.0f), surf_norm)); glm::vec3 reflectDir = 2 * glm::dot(surf_norm,lightDir) * surf_norm - lightDir ; reflectDir = glm::normalize(reflectDir); viewDir = glm::normalize(viewDir); float reflectTerm = max(glm::dot(reflectDir, viewDir),0); glm::vec3 specular = decay * ( light1_specular * obj->mat_specular) * (float) pow( reflectTerm, obj->mat_shineness) ; //if(shadow) specular = glm::vec3(0); // calc color glm::vec3 color = global_ambient * mat_ambient + ambient; if(!shadow) color += diffuse + specular; //color = specular; //color = global_ambient + ambient ; return color; }
bool ossimPlanetSceneView::computeLineOfSiteIntersection(osg::Vec3d& intersectionPoint, double startPointShift) { osg::Viewport* v = getViewport(); if(v) { return intersectScene(0, intersectionPoint, (double)v->x() + v->width()/2.0, (double)v->y() + v->height()/2.0, startPointShift); } intersectionPoint = osg::Vec3d(0.0,0.0,0.0); return false; }
bool visibleAndFacing( const Intersection& isectA, const Intersection& isectB, const RTScene& scene ) { if(!facing(isectA, isectB)) { return false; } //make sure they're facing each other first float3 dir = normalize(isectB.position - isectA.position); //now trace the ray... Ray ray(isectA.position, dir); IntersectionQuery query(ray); //float desiredT = glm::length(isectB.position - isectA.position); Intersection sceneIsect; intersectScene(scene, query, &sceneIsect, nullptr); //see if we hit isect B if(!sceneIsect.hit) return false; //if(fabs(sceneIsect.t - desiredT) > 0.0001) return false; if(sceneIsect.primitiveId != isectB.primitiveId) return false; return true; }
bool visibleAndFacing( const float3& posA, const float3& nA, const float3& posB, const float3& nB, const RTScene& scene ) { if(!facing(posA, nA, posB, nB)) { return false; } //make sure they're facing each other first float3 dir = normalize(posB - posA); //now trace the ray... Ray ray(posA, dir); IntersectionQuery query(ray); float desiredT = glm::length(posB - posA); Intersection sceneIsect; intersectScene(scene, query, &sceneIsect, nullptr); //see if we hit isect B if(!sceneIsect.hit) return false; if(fabs(sceneIsect.t - desiredT) > 0.0001) return false; return true; }
float3 directLight( Rand& rand, const RTScene& scene, const PathVertex& vertex, const ShadingCS& shadingCS) { //TODO: this does not work for multiple lights! auto & light = scene.accl->lights[0]; float3 lightPos; float lightPdf; //t is already incorporated into pdf float lightT; float3 wiDirectWorld; //sample the light light.sample(rand, vertex.position, &lightPos, &wiDirectWorld, &lightPdf, &lightT); //see if we're occluded Ray shadowRay(vertex.position, wiDirectWorld); //we cannot ignore the light here, as we need to differentiate b/t hit empty space //and hit light IntersectionQuery shadowQuery(shadowRay); Intersection sceneIsect; Intersection lightIsect; intersectScene(scene, shadowQuery, &sceneIsect, &lightIsect); bool hitLight = hitLightFirst(sceneIsect, lightIsect) && lightIsect.lightId == light.id; if(hitLight && facing(vertex.position, vertex.normal, lightIsect.position, lightIsect.normal)) { float3 wiDirect = shadingCS.local(wiDirectWorld); float3 brdfEval = vertex.material->eval(wiDirect, shadingCS.local(vertex.woWorld)); float3 cosTheta = float3(dot(vertex.normal, wiDirectWorld)); float3 le = light.material.emission; return le * brdfEval * cosTheta / lightPdf; } return float3(0); }
void intersectScene( const RTScene& scene, const Ray& ray, Intersection* sceneIsect, Intersection* lightIsect ) { IntersectionQuery query(ray); intersectScene(scene, query, sceneIsect, lightIsect); }
/************************************************************************ * This is the recursive ray tracer ************************************************************************/ glm::vec3 recursive_ray_trace(glm::vec3 eye, glm::vec3 ray,int ignore, int step) { Object* S = NULL; glm::vec3 hit; S = intersectScene(eye, ray, &hit, ignore); //printf("%d : after intersect scene (type: '%c')\n", step, S==NULL?'N':S->type); glm::vec3 color; if(S == NULL) color = background_clr; else { //color = glm::vec3(1.0,1.0,1.0); glm::vec3 viewDir = glm::normalize(eye - hit); glm::vec3 surf_norm = S->GetNormal(hit); //printf(" after get normal\n"); color = phong(hit,viewDir, surf_norm, S ); //printf(" after phong\n"); if(reflect_on && step < step_max){ //printf(" enter reflect\n"); glm::vec3 reflectDir = glm::normalize(glm::rotate(viewDir, glm::radians(180.0f), surf_norm)); glm::vec3 color_rf = recursive_ray_trace(hit, reflectDir, S->index, step+1); color += color_rf * S->reflectance ; //printf(" exit reflect\n"); } if(refract_on && step < step_max && S->refract ){ if(S->type == 'S'){ glm::vec3 outRay, outPoint; if(S->Refract(ray, hit, &outRay, &outPoint)){ glm::vec3 color_rfr = recursive_ray_trace(outPoint, outRay, S->index, step+2); color += color_rfr * S->refractance; } } else{ glm::vec3 outRay; if(S->GetRefractRay(ray, hit, &outRay)){ glm::vec3 color_rfr = recursive_ray_trace(hit,outRay, S->index, step+1); color += color_rfr * S->refractance; } } } if(difref_on && step < 2){ for(int i=0;i<DIFFUSE_RAYS;i++){ glm::vec3 difrefDir = glm::normalize(glm::rotate(viewDir, glm::radians(180.0f), surf_norm)); glm::vec3 axis = glm::cross(viewDir, surf_norm); float angle1 = random(-5.0f,0.0f); difrefDir = glm::rotate(difrefDir, glm::radians(angle1), axis); float angle2 = random(-5.0f,5.0f); difrefDir = glm::rotate(difrefDir, glm::radians(angle2), surf_norm); difrefDir = glm::normalize(difrefDir); glm::vec3 color_difref = recursive_ray_trace(hit, difrefDir, S->index, step+1); color += color_difref * float(0.1); } } } return color; }
/********************************************************************* * Phong illumination ray *********************************************************************/ vec3 phong(vec3 hit, vec3 viewDir, vec3 surf_norm, vec3 ray, Object *obj, int step) { // globle ambient vec3 mat_ambient = obj->GetAmbient(hit); vec3 ambient = light1_ambient * mat_ambient ; // decay float dist = glm::length(light1 - hit); float decay = 1 / ( decay_a + decay_b * dist + decay_c * dist * dist ); // diffuse vec3 lightDir = glm::normalize(light1 - hit); surf_norm = glm::normalize(surf_norm); vec3 mat_diffuse = obj->GetDiffuse(hit); vec3 diffuse = decay * (light1_diffuse * mat_diffuse ) * max(glm::dot(surf_norm, lightDir),0) ; // specular vec3 reflectDir = 2 * glm::dot(surf_norm,lightDir) * surf_norm - lightDir ; reflectDir = glm::normalize(reflectDir); viewDir = glm::normalize(viewDir); float reflectTerm = max(glm::dot(reflectDir, viewDir),0); vec3 specular = decay * ( light1_specular * obj->mat_specular) * (float) pow( reflectTerm, obj->mat_shineness) ; //shadow test vec3 temp; bool shadow = false; if( shadow_on && intersectScene(hit, lightDir, &temp, obj->index) != NULL ) shadow = true; // calc color vec3 color = global_ambient * mat_ambient + ambient; if(!shadow) color += diffuse + specular; //specular reflect ray if(reflect_on && step < step_max){ vec3 reflectDir = glm::normalize(glm::rotate(viewDir, glm::radians(180.0f), surf_norm)); vec3 color_rf = recursive_ray_trace(hit, reflectDir, obj->index, step+1); color += color_rf * obj->reflectance ; } //diffuse reflect ray if(difref_on && step < 2){ for(int i=0;i < DIFFUSE_RAYS;i++){ vec3 difrefDir = glm::normalize(glm::rotate(viewDir, glm::radians(180.0f), surf_norm)); vec3 axis = glm::cross(viewDir, surf_norm); float angle1 = random(-5.0f,0.0f); difrefDir = glm::rotate(difrefDir, glm::radians(angle1), axis); float angle2 = random(-5.0f,5.0f); difrefDir = glm::rotate(difrefDir, glm::radians(angle2), surf_norm); difrefDir = glm::normalize(difrefDir); vec3 color_difref = recursive_ray_trace(hit, difrefDir, obj->index, step+1); color += color_difref * float(0.5 / DIFFUSE_RAYS); } } if(refract_on && step < step_max && obj->refract ){ vec3 outRay, outPoint; if(obj->Refract(ray, hit, &outRay, &outPoint)){ vec3 color_rfr = recursive_ray_trace(outPoint, outRay, obj->index, step+1); color += color_rfr * obj->refractance; } } return color; }