Color ray_shade(int level, Real w, Ray v, RContext *rc, Object *ol) { Inode *i = ray_intersect(ol, v); if (i != NULL) { Light *l; Real wf; Material *m = i->m; Vector3 p = ray_point(v, i->t); Cone recv = cone_make(p, i->n, PIOVER2); Color c = c_mult(m->c, c_scale(m->ka, ambient(rc))); rc->p = p; for (l = rc->l; l != NULL; l = l->next) if ((*l->transport)(l, recv, rc) && (wf = shadow(l, p, ol)) > RAY_WF_MIN) c = c_add(c, c_mult(m->c, c_scale(wf * m->kd * v3_dot(l->outdir,i->n), l->outcol))); if (level++ < MAX_RAY_LEVEL) { if ((wf = w * m->ks) > RAY_WF_MIN) { Ray r = ray_make(p, reflect_dir(v.d, i->n)); c = c_add(c, c_mult(m->s, c_scale(m->ks, ray_shade(level, wf, r, rc, ol)))); } if ((wf = w * m->kt) > RAY_WF_MIN) { Ray t = ray_make(p, refract_dir(v.d, i->n, (i->enter)? 1/m->ir: m->ir)); if (v3_sqrnorm(t.d) > 0) { c = c_add(c, c_mult(m->s, c_scale(m->kt, ray_shade(level, wf, t, rc, ol)))); } } } inode_free(i); return c; } else { return BG_COLOR; } }
double rayvolume(Prim *p, double stepsize){ Ray rayo; Vector3 vo; Vector3 vd; // Rays parallel to Y axis: vd = v3_make(0,1,0); double t0, t1; Inode *intersect; double i, j; double Vol = 0.0; for (i=-30; i<=30; i+=stepsize){ for (j=-20; j<=20; j+=stepsize){ // Origin of the rays XZ parallel plane: vo = v3_make(j*1.0,-100,-i*1.0); rayo = ray_make(vo,vd); if ( prim_intersect(p,rayo) != NULL ){ t0 = prim_intersect(p,rayo)[0].t; if (prim_intersect(p,rayo)[0].enter){ t1 = prim_intersect(p,rayo)[0].next->t; Vol += abs(t1 - t0); } else { } } else { } } }; return Vol*SQR(stepsize); }
static Real visible(int n, Poly **p, Vector3 v, Vector3 d) { Ray r = ray_make(v, d); while (n--) { Real t = poly3_ray_inter(p[n], poly3_plane(p[n]), r); if (t > REL_EPS && t < 1) return 0.0; } return 1.0; }
Real shadow(Light *l, Vector3 p, Object *ol) { Real t, kt; Inode *i; Vector3 d; if (l->type == LIGHT_AMBIENT) return 1.0; d = (l->type == LIGHT_DISTANT)? l->dir : v3_sub(l->loc, p); if ((i = ray_intersect(ol, ray_make(p, d))) == NULL) return 1.0; t = i->t; kt = i->m->kt; inode_free(i); if (l->type == LIGHT_DISTANT && t > RAY_EPS) return kt; else if (l->type != LIGHT_DISTANT && t > RAY_EPS && t < 1) return kt; else return 1.0; }
Ray ray_view(int u, int v) { Vector4 w = v4_m4mult(v4_make(u, v,s->view->sc.ur.z, 1), mdpy); return ray_make(v3_v4conv(v4_m4mult(v4_make(0, 0, 1, 0), mdpy)), v3_make(w.x, w.y, w.z)); }