学习光线追踪(3)---相机

0.简介

相机应该都用过吧,手机上面有,数码相机什么的,原理是相机里面有接收光线的元件,就是感光元件,然后将光信号转换成电信号,之后就变成了我们拍摄出来的图像,这里我们来模拟一个相机,只不过我们的相机不是像真实的那样接收光线,而是要从相机发出光线,之后,根据相机发出的光线,追随着这些光线,找到光线能打到的无物体,然后再继续追踪反射,折射的光线,最后将本来是最终打到相机上的一束光线逆向的找到的来的路径,将这沿途的颜色叠加在一起,就得到了屏幕上对应像素点的颜色,每条从相机出发的光线就是与图像上像素点一一对应的,也就是从每一个像素点出发,寻找这个像素点都受到哪些光线影响。

1.相机模型

模拟相机,首先要确定一个相机的基本坐标系,相机有一个自身的坐标系,利用这个坐标系来确定屏幕上像素发出光线的信息。相机类的设计如下。

class Camera
{
public:
	Camera();
	Camera(vec3 _position,vec3 _front,vec3 _up,float fov/*field of view 视场*/);
	//前方
	vec3 front;
	//上方
	vec3 up;
	//右方
	vec3 right;
	//相机位置
	vec3 position;
	//对应长宽的缩放比例
	float scale;
	//生成光线
	Ray generateRay(float x,float y);
	~Camera();
};

相机初始化的函数如下

Camera::Camera(vec3 _position, vec3 _front, vec3 _up, float fov)
{
	position = _position;
	//保存相机前方向
	front = glm::normalize(_front);
	//计算相机右方向
	right = glm::normalize(glm::cross(front,_up));
	//计算相机上方向
	up = glm::cross(right, front);
	//这里是计算相机投影范围的,暂时考虑的是正方形区域
	scale = tan(fov * 0.5 * 3.141592654 / 180) * 2;
}

以相机前方向为主,利用前和上方向,组合出右方向,此时右方向和前方向一定垂直,再用右方向和前方向重新确定上方向,此时,三个方向向量必定互相垂直。scale是相机显示的范围,根据fov角度计算的。

如图,scale值就是红色箭头的2倍长度

因为后面要将图像映射区域坐标从[0,1]范围转换到[-1,1]范围,所以要2倍的scale值。

有了上面那些向量之后,就可以计算某一个像素点发出的光线方向了,对应代码如下。

Ray Camera::generateRay(float x, float y)
{
	vec3 u = right * vec1(x-0.5) * vec1(scale);
	vec3 v = up * vec1(y - 0.5) * vec1(scale);
	return Ray(glm::normalize(front+u+v),position,0,vec3(0,0,0));
}

u,v向量就是偏移向量,原本的front是图像的中心(0,0)坐标,u,v就是对应不同坐标的偏移。

一条光线向量生成

上图表示了光线生成函数的过程。

投影区域范围变换到[-1,1],所以要减去0.5,乘以2倍的区域边长。

图像坐标变换示意图

这样,相机就可以根据图像像素位置来生成对应像素射入的光线了,之后就能根据生成的光线进行反向追踪了。

2.说明

源代码暂时不会公布,因为还没有出第一个效果,并且大部分核心代码都在博客中公布,等能显示第一张图像开始我会将完整代码放在网上供参考学习。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值