光栅化的实现

遍历三角形-对每个三角形逐像素遍历-直线和三角形求交判断点是不是在三角形内-着色

代码如下:

void rasterize(Image& image, const Scene& scene, const Camera& camera) {
	const int w = image.width();
	const int h = image.height();
	DepthBuffer depthBudder(w.h, INFINITY);
	for (unsigened int t = 0; t < scene.triangleArray.size(); i++) //遍历场景中的三角形数组
	{
		const Triangle& T = scene.triangleArray[t];
		const int x0 = 0;
		const int x1 = w;
		const int y0 = 0;
		const int y1 = h;
		//遍历像素
		for (int y = y0; y < y1; y++)
		{
			for (int x = x0; x < x1; x++)
			{
				const Ray& R = computeEyeRay(x, y, w, h, camera);  //计算穿过像素(x,y)中心的射线
				Radiance3 L_o;
				float distance = depthBuffer.get(x, y);//获得当前像素的深度
				if (sampleRayTriangle(scene, x, y, R, T, L_o, distance)) //一根光线对一个三角形进行求交和着色
				{
					image.set(x, y, L_O);
					depthBuffer.set(x, y, distance);
				}
			}
		}
	}
}


bool sampleRayTriangle(const Scene& scene, int x, int y, const Ray& R, const Triangle& T, Radiance3& radiance, float& distance)
{
	float weight[3];
	const float d = intersect(R, T, weight);//光线三角形求交
	if (d >= distacne) {
		return false;
	}
	distance = d;
	const Point3& p = R.origin() + R.direction() * d;
	const Vector3& n = (T.normal(0) * weight[0] +
		T.normal(1) * weight[1] +
		T.normal(2) * weight[2]).direction();
	const Vector3& w_o = -R.direction();

	shade(scene, T, P, n, w_o, radiance);

	return true;
}

float intersect(const Ray& R, const Triangle& T, float weight[3]) {  //求交
	const Vector3& e1 = T.vertex(1) - T.vertex(0); //V0到V1的边向量
	const Vector3& e2 = T.Vertex(2) - T.vertex(0); //V0到V2的边向量
	const Vector3& q = R.direction().cross(e2);  //向量q垂直于e2和光线
	const float a = e1.dot(q);
	const Vector3& s = R.origin() - T.vertex(0);  //光线起始点到V0的位移向量
	const Vector3& r = s.cross(e1); //s和e1的叉积

	weight[1] = s.dot(q) / a;
	weight[2] = R.direction().dot(r) / a;
	weight[0] = 1.0f - (weight[1] + weight[2]);

	const float dist = e2.dot(r) / a;
	static const float epsilon = le - 7f;
	static const float epsilon2 = le - 10;

	if ((a <= epsilon) || (weight[0] < -epsilon2) || (weight[1] < -epsilon2) || (weight < -epsilon2) || (dist <= 0.0f))
	{
		return INFINITY;
	}
	else
	{
		return dist;
	}
}

void shade(const Scene& scene, const Triangle& T, const Point3& P, const Vector3& n, const Vector3& w_o, Radiance3* L_o) {  //着色
	L_0 = Color3(0.0f, 0.0f, 0.0f);
	for (unsigned int i = 0; i < scene.lightArray.size(); ++i) {
		const Light& light = scene.lightArray[i];
		const Vector3& offset = light.position - P;
		const float distanceToLight = offset.length();
		const Vector3& w_i = offset / distanceToLight;

		if (visible(P, w_i, distanceToLight, scene)) {
			const Radiance3& L_i = light.power / (4 * PI * square(distanceToLight));
			L_o += L_i * T.bsdf().evaluateFiniteScatteringDensity(w_i, w_o) * max(0.0, dot(w_i, n));
		}
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值