void firstIntersection(VECTOR *eyePosition, VECTOR *rayFromEyeDirection, LIST_NODE_PTR *intersections) { LIST_NODE_PTR scene = sceneList; while (scene != NULL) { switch (scene->data.object.type) { case SPHERE: sphereIntersection(eyePosition, rayFromEyeDirection, &scene->data.object, intersections); break; case POLYGON: if (stop) { int trash = 0; } polygonIntersection(eyePosition, rayFromEyeDirection, &scene->data.object, intersections); break; case DISK: diskIntersection(eyePosition, rayFromEyeDirection, &scene->data.object, intersections); break; case CYLINDER: cylinderInterseption(eyePosition, rayFromEyeDirection, &scene->data.object, intersections); break; case CONE: coneInterseption(eyePosition, rayFromEyeDirection, &scene->data.object, intersections); break; } scene = scene->nextPtr; } }
Color raytrace( Scene scene, Ray ray ) { Color color; color.r = 0; color.b = 0; color.g = 0; Intersection best; best.hit = false; float bestT = 10000; float t; for( int j = 0; j < scene.numSpheres; j++ ) { t = sphereHitTest( scene.spheres[j], ray ); if( t > 0 ) { if( !best.hit || t < bestT ) { best = sphereIntersection( scene.spheres[j], ray, t ); bestT = t; } } } for( int j = 0; j < scene.numTriangles; j++ ) { t = triangleHitTest( scene.triangles[j], ray ); if( t > 0 ) { if( !best.hit || t < bestT ) { best = triangleIntersection( scene.triangles[j], ray, t ); bestT = t; } } } for( int j = 0; j < scene.numPlanes; j++ ) { t = planeHitTest( scene.planes[j], ray ); if( t > 0 ) { if( !best.hit || t < bestT ) { best = planeIntersection( scene.planes[j], ray, t ); bestT = t; } } } if( best.hit ) { color = plus( color, directIllumination( best, scene ) ); //printf("color: %f, %f, %f\n", color.r, color.g, color.b); } return limitColor( color ); }
Color directIllumination( Intersection inter, Scene scene ) { Color ret; ret.r = 0; ret.b = 0; ret.g = 0; for( int i = 0; i < scene.numPointLights; i++ ) { PointLight temp = scene.pointLights[i]; vec3 lvec = unit(newDirection(temp.pos, inter.hitMark )); float nlDot = dot(lvec, inter.normal ); bool inShadow = false; float lightDistance = distance( temp.pos, inter.hitMark ); //contruct possible hits for shadow ray using bvh for( int j = 0; j < scene.numSpheres; j++ ) { Ray shadowRay; shadowRay.pos = inter.hitMark; shadowRay.dir = lvec; float t = sphereHitTest(scene.spheres[j], shadowRay ); if( t > 0 ) { Intersection info = sphereIntersection( scene.spheres[j], shadowRay, t ); if(info.hit) { if( distance( info.hitMark, inter.hitMark ) < lightDistance ) { inShadow = true; break; } } } } ObjectInfo shadowInter; if( !inShadow ) { vec3 r; r.x = -lvec.x + 2 * nlDot * inter.normal.x; r.y = -lvec.y + 2 * nlDot * inter.normal.y; r.z = -lvec.z + 2 * nlDot * inter.normal.z; r = unit(r); float rvDot = dot(r, unit(inter.viewVector)); if(nlDot < 0) nlDot = 0; if(rvDot < 0) rvDot = 0; float powRV = pow( rvDot, 1.0/inter.colorInfo.finish_roughness ); ret.r =ret.r + temp.color.r * powRV*inter.colorInfo.finish_specular; ret.g = ret.g + temp.color.g* powRV*inter.colorInfo.finish_specular; ret.b = ret.b + temp.color.b * powRV*inter.colorInfo.finish_specular; ret.r+= inter.colorInfo.pigment.r * temp.color.r * nlDot*inter.colorInfo.finish_diffuse; ret.g += inter.colorInfo.pigment.g * temp.color.g * nlDot*inter.colorInfo.finish_diffuse; ret.b+= inter.colorInfo.pigment.b * temp.color.b * nlDot*inter.colorInfo.finish_diffuse; ret = limitColor( ret ); } } //1.5 not 1 to increase the directlight which will be balanced in Util/tga.cpp during gamma correction float mod = 1;//.2 - finish_reflection - pigment_f*finish_refraction; ret.r = ret.r * mod; ret.g = ret.g * mod; ret.b = ret.b * mod; return ret; }