PBRT_V2 总结记录 <17> GenerateRay 和 Depth Of Field

这次主要是记录 PerspectiveCamera : GenerateRay 函数的思路:


// Ray : RasterToCamera -> CameraToWorld , 所以 得到的Ray是World Space
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;
		// P667
		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
		// 这里就是从Camera的原点Point(0.f, 0.f, 0.f); 变成 Point(lensU, lensV, 0.f);
		ray->o = Point(lensU, lensV, 0.f);
		ray->d = Normalize(Pfocus - ray->o);
	}
	ray->time = sample.time;
	CameraToWorld(*ray, ray);
	return 1.f;
}

这个方法主要的作用就是 从一个 采样点 CameraSample 生成一条 Ray。

细节:

a.

Point Pras(sample.imageX, sample.imageY, 0);
Point Pcamera;
RasterToCamera(Pras, &Pcamera);
*ray = Ray(Point(0, 0, 0), Normalize(Vector(Pcamera)), 0.f, INFINITY);

作用:把 Image Plane 的 采样点  Pras(sample.imageX, sample.imageY, 0) 变换到 Camera Space 中 Point Pcamera;,生成一条射线  *ray = Ray(Point(0, 0, 0), Normalize(Vector(Pcamera)), 0.f, INFINITY); 这条射线 是在 Camera Space 中的,那就是 

上面的代码就是在 Camera Space 中 生成一条 射线,这条射线的 原点 是 (0,0,0),方向是  (Pcamera - (0,0,0)),也就是射线的方向是 ” 原点 指向 采样点 “。

 CameraToWorld(*ray, ray);

 最后再把 这条在 Camera Space 的ray 变换到 World Space 中。

b.景深

1. 思路:

(在 Focal plane 上的点,是可以 完美聚焦,但是不在 Focal plane的点,就会导致 模糊)

Real-world cameras have a lens with finite aperture(光圈) and lens(透镜) controls that adjust the lens
position with respect to the film plane. Because the aperture is finite, objects in the scene aren’t all
imaged onto the film in perfect focus. Here, the point p1 doesn’t lie on the plane of points in perfect
focus, so it images to an area p‘1 on the film and is blurred. The point p2 does lie on the focal plane,
so it images to a point p’2 and is in focus.
Either increasing the aperture size or increasing an object’s
distance from the focal plane will increase an out-of-focus object’s blurriness.

(先计算 利用 B点(the center of the lens)和A点 做一条射线,计算出 这条射线在 Focal plane 上的交点 C,然后 在  D点(the lens position sample)和C点再形成一条新的射线来进行 光线追踪, 这样,如果在 Focal plane 的点,与 新的射线相交的话,依然可以求出 与旧射线一样的交点,但是不在 Focal plane 的点与新的射线相交的话,求出的相交点与旧的射线的相交点不一样,所以模糊了,而且,随着Pixel的采样点数目越高,越模糊)

(a) For a pinhole camera model, a single camera ray is associated with each point on
the film plane (filled circle), given by the ray that passes through the single point of the pinhole lens
(empty circle). (b) For a camera model with a finite aperture, we sample a point (filled circle) on the
disk-shaped lens for each ray. We can also compute the ray that passes through the center of the
lens (corresponding to the pinhole model) and the point where it intersects the focal plane (solid line)
.
We know that all objects in the focal plane must be in focus, regardless of the lens sample position.
Therefore, the ray corresponding to the lens position sample (dashed line) is given by the ray starting
on the lens sample point and passing through the computed intersection point on the focal plane.

It is generally necessary to trace many rays for each
image pixel in order to adequately sample the lens for smooth depth of field.

2. 细节

float lensRadius, focalDistance;

作用:(一个是控制 透镜的半径,一个是控制 Focal Plane的距离,只有的 Focal Plane上的点才可以 完美聚焦,其他会模糊)

one sets the size of the
lens aperture, and the other sets the focal distance.

if (lensRadius > 0.) {
		// Sample point on lens
		float lensU, lensV;
		// P667
		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
		// 这里就是从Camera的原点Point(0.f, 0.f, 0.f); 变成 Point(lensU, lensV, 0.f);
		ray->o = Point(lensU, lensV, 0.f);
		ray->d = Normalize(Pfocus - ray->o);
	}

ConcentricSampleDisk() function:

作用:

(利用 sample.lensU, sample.lensV 采样点数据,得到 均匀分布的 lensU, lensV,lensU, lensV 都是[-1,1])

The ConcentricSampleDisk() function, defined in Chapter 13, takes a (u, v) sample position
in [0, 1] and maps it to a 2D unit disk centered at the origin (0, 0). To turn this into
a point on the lens, these coordinates are scaled by the lens radius. The CameraSample
class provides the (u, v) lens-sampling parameters in the CameraSample::lensU and
CameraSample::lensV fields.

Peter Shirley (1997) developed a “concentric” mapping from the unit square to the
unit circle that avoids this problem. The concentric mapping takes points in the square
[−1, 1] to the unit disk by uniformly mapping concentric squares to concentric circles



 

float ft = focalDistance / ray->d.z;

Point Pfocus = (*ray)(ft);

作用:

Compute point on plane of focus


 

ray->o = Point(lensU, lensV, 0.f);
ray->d = Normalize(Pfocus - ray->o);

作用:

这里就是从Camera的原点Point(0.f, 0.f, 0.f); 变成 Point(lensU, lensV, 0.f);

猜你喜欢

转载自blog.csdn.net/aa20274270/article/details/83047805