CollisionResult collision_ray_scene_union(const Ray* ray, const Scene* scene) { const Scene* scene1 = ((ScenePair*)scene->data)->scene1; const Scene* scene2 = ((ScenePair*)scene->data)->scene2; const int max_iterations = 10; CollisionResult r1; { Ray ray2 = *ray; Vec3 p; for (int i = 0; i < max_iterations; ++i) { r1 = collision_ray_scene(&ray2, scene1); if (r1.type == None) { break; } p = ray_point(&ray2, r1.time); if (!scene_is_point_in_solid(scene2, &p)) { break; } Vec3 ro = ray_point(&ray2, r1.time+0.1); ray2 = ray_init(&ro, &ray2.direction); } if (r1.type != None) { Vec3 v = vec3_sub(&p, &ray->origin); r1.time = vec3_dot(&ray->direction, &v); } } CollisionResult r2; { Ray ray2 = *ray; Vec3 p; for (int i = 0; i < max_iterations; ++i) { r2 = collision_ray_scene(&ray2, scene2); if (r2.type == None) { break; } p = ray_point(&ray2, r2.time); if (!scene_is_point_in_solid(scene1, &p)) { break; } Vec3 ro = ray_point(&ray2, r2.time+0.1); ray2 = ray_init(&ro, &ray2.direction); } if (r2.type != None) { Vec3 v = vec3_sub(&p, &ray->origin); r2.time = vec3_dot(&ray->direction, &v); } } if (r1.type == None) { if (r2.type == None) { return (CollisionResult){.type=None}; } else { return r2; } } else {
/* * Calculate light color */ color lightColor(const intersection *inter, const ray *srcRay) { vec3 v = vector_normalized(vector_float_mul(-1.0f, srcRay->dir)); color cD = BLACK, refCoef = reflectCoef(inter->mat.reflect_coef, inter->normal, srcRay->dir); // For each light calculate and sum color for (int k = 0; k < num_lights; ++k) { vec3 l = vector_minus(lights[k].position, inter->position); float normL = vector_norm(l); l = vector_normalized(l); // Look for object between light source and current intersection ray objectRay; // Ray from object to light ray_init(&objectRay, inter->position, l, EPSILON, normL, 0); float interFound = 0.0f; for (int i = 0; i < object_count; ++i) { interFound += interDist(&objectRay, &(scene[i])); } if (!interFound) { vec3 h = vector_normalized(vector_add(l, v)); float sc_nl = clamp(vector_dot(inter->normal, l), 0.0f, 1.0f); float sc_hn = clamp(vector_dot(h, inter->normal), 0.0f, 1.0f); cD = vector_add(cD, vector_vec_mul(lights[k].col, vector_float_mul(sc_nl, (vector_add(vector_float_mul(1 / M_PI, inter->mat.kd), (vector_float_mul(pow(sc_hn, inter->mat.shininess), vector_float_mul(((inter->mat.shininess + 8) / (8 * M_PI)), refCoef)))))))); } } return cD; }
void ray_pinit( /* initialize ray-tracing processes */ char *otnm, int nproc ) { if (nobjects > 0) /* close old calculation */ ray_pdone(0); ray_init(otnm); /* load the shared scene */ ray_popen(nproc); /* fork children */ }
void raycasting(t_env *e) { int x; x = 0; e->ray.pos.x = e->player.pos.x; e->ray.pos.y = e->player.pos.y; while (x < e->width) { ray_init(e, x); ray_calc_step_side(e); ray_calc_dist(e); ray_draw(e, x); x++; } }
/* * Calculate reflection color */ color refColor(const intersection *inter, const ray *srcRay) { color cR = BLACK; if (srcRay->depth == MAX_DEPTH) return cR; intersection refInter; vec3 refVec = vector_reflect(srcRay->dir, inter->normal); ray refRay; // Ray from object to other object ray_init(&refRay, inter->position, refVec, EPSILON, 1000, srcRay->depth + 1); int bounceFound = 0; for (int k = 0; k < object_count; ++k) { bounceFound += intersect(&refRay, &(scene[k]), &refInter); } color refCoef = reflectCoef(inter->mat.reflect_coef, inter->normal, srcRay->dir); if (bounceFound) cR = vector_vec_mul(refCoef, vector_add(refColor(&refInter, &refRay), lightColor(&refInter, &refRay))); else cR = vector_vec_mul(refCoef, SKY_COLOR); return cR; }
void raytrace() { vec3 xR = theCamera.xdir; vec3 yR = vector_float_mul(1 / theCamera.aspect, theCamera.ydir); vec3 zR = vector_float_mul(1 / (tanf(0.5 * ((theCamera.fov / 180) * M_PI))), theCamera.zdir); int halfWidth = WIDTH / 2, halfHeight = HEIGHT / 2; for (int i = 0; i < WIDTH; ++i) { for (int j = 0; j < HEIGHT; ++j) { color c = BLACK; float deltas[4][2] = { { .25f, .25f }, { .25f, .75f }, { .75f, .25f }, { .75f, .75f } }; ray rays[4]; for (int n = 0; n < 4; ++n) { // Calculate ray vec3 x = vector_float_mul((i + deltas[n][0] - halfWidth) / halfWidth, xR); vec3 y = vector_float_mul((j + deltas[n][1] - halfHeight) / halfHeight, yR); vec3 d = vector_add(x, y); d = vector_add(d, zR); ray_init(&rays[n], theCamera.position, d); // Calculate intersection intersection inter; int found = 0; for (int k = 0; k < object_count; ++k) { found += (intersect(&rays[n], &(scene[k]), &inter)); // Keep the closest intersection } // Calculate pixel color if (found) { color cD = lightColor(&inter, &rays[n]); color cR = refColor(&inter, &rays[n]); c = vector_add(c, vector_add(cD, cR)); } else c = vector_add(c, SKY_COLOR); } // Mean output_image[j * WIDTH + i] = vector_float_mul(1.0f / 4.0f, c); } // Progress printf("%d%%\n", (int) (((float) i / WIDTH) * 100)); } printf("Done :)\n"); }
int main(int argc, char *argv[]) { #define check(ol,al) if (argv[i][ol] || \ badarg(argc-i-1,argv+i+1,al)) \ goto badopt #define check_bool(olen,var) switch (argv[i][olen]) { \ case '\0': var = !var; break; \ case 'y': case 'Y': case 't': case 'T': \ case '+': case '1': var = 1; break; \ case 'n': case 'N': case 'f': case 'F': \ case '-': case '0': var = 0; break; \ default: goto badopt; } char *octnm = NULL; char *err; int rval; int i; /* global program name */ progname = argv[0] = fixargv0(argv[0]); /* set our defaults */ shadthresh = .1; shadcert = .25; directrelay = 0; vspretest = 128; srcsizerat = 0.; specthresh = .3; specjitter = 1.; maxdepth = 6; minweight = 1e-2; ambacc = 0.3; ambres = 32; ambdiv = 256; ambssamp = 64; /* option city */ for (i = 1; i < argc; i++) { /* expand arguments */ while ((rval = expandarg(&argc, &argv, i)) > 0) ; if (rval < 0) { sprintf(errmsg, "cannot expand '%s'", argv[i]); error(SYSTEM, errmsg); } if (argv[i] == NULL || argv[i][0] != '-') break; /* break from options */ if (!strcmp(argv[i], "-version")) { puts(VersionID); quit(0); } if (!strcmp(argv[i], "-defaults") || !strcmp(argv[i], "-help")) { printdefaults(); quit(0); } if (!strcmp(argv[i], "-devices")) { printdevices(); quit(0); } rval = getrenderopt(argc-i, argv+i); if (rval >= 0) { i += rval; continue; } rval = getviewopt(&ourview, argc-i, argv+i); if (rval >= 0) { i += rval; continue; } switch (argv[i][1]) { case 'n': /* # processes */ check(2,"i"); nproc = atoi(argv[++i]); if (nproc <= 0) error(USER, "bad number of processes"); break; case 'v': /* view file */ if (argv[i][2] != 'f') goto badopt; check(3,"s"); rval = viewfile(argv[++i], &ourview, NULL); if (rval < 0) { sprintf(errmsg, "cannot open view file \"%s\"", argv[i]); error(SYSTEM, errmsg); } else if (rval == 0) { sprintf(errmsg, "bad view file \"%s\"", argv[i]); error(USER, errmsg); } break; case 'b': /* grayscale */ check_bool(2,greyscale); break; case 'p': /* pixel */ switch (argv[i][2]) { case 's': /* sample */ check(3,"i"); psample = atoi(argv[++i]); break; case 't': /* threshold */ check(3,"f"); maxdiff = atof(argv[++i]); break; case 'e': /* exposure */ check(3,"f"); exposure = atof(argv[++i]); if (argv[i][0] == '+' || argv[i][0] == '-') exposure = pow(2.0, exposure); break; default: goto badopt; } break; case 'w': /* warnings */ rval = erract[WARNING].pf != NULL; check_bool(2,rval); if (rval) erract[WARNING].pf = wputs; else erract[WARNING].pf = NULL; break; case 'e': /* error file */ check(2,"s"); errfile = argv[++i]; break; case 'o': /* output device */ check(2,"s"); dvcname = argv[++i]; break; case 'R': /* render input file */ check(2,"s"); strcpy(rifname, argv[++i]); break; default: goto badopt; } } err = setview(&ourview); /* set viewing parameters */ if (err != NULL) error(USER, err); /* set up signal handling */ sigdie(SIGINT, "Interrupt"); sigdie(SIGTERM, "Terminate"); #if !defined(_WIN32) && !defined(_WIN64) sigdie(SIGHUP, "Hangup"); sigdie(SIGPIPE, "Broken pipe"); sigdie(SIGALRM, "Alarm clock"); #endif /* open error file */ if (errfile != NULL) { if (freopen(errfile, "a", stderr) == NULL) quit(2); fprintf(stderr, "**************\n*** PID %5d: ", getpid()); printargs(argc, argv, stderr); putc('\n', stderr); fflush(stderr); } #ifdef NICE nice(NICE); /* lower priority */ #endif /* get octree */ if (i == argc) octnm = NULL; else if (i == argc-1) octnm = argv[i]; else goto badopt; if (octnm == NULL) error(USER, "missing octree argument"); /* set up output & start process(es) */ SET_FILE_BINARY(stdout); ray_init(octnm); /* also calls ray_init_pmap() */ /* temporary shortcut, until winrview is refactored into a "device" */ #ifndef WIN_RVIEW rview(); /* run interactive viewer */ devclose(); /* close output device */ #endif /* PMAP: free photon maps */ ray_done_pmap(); #ifdef WIN_RVIEW return 1; #endif quit(0); badopt: sprintf(errmsg, "command line error at '%s'", argv[i]); error(USER, errmsg); return 1; /* pro forma return */ #undef check #undef check_bool }