Пример #1
0
float OrthoCamera::GenerateRayDifferential(const CameraSample &sample,
        RayDifferential *ray) const {
    // Compute main orthographic viewing ray

    // Generate raster and camera samples
    PbrtPoint Pras(sample.imageX, sample.imageY, 0);
    PbrtPoint Pcamera;
    RasterToCamera(Pras, &Pcamera);
    *ray = RayDifferential(Pcamera, Vector(0,0,1), 0., INFINITY);

    // Modify ray for depth of field
    if (lensRadius > 0.) {
        // Sample point on lens
        float lensU, lensV;
        ConcentricSampleDisk(sample.lensU, sample.lensV, &lensU, &lensV);
        lensU *= lensRadius;
        lensV *= lensRadius;

        // Compute point on plane of focus
        float ft = focalDistance / ray->d.z;
        PbrtPoint Pfocus = (*ray)(ft);

        // Update ray for effect of lens
        ray->o = PbrtPoint(lensU, lensV, 0.f);
        ray->d = Normalize(Pfocus - ray->o);
    }
    ray->time = Lerp(sample.time, shutterOpen, shutterClose);
    ray->rxOrigin = ray->o + dxCamera;
    ray->ryOrigin = ray->o + dyCamera;
    ray->rxDirection = ray->ryDirection = ray->d;
    ray->hasDifferentials = true;
    CameraToWorld(*ray, ray);
    return 1.f;
}
Пример #2
0
double PerspectiveCamera::generateRay(const CameraSample &sample,
                                      Ray *ray) const {
    auto cameraLength = 1.0_um;

    // Generate raster and camera samples
    Point3D Pras(sample.imageX*cameraLength, sample.imageY*cameraLength, 0);
    Point3D Pcamera;
    RasterToCamera(Pras, &Pcamera);
    *ray = Ray(Point3D(), normalize(Length3D(Pcamera)));
    // Modify ray for depth of field
    if (lensRadius > 0.0_um) {
        // Sample point on lens
        double lensU, lensV;
        concentricSampleDisk(sample.lensU, sample.lensV, &lensU, &lensV);

        Length x = lensU * lensRadius;
        Length y = lensV * lensRadius;

        // Compute point on plane of focus
        double ft = focalDistance / ray->m_direction.z;
        Point3D Pfocus = (*ray)(ft);

        // Update ray for effect of lens
        ray->m_origin = Point3D(x, y, 0.0_um);
        ray->m_direction = normalize(Pfocus - ray->m_origin);
    }
    ray->m_time = sample.time;
    CameraToWorld(*ray, ray);
    return 1.f;
}
Пример #3
0
float PerspectiveCamera::GenerateRayDifferential(const CameraSample &sample,
                                                 RayDifferential *ray) const {
    // Generate raster and camera samples
    Point Pras(sample.imageX, sample.imageY, 0);
    Point Pcamera;
    RasterToCamera(Pras, &Pcamera);
    Vector dir = Normalize(Vector(Pcamera.x, Pcamera.y, Pcamera.z));
    *ray = RayDifferential(Point(0,0,0), dir, 0.f, INFINITY);
    // Modify ray for depth of field
    if (lensRadius > 0.) {
        // Sample point on lens
        float lensU, lensV;
        ConcentricSampleDisk(sample.lensU, sample.lensV, &lensU, &lensV);
        lensU *= lensRadius;
        lensV *= lensRadius;

        // Compute point on plane of focus
        float ft = focalDistance / ray->d.z;
        Point Pfocus = (*ray)(ft);

        // Update ray for effect of lens
        ray->o = Point(lensU, lensV, 0.f);
        ray->d = Normalize(Pfocus - ray->o);
    }

    // Compute offset rays for _PerspectiveCamera_ ray differentials
    ray->rxOrigin = ray->ryOrigin = ray->o;
    ray->rxDirection = Normalize(Vector(Pcamera) + dxCamera);
    ray->ryDirection = Normalize(Vector(Pcamera) + dyCamera);
    ray->time = Lerp(sample.time, shutterOpen, shutterClose);
    CameraToWorld(*ray, ray);
    ray->hasDifferentials = true;
    return 1.f;
}
Пример #4
0
float PerspectiveCamera::GenerateRay(const CameraSample &sample,
                                     Ray *ray) const {
    // Generate raster and camera samples
    Point Pras(sample.imageX, sample.imageY, 0);
    Point Pcamera;
    RasterToCamera(Pras, &Pcamera);
    *ray = Ray(Point(0,0,0), Normalize(Vector(Pcamera)), 0.f, INFINITY);
    // Modify ray for depth of field
    if (lensRadius > 0.) {
        // Sample point on lens
        float lensU, lensV;
        ConcentricSampleDisk(sample.lensU, sample.lensV, &lensU, &lensV);
        lensU *= lensRadius;
        lensV *= lensRadius;

        // Compute point on plane of focus
        float ft = focalDistance / ray->d.z;
        Point Pfocus = (*ray)(ft);

        // Update ray for effect of lens
        ray->o = Point(lensU, lensV, 0.f);
        ray->d = Normalize(Pfocus - ray->o);
    }
    ray->time = Lerp(sample.time, shutterOpen, shutterClose);
    CameraToWorld(*ray, ray);
    return 1.f;
}
Пример #5
0
float OrthoCamera::GenerateRay(const Sample &sample,
                               Ray *ray) const {
	// Generate raster and camera samples
	Point Pras(sample.imageX, sample.imageY, 0);
	Point Pcamera;
	RasterToCamera(Pras, &Pcamera);
	ray->o = Pcamera;
	ray->d = Vector(0,0,1);
	// Set ray time value
	ray->time = Lerp(sample.time, ShutterOpen, ShutterClose);
	// Modify ray for depth of field
	if (LensRadius > 0.) {
		// Sample point on lens
		float lensU, lensV;
		ConcentricSampleDisk(sample.lensU, sample.lensV,
		                     &lensU, &lensV);
		lensU *= LensRadius;
		lensV *= LensRadius;
		// Compute point on plane of focus
		float ft = (FocalDistance - ClipHither) / ray->d.z;
		Point Pfocus = (*ray)(ft);
		// Update ray for effect of lens
		ray->o.x += lensU * (FocalDistance - ClipHither) / FocalDistance;
		ray->o.y += lensV * (FocalDistance - ClipHither) / FocalDistance;
		ray->d = Pfocus - ray->o;
	}
	ray->mint = 0.;
	ray->maxt = ClipYon - ClipHither;
	ray->d = Normalize(ray->d);
	CameraToWorld(*ray, ray);
	return 1.f;
}
Пример #6
0
float RealisticCamera::GenerateRay(const CameraSample &sample, Ray *ray) const {

	// STEP 1 - generate first ray

	// use sample->imageX and sample->imageY to get raster-space coordinates of the sample point on the film.
	Point Pras(sample.imageX, sample.imageY, 0);
	Point Pcamera;
	RasterToCamera(Pras, &Pcamera);

	// use sample->lensU and sample->lensV to get a sample position on the lens
	float lensU, lensV;
	ConcentricSampleDisk(sample.lensU, sample.lensV, &lensU, &lensV);
	lensU *= lens[lensnum - 1].apradius;
	lensV *= lens[lensnum - 1].apradius;

	float pfz = lens[lensnum - 1].centerz + sqrtf(lens[lensnum - 1].radiusSquard - lensU * lensU - lensV * lensV);
	Point Pfocus = Point(lensU, lensV, pfz);
	Vector Rdir = Normalize(Pfocus - Pcamera);
	ray->o = Pcamera;
	ray->d = Rdir;
	ray->time = Lerp(sample.time, shutteropen, shutterclose);

	// STEP 2 - ray through the lens
	Point Plens;
	for (int i = 0; i < lensnum; i++) {

		lensData ls = lens[i];

		if ( ls.plane ){
			float t = (ls.centerz - ray->o.z) / ray->d.z;
			float x = ray->o.x + t * ray->d.x;
			float y = ray->o.y + t * ray->d.y;

			if (x * x + y * y > ls.apradiusSquared) 
				return 0.f;
		}
		else
		{
			// Find the intersection point
			Vector oc = ray->o - Point(0.f, 0.f, ls.centerz);
			float l1 = oc.LengthSquared();
			float rz = Dot(oc, ray->d);
			float l2 = rz *rz - l1 + ls.radiusSquard;
			if (l2 < 0.f)
				return 0.f;
			float t = (ls.radius > 0.f) ? (-rz + sqrtf(l2)) : (-rz - sqrtf(l2));
			
			Plens = ray->o + t * ray->d;
			if (Plens.x*Plens.x + Plens.y*Plens.y > ls.apradiusSquared) 
				return 0.f;

			// calculate the refraction 
			Vector N = (ls.radius > 0.f) ? Normalize(Point(0.f, 0.f, ls.centerz) - Plens)
				: Normalize(Plens - Point(0.f, 0.f, ls.centerz));
			Vector I = ray->d;
			float c1, c2;
			c1 = -Dot(I, N);
			c2 = ls.nratioSquared - 1.f + c1 * c1;
			if (c2 < 0.f) 	
				return 0.f;
			c2 = c1 - sqrtf(c2);
			Vector T = (I + c2 * N) / ls.nratio;

			ray->o = Plens;
			ray->d = Normalize(T);
		}
	}

	ray->mint = cliphiter;
	ray->maxt = (clipyon - cliphiter) / ray->d.z;

	// STEP 3 - output the ray and weight
	CameraToWorld(*ray, ray);
	
	float weight = Dot(Normalize(Plens - Pcamera), Vector(0, 0, 1));
	weight *= weight / totallength;
	weight *= weight * (lens[lensnum - 1].apradiusSquared * M_PI);
	return weight;

}