public override Isect intersect(Ray ry) { double b, disc, t; Isect ip; v.sub2(c, ry.P); b = Vec.dot(v, ry.D); disc = b * b - Vec.dot(v, v) + r2; if (disc < 0.0) { return null; } disc = Math.Sqrt(disc); t = (b - disc < 1e-6) ? b + disc : b - disc; if (t < 1e-6) { return null; } ip = new Isect(); ip.t = t; ip.enter = Vec.dot(v, v) > r2 + 1e-6 ? 1 : 0; ip.prim = this; ip.surf = surf; return ip; }
/** * Returns the shaded color * @return The color in Vec form (rgb) */ Vec shade(int level, double weight, Vec P, Vec N, Vec I, Isect hit) { double n1, n2, eta, c1, cs2; Vec r; Vec tcol; Vec R; double t, diff, spec; Surface surf; Vec col; int l; col = new Vec(); surf = hit.surf; R = new Vec(); if (surf.shine > 1e-6) { R = SpecularDirection(I, N); } // Computes the effectof each light for (l = 0; l < lights.Length; l++) { L.sub2(lights[l].pos, P); if (Vec.dot(N, L) >= 0.0) { t = L.normalize(); tRay.P = P; tRay.D = L; // Checks if there is a shadow if (Shadow(tRay, t) > 0) { diff = Vec.dot(N, L) * surf.kd * lights[l].brightness; col.adds(diff, surf.color); if (surf.shine > 1e-6) { spec = Vec.dot(R, L); if (spec > 1e-6) { spec = Math.Pow(spec, surf.shine); col.x += spec; col.y += spec; col.z += spec; } } } } // if } // for tRay.P = P; if (surf.ks * weight > 1e-3) { tRay.D = SpecularDirection(I, N); tcol = trace(level + 1, surf.ks * weight, tRay); col.adds(surf.ks, tcol); } if (surf.kt * weight > 1e-3) { if (hit.enter > 0) tRay.D = TransDir(null, surf, I, N); else tRay.D = TransDir(surf, null, I, N); tcol = trace(level + 1, surf.kt * weight, tRay); col.adds(surf.kt, tcol); } // garbaging... tcol = null; surf = null; return col; }