光线跟踪smallpt详解 (二)

来源:互联网 发布:穿衣打扮知乎 编辑:程序博客网 时间:2024/05/16 06:53

本文主要是为了记录我学习smallpt的过程。第一部分是关于整个程序的大致分解。第二部分主要说一下我对main函数中cx和cy的理解。第三部分主要说明光线跟踪的每一行代码所用到的数学知识。

本文主要说一下自己的理解,
关于smallpt的cx,cy是怎么来的,是用来做什么的?

1. 透视投影的原理

这里写图片描述
如果是小孔成像的话,我们应该是投影在z=-d的平面上,但是这样做涉及到负值操作,还使图像反了。如果我们将投影平面移到z = d,这样做就可以避免负值问题。(但是有个问题就是,物体在摄像机和z=d平面之间的物体,电脑就无法绘制了)

2. cx和cy的定义

这里写图片描述
及计算光线d的代码

Vec d = cx*(((sx + .5 + dx) / 2 + x) / w - .5) +                            cy*(((sy + .5 + dy) / 2 + y) / h - .5) + cam.d;

其中sx,sy是[0,1],dx,dy的范围是[-1,1],dx,dy的分布函数
这里写图片描述

所以(sx + .5 + dx) / 2这个的值得范围是[-0.25, 0.75]。这个值主要是为了在随机采样时,对x进行偏移。我们如果把他忽略不计。
那么(((sx + .5 + dx) / 2 + x) / w - .5)的值其实是在[-0.5, 0.5]的。
当x = w-1, y = 0时,
(0.5*cx)+(-0.5*cy)+cam.d是为了计算最大角度的射出光线。

图例1, 如果我们的cx = (w / h)
这里写图片描述

图例2, 如果我们的cx = (w/h *0.5135),我们的最大角度肯定比图例1小。
这里写图片描述

3. 验证结果

我的理解是:
0.5135这个参数就是为了设置视角大小的。
作者计算好了角度之后,才这样设置的。

例子1

double testVal = 1.0;double cx = Vec(w*.testVal / h), cy = (cx.cross(cam.d)).norm()*.testVal;

这里写图片描述

例子2

double testVal = 0.5135;double cx = Vec(w*.testVal / h), cy = (cx.cross(cam.d)).norm()*.testVal;

这里写图片描述

double testVal = 0.2;double cx = Vec(w*.testVal / h), cy = (cx.cross(cam.d)).norm()*.testVal;

这里写图片描述

0 0
原创粉丝点击