smallpt详解(二)
本文主要说一下自己的理解,
关于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;
例子3
double testVal = 0.2;
double cx = Vec(w * testVal / h), cy = (cx.cross(cam.d)).norm() * testVal;