学习光线追踪(13)---改进一下三角形碰撞光线的算法

0.简介

之前绘制了一面墙之后,发现墙的斜对角有缝隙,找到了原因后,更换了其算法。这里借鉴下面这篇博客中介绍的随后一种方法。

参考文章

具体原理就不在重复了。

1.修改

为了方便对比,我把原来的算法和新的算法都整理成了一个新的函数,这样编码也规则很多。

光线碰撞代码做了一些修改,将判断点在三角形内部换成了一个函数,而不是原来的一堆代码.

Ray Triangle::intersect(Ray ray)
{
	Ray result(ray.direction, ray.position, ray.intensity, ray.color, nullptr);
	if ((result = Plane::intersect(ray)).polygon == nullptr)
		return Ray(ray.direction, ray.position, ray.intensity, vec3(0, 0, 0), nullptr);
	//这里说明点在三角面是上
	if (onTriangle0(wA.position, wB.position, wC.position, result.end.position))
	{
		//计算点所在的纹理坐标
		vec5 p_end;
		result.end.textureUV = getUVCoord(A, B, C, result.end);
		return result;
	}
	return Ray(ray.direction, ray.position, ray.intensity, vec3(0, 0, 0), nullptr);
}

这个是新方法,我观察了一下,算法足够简练,这样就够了。

bool Triangle::onTriangle0(vec3 A, vec3 B, vec3 C, vec3 O)
{
	vec3 v0 = C - A;
	vec3 v1 = B - A;
	vec3 v2 = O - A;

	float dot00 = dot(v0, v0);
	float dot01 = dot(v0, v1);
	float dot02 = dot(v0, v2);
	float dot11 = dot(v1, v1);
	float dot12 = dot(v1, v2);

	float inverDeno = 1 / (dot00 * dot11 - dot01 * dot01);

	float u = (dot11 * dot02 - dot01 * dot12) * inverDeno;
	if (u < 0 || u > 1)
		return false;

	float v = (dot00 * dot12 - dot01 * dot02) * inverDeno;
	if (v < 0 || v > 1)
		return false;
	return u + v <= 1;
}

老方法也在这里贴一下,对比

bool Triangle::onTriangle1(vec3 A, vec3 B, vec3 C, vec3 O)
{
	vec3 a = A - O;
	vec3 b = B - O;
	vec3 c = C - O;
	//在三角形内部
	//double angle = (acos(dot(a, b))+ acos(dot(b, c))+ acos(dot(c, a)))* R_ANGLE;
	//if (fabs(angle-360.0)<0.1)
	//{
	//	return result;
	//}
	vec3 sa = normalize(cross(a, b));
	vec3 sb = normalize(cross(b, c));
	vec3 sc = normalize(cross(c, a));
	return dot(sa, sb) > 0.9999&& dot(sb, sc) > 0.9999&& dot(sc, sa) > 0.9999;
}

原来的方法应该是受到了点在平面上的精度问题,导致有些位置点实际是在平面上,但是由于计算精度问题,使得结果差一点,就不在平面上了,新方法是直接基于向量的计算,所有点都默认在平面上,不会受到是否在平面上的精度误差影响,也就是对于边界值来说也适用。在速度上,新算法与老算法在同一个场景两个三角形相比,快了100ms。

2.效果

新方法效果

对角线的缝隙已经没有了。

3.源码

release0.08

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

猜你喜欢

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