/* * Trace color for each pixel and store resulting * color in an array * * TODO: Add fov calculation */ void rt_renderScene(Pixel *pixels) { int x,y; Color c; double angle; Ray primaryRay; /* Map fov to resolution -> angle for x and y */ primaryRay.direction.x = scene.cameraDirection.x; primaryRay.direction.y = scene.cameraDirection.y; primaryRay.direction.z = scene.cameraDirection.z; primaryRay.position.y = scene.cameraPosition.y - (scene.screenY/2); primaryRay.position.z = scene.cameraPosition.z; for(y=0;y<scene.screenY;y++) { primaryRay.position.x = scene.cameraPosition.x - (scene.screenX/2); for(x=0;x<scene.screenX;x++) { c = rt_trace(&primaryRay,MAXRECURSION); pixels[y*scene.screenX+x] = gfx_createPixel(c.r,c.g,c.b); primaryRay.position.x += 1; } primaryRay.position.y += 1; } }
float pos[3] = {0., 0., 0.}; float dir[3] = {0.688749, 0.722979, 0.0540979}; float dist = 4.632; intptr_t * ipars = NULL; size_t size =0; size_t length = rt_trace(pos, dir, dist, &ipars, &size); for(i = 0; i < length; i++) { intptr_t ipar = ipars[i]; printf("%ld %g %g %g\n", ipar, psys.pos[ipar][0], psys.pos[ipar][1], psys.pos[ipar][2]); } free(ipars);
/* * Trace a color for single ray * Color may be affected by other rays. * * TODO: refraction support. fresnel equation */ Color rt_trace(Ray *ray, int recursions) { Object *object; Color c; Vector pointHit, normalHit; double minDist, t; int i; object = NULL; minDist = INFINITY; c.r = 0; c.g = 0; c.b = 0; /* Find out closest intersection, if any */ for(i=0;i<scene.objectCount;i++) { t = rt_intersect(ray,&(scene.objects[i])); if(t > 0.0 && t < minDist) { minDist = t; object = &scene.objects[i]; } } /* If there was an intersection */ if(NULL != object) { double brightness; /* Calculate point hit */ rt_vectorMultiply(&(ray->direction),minDist,&pointHit); rt_vectorAdd(&pointHit,&(ray->position),&pointHit); /* Calculate normal hit */ rt_surfaceNormal(object,&pointHit,&normalHit); /* Return light intensity on the intersection point * based on angles between visible light sources * Not very realistic. */ brightness = rt_illumination(&pointHit,&normalHit); /* Object is reflective or transparent */ if((object->reflection > 0 || object->transparency > 0) && (recursions > 0)) { Color reflectionColor, refractionColor, diffuseColor; Ray reflectionRay, refractionRay; double reflet; if(object->reflection > 0) { reflectionRay.position.x = pointHit.x + normalHit.x * BIAS; reflectionRay.position.y = pointHit.y + normalHit.y * BIAS; reflectionRay.position.z = pointHit.z + normalHit.z * BIAS; reflet = rt_dotProduct(&(ray->direction),&normalHit); reflet *= 2.0; rt_vectorMultiply(&normalHit,reflet,&(reflectionRay.direction)); rt_vectorSubstract(&(ray->direction),&(reflectionRay.direction),&(reflectionRay.direction)); reflectionColor = rt_trace(&reflectionRay, recursions-1); } if(object->transparency > 0) { //TODO } c.r = (int) (reflectionColor.r * (object->reflection)) + 0.5; c.g = (int) (reflectionColor.g * (object->reflection)) + 0.5; c.b = (int) (reflectionColor.b * (object->reflection)) + 0.5; if(brightness > 0) { diffuseColor.r = (int) ((1 - (object->reflection)) * (object->color.r * brightness) + 0.5); diffuseColor.g = (int) ((1 - (object->reflection)) * (object->color.g * brightness) + 0.5); diffuseColor.b = (int) ((1 - (object->reflection)) * (object->color.b * brightness) + 0.5); c.r += diffuseColor.r; c.g += diffuseColor.g; c.b += diffuseColor.b; } } /* Diffuse object */ else { /* Calculate color */ if(brightness > 0) { c.r = object->color.r; c.g = object->color.g; c.b = object->color.b; c.r = (int) c.r*brightness+0.5; c.g = (int) c.g*brightness+0.5; c.b = (int) c.b*brightness+0.5; } } } return c; }
/* Debug function * prints out results of tests */ void rt_printScene() { int i; printf("-=-=-=-Scene-=-=-=-\n"); printf("Resolution: %dx%d\n",scene.screenX,scene.screenY); printf("Field of View: %d\n",scene.fov); printf("Camera position: %f,%f,%f\n", scene.cameraPosition.x, scene.cameraPosition.y, scene.cameraPosition.z); printf("Camera direction: %f,%f,%f\n", scene.cameraDirection.x, scene.cameraDirection.y, scene.cameraDirection.z); printf("Light count %d\n",scene.lightCount); for(i=0;i<scene.lightCount;i++) { printf("Light[%d]: Position: x=%f y=%f z=%f Intensity %f\n", i, scene.lights[i].position.x, scene.lights[i].position.y, scene.lights[i].position.z, scene.lights[i].intensity); } printf("Object count %d\n",scene.objectCount); for(i=0;i<scene.objectCount;i++) { printf("Object[%d]: ",i); switch(scene.objects[i].type) { case t_null: { printf("Empty object\n"); } break; case t_sphere: { printf("Sphere\n"); Sphere *s; s = (Sphere *)scene.objects[i].object; printf("\tType: Sphere Position: x=%f y=%f z=%f Radius: %f\n", s->position.x, s->position.y, s->position.z, s->radius); } break; case t_plane: { printf("\tType: Plane No features implemented.\n"); } break; default: { printf("unknown type %d\n",scene.objects->type); } break; } } printf("\n-=-=-=-Vector math test-=-=-=-\n"); Vector v1,v2,v3; double scalar, result, len; v1.x = 4.0; v2.x = 8.0; v3.x = 0.0; v1.y = 3.0; v2.y = 1.0; v3.y = 0.0; v1.z = 9.0; v2.z = -3.4; v3.z = 0.0; scalar = 5.0; printf("v1 = (%f,%f,%f)\n",v1.x,v1.y,v1.z); printf("v2 = (%f,%f,%f)\n",v2.x,v2.y,v2.z); len = rt_vectorLength(&v1); printf("length(v1) = %f\n",len); rt_vectorAdd(&v1,&v2,&v3); printf("v1 + v2 = (%f,%f,%f)\n",v3.x,v3.y,v3.z); rt_vectorSubstract(&v1,&v2,&v3); printf("v1 - v2 = (%f,%f,%f)\n",v3.x,v3.y,v3.z); rt_vectorMultiply(&v1,scalar,&v3); printf("v1 * %f = (%f,%f,%f)\n",scalar,v3.x,v3.y,v3.z); result = rt_dotProduct(&v1,&v2); printf("dot(v1,v2) = %f\n",result); rt_vectorNormalize(&v1,&v3); printf("normalize(v1) = (%f,%f,%f)\n",v3.x,v3.y,v3.z); printf("\n-=-=-=-Intersection testing-=-=-=-\n"); Ray r; Object o; Sphere s; double intersects; r.position.x = -10.0; r.direction.x = 0.0; s.position.x = 0.0; r.position.y = 5.0; r.direction.y = 0.0; s.position.y = 0.0; r.position.z = -80.0; r.direction.z = 1.0; s.position.z = 0.0; s.radius = 30.0; o.type = t_sphere; o.object = &s; rt_vectorNormalize(&r.direction,&r.direction); printf("Intersection of\n"); printf("\t[RAY] Position: (%f,%f,%f) Direction: (%f,%f,%f)\n", r.position.x,r.position.y,r.position.z, r.direction.x,r.direction.y,r.direction.z); printf("\t[SPHERE] Position: (%f,%f,%f) Radius: %f\n", s.position.x,s.position.y,s.position.z, s.radius); intersects = rt_intersect(&r,&o); printf("Result: %f\n",intersects); printf("\n-=-=-=-Trace testing-=-=-=-\n"); rt_trace(&r,MAXRECURSION); printf("\n-=-=-=-Mapping test-=-=-=-\n"); double mapInput, mapMinIn, mapMinOut, mapMaxIn, mapMaxOut, mapResult; mapInput = 48.228; mapMinIn = 1.0; mapMaxIn = 2000.0; mapMinOut = 0.0; mapMaxOut = 255.0; printf("Mapping %f from range[%f,%f] to range[%f,%f]\n",mapInput,mapMinIn,mapMaxIn,mapMinOut,mapMaxOut); mapResult = rt_map(mapMinIn,mapMaxIn,mapMinOut,mapMaxOut,mapInput); printf("\tResult = %f\n",mapResult); printf("\n_______END OF DEBUG_______\n"); }