public static Color TraceRay(Vector3 start, Vector3 dir, Scene scene, int depth_) { if (depth_ >= scene.MaxRayDepth) { return(scene.Ambient); } Ray ray = new Ray() { Start = start, Dir = dir }; Intersection isect = scene.FirstIntersect(ray); if (null == isect) { return(scene.Background); } //light hit Surface surf = isect.Thing.Surface; Vector3 pos = isect.Ray.Start + isect.Dist * isect.Ray.Dir; Vector3 invRayDir = -isect.Ray.Dir; Vector3 normal = isect.Thing.Normal(pos, isect.Inside); Vector3 reflect = Vector3.Reflect(normal, invRayDir); Color ambient = scene.Ambient; Color local = LocalLighting(surf, pos, normal, reflect, scene); float refl = surf.Reflect(pos); float alpha = surf.Alpha(pos); Color reflected = Color.Black(); if (0 < refl && 0 < alpha) { reflected = TraceRay(pos + .001 * reflect, reflect, scene, depth_ + 1) * refl; } Color transmitted = Color.Black(); if (1 > alpha) { double eta = isect.Inside ? 1 / surf.Eta : surf.Eta; Vector3 transmit = Vector3.Refract(normal, invRayDir, eta); transmitted = TraceRay(pos + .001 * transmit, transmit, scene, depth_ + 1); } return(ambient + (local + reflected) * alpha + transmitted * (1 - alpha)); }