基本信息
源码名称:c++ 光线跟踪算法 实例源码
源码大小:54.36M
文件格式:.rar
开发语言:C/C++
更新时间:2017-12-13
   友情提示:(无需注册或充值,赞助后即可获取资源下载链接)

     嘿,亲!知识可是无价之宝呢,但咱这精心整理的资料也耗费了不少心血呀。小小地破费一下,绝对物超所值哦!如有下载和支付问题,请联系我们QQ(微信同号):813200300

本次赞助数额为: 2 元 
   源码介绍

c MFC算法实现光线跟踪算法,将光线从人眼的方向开始跟踪,直至光线消失


void CTestView::DrawObject(CDC* pDC)
{
	objects[0] = new CSphere(60,CP3(-150,-70,-100),pMaterial[2]);//获取球的半径,位置,材质
	objects[1] = new CSphere(40,CP3(0,-90,100),pMaterial[0]);//获取球的半径,位置,材质
	objects[2] = new CSphere(60,CP3(180,-60,-170),pMaterial[1]);//获取球的半径,位置,材质
	objects[3] = new CSphere(50,CP3(0,-10,-200),pMaterial[3]);//获取球的半径,位置,材质
	objects[4] = new CSphere(40,CP3(100,-60,-100),pMaterial[0]);//获取球的半径,位置,材质
    objects[5] = new CPlane(140,CP3(0.0,1.0,0.0),pMaterial[4],-350,350,-140,-140,-1600,300);//下面的墙
	
	nObjectCount = 6;

	for (int i = -Width/2; i< Width/2; i  )//遍历背景
	{
		for (int j = -Height/2; j< Height/2; j  )
		{
			is_pppp = true;
			CVector EyeToScreenP(projection.ViewPoint,CP3(i,j,-200)); //从屏幕到 某一视点  像素中心得 矢量	
			CRay ray(projection.ViewPoint,EyeToScreenP); //光线的 起点, 方向矢量
			ray.alpha = -1;
			ray.Normalized();  //单位化该矢量

			CRGB color = Trace(ray,3);   //发出这条矢量		

			CP2 p = projection.PerspectiveProjection(ppppp);//透视投影
			color.Normalize();
			pDC->SetPixelV(Round(p.x),Round(p.y),RGB(color.red,color.green,color.blue));
		}
	}
}
CRGB CTestView::Trace(CRay ray, int count) // 从视点 发出的 第一条 矢量  、 递归次数
{
	CRGB ret(0.0,0.0,0.0); //初始 颜色 、黑色
	if(!count)//递归次数为3
	{
		return ret;
	}
	CInterPoint min_hit; 
	for (int i = 0; i<nObjectCount; i  )// 循环所有物体,找到 最先与此条光线相交 的一点
	{
		CInterPoint hit;
		if (objects[i]->GetInterPoint(ray,hit) && hit.t > 0.00001 &&hit.t < min_hit.t)
		{
			min_hit = hit; //找到最近的交点保存
		}
	}

	if (min_hit.t == 100000)  //没有找到
	{
		return ret;
	}
	else
	{
		if (is_pppp)//保存每一次刚开始的交点坐标,让其透视投影
		{
			ppppp = min_hit.IntersectionPoint;
		}
		is_pppp = FALSE;
		return Shade(ray, min_hit, count);  //找到了光线与物体的第一个交点min_hit
	}
}
CRGB CTestView::Shade(CRay ray, CInterPoint  hit, int count)//此条光线矢量  交点 递归次数
{
	CRGB ret(0.0,0.0,0.0);
	CP3 point = hit.IntersectionPoint;  //光线与物体的交点
	for (int i = 0; i < nLightCount; i  )
	{
		CRay shadow_ray(point, CVector(point,pLight->Light[i].L_Position)); //交点到 光源的 光线
		shadow_ray.Normalized();//方向单位化
	                                             
		CInterPoint min_hit;
		for (int j = 0; j<nObjectCount; j  )//判断在 交点和 光源之间是否有物体阻挡
			{
				CInterPoint hit1;
				if (objects[j]->GetInterPoint(shadow_ray, hit1) && hit1.t > 0.00001 && hit1.t < min_hit.t)
				{
					min_hit = hit1;	

				}
			}
		//交点与光源的距离
		double dist = sqrt(pow(pLight->Light[i].L_Position.x-point.x,2)  
			pow(pLight->Light[i].L_Position.y-point.y,2)  
			pow(pLight->Light[i].L_Position.z-point.z,2) );


		if (min_hit.t >= dist)
		{
			ret = pLight->Lighting(ray.origin ,point, hit.Nformal,&hit.pMaterial, i);	
		}
		else
		{
			ret = CRGB(0.2,0.2,0.2);
		}
		
	}

///////////	
	////加入递归
	CRGB TotalRGB ;
	CRGB s = Trace(CalculateReflection(ray, hit), count - 1); //反射

	TotalRGB = 0.6 * s   0.7 * ret ;
//	TotalRGB = ret;
	return TotalRGB;
}     

CRay CTestView::CalculateReflection(CRay in, CInterPoint hit) //已知入射光线 和交点 求反射 光线
{
	CRay ret;
	CVector VL(-in.dir.x, -in.dir.y, -in.dir.z);//单位化之后的入射光线矢量
	CVector VN(hit.Nformal.x, hit.Nformal.y, hit.Nformal.z);//交点法向量矢量
	VN = VN.Normalize();//单位化
	CVector R = 2.0 * VN * fabs(DotProduct(VN, VL)) - VL;

	ret.dir.x = R.x;
	ret.dir.y = R.y;
	ret.dir.z = R.z;//新光线的方向矢量
	ret.origin = hit.IntersectionPoint;//新光线的起始点
	ret.Normalized();

	return ret;
}