学习光线追踪(8)---材质反射

0.简介

这次实现以下反射效果,这里开始就涉及光线追踪原理了。

1.反射

光线反射,要经过多个物体反射,这里我们使用光线追踪方法,追踪折射光线。

Ray rayTrac(Ray ray,vector<Polygon*> s,int times)
{
	Ray r(vec3(0,0,0),vec3(0,0,0),0,vec3(0,0,0),nullptr);
	if (times <= 0)
		return r;
	float minDistance= FLT_MAX;
	for (auto obj : s)
	{
		//找到最近的物体
		Ray rayTemp = obj->intersect(ray);
		if (rayTemp.distance < minDistance )
		{
			minDistance = rayTemp.distance;
			r = rayTemp;
		}
	}
	if (r.polygon == nullptr)
		return Ray(vec3(0, 0, 0), vec3(0, 0, 0), 0, vec3(0, 0, 0), nullptr);
	//计算反射光线
	vec3 reflectRayNormal = r.normal;
	//if (dot(r.direction , reflectRayNormal) > 0)
	//	reflectRayNormal = -reflectRayNormal;
	//构造反射光线
	Ray reflectRay = Ray(normalize(r.direction - (2 * dot(r.direction, reflectRayNormal)) * reflectRayNormal),r.end,0,vec3(0,0,0),nullptr);
	//获得反射光线方向
	reflectRay = rayTrac(reflectRay,s,times-1);
	//计算物体返回的颜色
	r = ((Polygon*)(r.polygon))->sample(r, reflectRay ,r);
	return r;
}

这个函数会追踪3次折射光线,开始先找到从逆向光线出发的位置,这里和之前说的光线都是逆向的光线,找到逆向光线打到的最近的物体,然后计算这个物体上的反射光线。反射光线比较好计算,已知逆向入射光线,和法向量,就可以求得逆向的反射光线,应该不难,下面我把原理图画一下。

反射光线计算示意图

所以反射光线就是这样计算 b=a-2*(n*a)*n

计算好反射光线后,就要对反射光线进行追踪,就是递归追踪函数,这里递归了3层。然后将反射光线的结果输入到颜色采样中计算。

Ray Polygon::sample(Ray out, Ray reflect, Ray refract)
{
	Ray res(out.direction, out.position, 0, vec3(0, 0, 0), out.polygon);
	float cosa = dot(out.normal ,normalize(-out.direction));//光线入射角和面法向量的cos值
	//发光计算
	res.color += m.color * m.light * std::fmaxf(cosa,0);
	//反射颜色计算
	res.color += reflect.color * m.specular;

	return res;
}

这样一来就支持了反射计算,放一张图看效果。

反射效果

可以看到,蓝色球上面反射了黄色球,黄色球上面反射了蓝色球,因为反射次数有限,所以不会无限反射下去。

2.下一步

光是球没什么意思,下一步加上平面看看效果。

3.源码

release里面0.03版本

发布了64 篇原创文章 · 获赞 16 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/ARTELE/article/details/103721733
今日推荐