00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "stdafx.h"
00027 #include "cameras/perspective.h"
00028 #include "paramset.h"
00029 #include "sampler.h"
00030 #include "montecarlo.h"
00031
00032
00033 PerspectiveCamera:: PerspectiveCamera(const AnimatedTransform &cam2world,
00034 const float screenWindow[4], float sopen, float sclose,
00035 float lensr, float focald, float fov, Film *f)
00036 : ProjectiveCamera(cam2world, Perspective(fov, 1e-2f, 1000.f),
00037 screenWindow, sopen, sclose, lensr, focald, f) {
00038
00039 dxCamera = RasterToCamera(Point(1,0,0)) - RasterToCamera(Point(0,0,0));
00040 dyCamera = RasterToCamera(Point(0,1,0)) - RasterToCamera(Point(0,0,0));
00041 }
00042
00043
00044 float PerspectiveCamera::GenerateRay(const CameraSample &sample,
00045 Ray *ray) const {
00046
00047 Point Pras(sample.imageX, sample.imageY, 0);
00048 Point Pcamera;
00049 RasterToCamera(Pras, &Pcamera);
00050 *ray = Ray(Point(0,0,0), Vector(Pcamera), 0.f, INFINITY);
00051
00052 if (lensRadius > 0.) {
00053
00054 float lensU, lensV;
00055 ConcentricSampleDisk(sample.lensU, sample.lensV, &lensU, &lensV);
00056 lensU *= lensRadius;
00057 lensV *= lensRadius;
00058
00059
00060 float ft = focalDistance / ray->d.z;
00061 Point Pfocus = (*ray)(ft);
00062
00063
00064 ray->o = Point(lensU, lensV, 0.f);
00065 ray->d = Normalize(Pfocus - ray->o);
00066 }
00067 ray->time = Lerp(sample.time, shutterOpen, shutterClose);
00068 CameraToWorld(*ray, ray);
00069 return 1.f;
00070 }
00071
00072
00073 float PerspectiveCamera::GenerateRayDifferential(const CameraSample &sample,
00074 RayDifferential *ray) const {
00075
00076 Point Pras(sample.imageX, sample.imageY, 0);
00077 Point Pcamera;
00078 RasterToCamera(Pras, &Pcamera);
00079 Vector dir = Normalize(Vector(Pcamera.x, Pcamera.y, Pcamera.z));
00080 *ray = RayDifferential(Point(0,0,0), dir, 0.f, INFINITY);
00081
00082 if (lensRadius > 0.) {
00083
00084 float lensU, lensV;
00085 ConcentricSampleDisk(sample.lensU, sample.lensV, &lensU, &lensV);
00086 lensU *= lensRadius;
00087 lensV *= lensRadius;
00088
00089
00090 float ft = focalDistance / ray->d.z;
00091 Point Pfocus = (*ray)(ft);
00092
00093
00094 ray->o = Point(lensU, lensV, 0.f);
00095 ray->d = Normalize(Pfocus - ray->o);
00096 }
00097
00098
00099 ray->rxOrigin = ray->ryOrigin = ray->o;
00100 ray->rxDirection = Normalize(Vector(Pcamera) + dxCamera);
00101 ray->ryDirection = Normalize(Vector(Pcamera) + dyCamera);
00102 ray->time = Lerp(sample.time, shutterOpen, shutterClose);
00103 CameraToWorld(*ray, ray);
00104 ray->hasDifferentials = true;
00105 return 1.f;
00106 }
00107
00108
00109 PerspectiveCamera *CreatePerspectiveCamera(const ParamSet ¶ms,
00110 const AnimatedTransform &cam2world, Film *film) {
00111
00112 float shutteropen = params.FindOneFloat("shutteropen", 0.f);
00113 float shutterclose = params.FindOneFloat("shutterclose", 1.f);
00114 float lensradius = params.FindOneFloat("lensradius", 0.f);
00115 float focaldistance = params.FindOneFloat("focaldistance", 1e30f);
00116 float frame = params.FindOneFloat("frameaspectratio",
00117 float(film->xResolution)/float(film->yResolution));
00118 float screen[4];
00119 if (frame > 1.f) {
00120 screen[0] = -frame;
00121 screen[1] = frame;
00122 screen[2] = -1.f;
00123 screen[3] = 1.f;
00124 }
00125 else {
00126 screen[0] = -1.f;
00127 screen[1] = 1.f;
00128 screen[2] = -1.f / frame;
00129 screen[3] = 1.f / frame;
00130 }
00131 int swi;
00132 const float *sw = params.FindFloat("screenwindow", &swi);
00133 if (sw && swi == 4)
00134 memcpy(screen, sw, 4*sizeof(float));
00135 float fov = params.FindOneFloat("fov", 90.);
00136 float halffov = params.FindOneFloat("halffov", -1.f);
00137 if (halffov > 0.f)
00138
00139 fov = 2.f * halffov;
00140 return new PerspectiveCamera(cam2world, screen, shutteropen,
00141 shutterclose, lensradius, focaldistance, fov, film);
00142 }
00143
00144