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);

在这部分的课程中,我们将专注于使用光线追踪来渲染图像。在光线追踪中 最重要的操作之一就是找到光线与物体的交点。一旦找到光线与物体的交点,就 可以执行着色并返回像素颜色。在这次作业中,我们需要实现两个部分:光线的 生成和光线与三角的相交。本次代码框架的工作流程为: 1. 从 main 函数开始。我们定义场景的参数,添加物体(球体或三角形)到场景 中,并设置其材质,然后将光源添加到场景中。 2. 调用 Render(scene) 函数。在遍历所有像素的循环里,生成对应的光线并将 返回的颜色保存在帧缓冲区(framebuffer)中。在渲染过程结束后,帧缓冲 区中的信息将被保存为图像。 3. 在生成像素对应的光线后,我们调用 CastRay 函数,该函数调用 trace 来 查询光线与场景中最近的对象的交点。 4. 然后,我们在此交点执行着色。我们设置了三种不同的着色情况,并且已经 为你提供了代码。 你需要修改的函数是: • Renderer.cpp 中的 Render():这里你需要为每个像素生成一条对应的光 线,然后调用函数 castRay() 来得到颜色,最后将颜色存储在帧缓冲区的相 应像素中。 • Triangle.hpp 中的 rayTriangleIntersect(): v0, v1, v2 是三角形的三个 顶点, orig 是光线的起点, dir 是光线单位化的方向向量。 tnear, u, v 是你需 要使用我们课上推导的 Moller-Trumbore 算法来更新的参数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值