使用MFC实现真实感图形绘制(4)

2018-12-04 16:31

I?Iaka?i?1?MfiIli(kdcos?i?kscosn?i)

其中,M表示对场景有贡献的点光源的总个数,ks为景物表面的镜面反射率,kd为景物表面的漫反射率,其它以i为下标的各参数项的意义与前面所述相同。?为光源入射角,?为视线与镜面反射方向的夹角。

在实际计算中,如果求出了景物表面各可见点处的单位法向量N、单位入射光线方向向量Li、单位视线向量V和Li的单位镜面反射向量Ri,就可由

cos?i?(Li?N),cos?i?(V?Ri)和Phong光照模型公式计算每一可

见点处的光亮度。由于(V?Ri)计算不方便,常用(N?Hi)来代替它,其中Hi是将入射光反射到观察者方向的理想镜面的法向量,即以Hi为法向量的镜面恰好能将入射光Li反射至Vi处,显然Hi即为

Li?V的单位向量(如图9.6)。 2

这样,Phong光照模型成为下式:

MI?Iaka?i?1?fiIli[kd(N?Li)?ks(N?Hi)n]

9.2.5 Phong局部光照模型的实现

在CReality类中添加Phong成员函数来实现Phong局部光照模型,其实现代码如下:

//Phong光照模型

void CReality::Phong(CDC *pDC)

{

int no = 0;

//景物表面三颜色分量的泛光反射率 double kra,kga,kba;

//景物表面三颜色分量的漫反射率 double krd,kgd,kbd;

//景物表面的三颜色分量的镜面反射率 double krs,kgs,kbs; //镜面高光指数 int n;

//理想镜面法向量 double hxn,hyn,hzn;

double cosnl;//景物表面单位法向量与入射光单位向量间夹角的余弦值 double cosnh;//景物表面单位法向量与理想镜面法向量夹角的余弦值 double ird,igd,ibd;//景物表面三角面反射的三颜色光强度 //循环处理每一个三角面

for (int i=0;i

} if (ird<0) ird =0;if (ird>255) ird = 255; if (igd<0) igd =0;if (igd>255) igd = 255; if (ibd<0) ibd =0;if (ibd>255) ibd = 255; //计算三角面的投影 CPoint p[3]; p[0] = Projection(surface.p1); p[1] = Projection(surface.p2); p[2] = Projection(surface.p3); //绘制三角面 CPen pen(PS_SOLID,1,RGB((int)ird,(int)igd,(int)ibd)); CBrush brush(RGB((int)ird,(int)igd,(int)ibd)); pDC->SelectObject(&pen); pDC->SelectObject(&brush); pDC->Polygon(p,3); brush.DeleteObject(); pen.DeleteObject(); } }

在应用程序中添加一个新的菜单项“Phong局部光照模型”,在该菜单项的处理函数中输入如下代码:

void CRealityDemoView::OnPhong() {

// TODO: Add your command handler code here m_Reality.Clear();//清除原有的景物和光源

CObject3D* m_ball = new CObject3D();//构造新的景物 m_ball->CreateBall(300,500,300,200);//创建球体 Param param;//景物光照参数

param.kra = 0.5;param.kga = 0.5;param.kba = 0.5; param.krd = 0.8;param.kgd = 0.8;param.kbd = 0.8; param.krs = 0.3;param.kgs = 0.3;param.kbs = 0.3; param.n = 10;

m_ball->SetParam(param);

m_Reality.AddObject3D(m_ball);//添加景物

hxn,hyn,hzn);

cosnh = pow(cosnh,n);//计算cosnh的n次幂

//累加计算景物表面在多个光源照射下的三颜色分量光强度 ird = ird + light.f * (krd * light.irl * cosnl + krs * light.irl * cosnh);

igd = igd + light.f * (kgd * light.igl * cosnl + kgs * light.igl * cosnh);

ibd = ibd + light.f * (kbd * light.ibl * cosnl + kbs * light.ibl * cosnh);

LightParam light;//光源

light.c1 = 0.25;light.c2 = 0.01;light.c3 = 0.0001; light.m_distance = 30;

light.irl = 255;light.igl = 255;light.ibl = 255; light.xn = 0;light.yn = 0.5;light.zn = 0.5; m_Reality.AddLight(light);//添加光源

m_Reality.SetIA(100,100,100);//设置泛光强度 //使用Phong局部光照模型进行绘制 m_Reality.Phong(this->GetDC()); delete m_ball; }

运行应用程序,其绘制结果如图9.7所示,可以看到球体表面因为镜面反射所形成的高光区。

我们也可以在绘制的时候添加多个光源,修改菜单项处理函数,输入如下代码:

void CRealityDemoView::OnPhong() {

// TODO: Add your command handler code here m_Reality.Clear();//清除原有的景物和光源

CObject3D* m_ball = new CObject3D();//构造新的景物 m_ball->CreateBall(300,500,300,200);//创建球体 Param param;//景物光照参数

param.kra = 0.5;param.kga = 0.5;param.kba = 0.5; param.krd = 0.8;param.kgd = 0.8;param.kbd = 0.8; param.krs = 0.3;param.kgs = 0.3;param.kbs = 1; param.n = 10;

m_ball->SetParam(param);

m_Reality.AddObject3D(m_ball);//添加景物 LightParam light;//光源1

light.c1 = 0.25;light.c2 = 0.01;light.c3 = 0.0001; light.m_distance = 30;

light.irl = 0;light.igl = 0;light.ibl = 255; light.xn = 1;light.yn = 0.5;light.zn = 0.5; m_Reality.AddLight(light);//添加光源1 LightParam light1;//光源2

light1.c1 = 0.25;light1.c2 = 0.01;light1.c3 = 0.0001; light1.m_distance = 30;

light1.irl = 255;light1.igl = 255;light1.ibl = 255; light1.xn = -1;light1.yn = -0.5;light1.zn = 0.5; m_Reality.AddLight(light1);//添加光源2

m_Reality.SetIA(100,100,100);//设置泛光强度 //使用Phong局部光照模型进行绘制 m_Reality.Phong(this->GetDC()); delete m_ball; }

运行应用程序,结果如图9.8所示。


使用MFC实现真实感图形绘制(4).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:《楚门的世界》英文影评Review of THE TRUMAN SHOW

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: