void RealisticCamera::DrawRayPathFromScene(const Ray &r, bool arrow, bool toOpticalIntercept) const { Float elementZ = LensFrontZ() * -1; // Transform _ray_ from camera to lens system space static const Transform CameraToLens = Scale(1, 1, -1); Ray ray = CameraToLens(r); for (size_t i = 0; i < elementInterfaces.size(); ++i) { const LensElementInterface &element = elementInterfaces[i]; bool isStop = (element.curvatureRadius == 0); // Compute intersection of ray with lens element Float t; Normal3f n; if (isStop) t = -(ray.o.z - elementZ) / ray.d.z; else { Float radius = element.curvatureRadius; Float zCenter = elementZ + element.curvatureRadius; if (!IntersectSphericalElement(radius, zCenter, ray, &t, &n)) return; } Assert(t >= 0.f); printf("Line[{{%f, %f}, {%f, %f}}],", ray.o.z, ray.o.x, ray(t).z, ray(t).x); // Test intersection point against element aperture Point3f pHit = ray(t); Float r2 = pHit.x * pHit.x + pHit.y * pHit.y; Float apertureRadius2 = element.apertureRadius * element.apertureRadius; if (r2 > apertureRadius2) return; ray.o = pHit; // Update ray path for from-scene element interface interaction if (!isStop) { Vector3f wt; Float etaI = (i == 0 || elementInterfaces[i - 1].eta == 0.f) ? 1.f : elementInterfaces[i - 1].eta; Float etaT = (elementInterfaces[i].eta != 0.f) ? elementInterfaces[i].eta : 1.f; if (!Refract(Normalize(-ray.d), n, etaI / etaT, &wt)) return; ray.d = wt; } elementZ += element.thickness; } // go to the film plane by default { Float ta = -ray.o.z / ray.d.z; if (toOpticalIntercept) { ta = -ray.o.x / ray.d.x; printf("Point[{%f, %f}], ", ray(ta).z, ray(ta).x); } printf("%s[{{%f, %f}, {%f, %f}}]", arrow ? "Arrow" : "Line", ray.o.z, ray.o.x, ray(ta).z, ray(ta).x); } }
bool RealisticCamera::TraceLensesFromScene(const Ray &rCamera, Ray *rOut) const { Float elementZ = -LensFrontZ(); // Transform _rCamera_ from camera to lens system space static const Transform CameraToLens = Scale(1, 1, -1); Ray rLens = CameraToLens(rCamera); for (size_t i = 0; i < elementInterfaces.size(); ++i) { const LensElementInterface &element = elementInterfaces[i]; // Compute intersection of ray with lens element Float t; Normal3f n; bool isStop = (element.curvatureRadius == 0); if (isStop) t = (elementZ - rLens.o.z) / rLens.d.z; else { Float radius = element.curvatureRadius; Float zCenter = elementZ + element.curvatureRadius; if (!IntersectSphericalElement(radius, zCenter, rLens, &t, &n)) return false; } Assert(t >= 0); // Test intersection point against element aperture Point3f pHit = rLens(t); Float r2 = pHit.x * pHit.x + pHit.y * pHit.y; if (r2 > element.apertureRadius * element.apertureRadius) return false; rLens.o = pHit; // Update ray path for from-scene element interface interaction if (!isStop) { Vector3f wt; Float etaI = (i == 0 || elementInterfaces[i - 1].eta == 0) ? 1 : elementInterfaces[i - 1].eta; Float etaT = (elementInterfaces[i].eta != 0) ? elementInterfaces[i].eta : 1; if (!Refract(Normalize(-rLens.d), n, etaI / etaT, &wt)) return false; rLens.d = wt; } elementZ += element.thickness; } // Transform _rLens_ from lens system space back to camera space if (rOut != nullptr) { static const Transform LensToCamera = Scale(1, 1, -1); *rOut = LensToCamera(rLens); } return true; }
void RealisticCamera::DrawRayPathFromFilm(const Ray &r, bool arrow, bool toOpticalIntercept) const { Float elementZ = 0; // Transform _ray_ from camera to lens system space static const Transform CameraToLens = Scale(1, 1, -1); Ray ray = CameraToLens(r); printf("{ "); if (!TraceLensesFromFilm(r, nullptr)) printf("Dashed, "); for (int i = elementInterfaces.size() - 1; i >= 0; --i) { const LensElementInterface &element = elementInterfaces[i]; elementZ -= element.thickness; bool isStop = (element.curvatureRadius == 0); // Compute intersection of ray with lens element Float t; Normal3f n; if (isStop) t = -(ray.o.z - elementZ) / ray.d.z; else { Float radius = element.curvatureRadius; Float zCenter = elementZ + element.curvatureRadius; if (!IntersectSphericalElement(radius, zCenter, ray, &t, &n)) goto done; } Assert(t >= 0); printf("Line[{{%f, %f}, {%f, %f}}],", ray.o.z, ray.o.x, ray(t).z, ray(t).x); // Test intersection point against element aperture Point3f pHit = ray(t); Float r2 = pHit.x * pHit.x + pHit.y * pHit.y; Float apertureRadius2 = element.apertureRadius * element.apertureRadius; if (r2 > apertureRadius2) goto done; ray.o = pHit; // Update ray path for element interface interaction if (!isStop) { Vector3f wt; Float etaI = element.eta; Float etaT = (i > 0 && elementInterfaces[i - 1].eta != 0) ? elementInterfaces[i - 1].eta : 1; if (!Refract(Normalize(-ray.d), n, etaI / etaT, &wt)) goto done; ray.d = wt; } } ray.d = Normalize(ray.d); { Float ta = std::abs(elementZ / 4); if (toOpticalIntercept) { ta = -ray.o.x / ray.d.x; printf("Point[{%f, %f}], ", ray(ta).z, ray(ta).x); } printf("%s[{{%f, %f}, {%f, %f}}]", arrow ? "Arrow" : "Line", ray.o.z, ray.o.x, ray(ta).z, ray(ta).x); // overdraw the optical axis if needed... if (toOpticalIntercept) printf(", Line[{{%f, 0}, {%f, 0}}]", ray.o.z, ray(ta).z * 1.05f); } done: printf("}"); }