计算机图形学 期末课设-青花瓷坛的实体模型
TIT 计算机图形学 期末课设-青花瓷坛的实体模型
前言
- 实验中用到了很多知识点,这里只讲解其中的一部分,仅供参考.详细讲解可以看孔老师的视频课,具体学习程序中的类
- 参考视频计算机图形学全套算法讲解和C++编码实现(共23讲配套源码),计算机图形学案例视频讲解以及主页相关算法。孔老师是我的代课老师,孔教授有十多年教学经验,视频课很不错,所有的源程序都基于他写的函数,并非小张写的。所有源程序都基于C+编译
- 参考教材《计算机图形学-理论与实践项目化教程》 孔令德著,大家多多支持哇
- 实验源码很多,没有传CSDN因为小张认为源码并不是我开的,只是拿老师的程序做了一些东西,拿这个赚积分和马内未免有点!这里直接放了期末课设青花瓷坛源程序,不方便访问Github的可以评论邮箱。孔老师的视频课讲的很清楚,大家去B站就可以看啦!
- 第四章贝塞尔曲线和回转体画出线框图 P106(两个人)丁兆国 刘元华
- 第五章使用projection类投影 P94,第三章图形的几何变换 transform类 P37(两个人)周立波
- 第五章消隐(ZBuffer) P94 刘元华
- 第七章材质(Material)、光照(Lighting、LightSource) P139(材质少,光照内容多,两个人合作一下)俞文巧 雷康哲
- 第八章球体映射纹理 P171(一个人)张帆
一、项目描述
使用双三次贝塞尔曲线绘制青花瓷坛的线框模型,通过增加光照、材质、纹理,实现线框模型变为实体模型,达到模拟三维青花瓷坛的效果

二、项目设计
1.原理
映射原理:双三次Bezier曲面的各处都具有了(u,v)值。将纹理uv与曲面uv同时规范化到[0,1]区间内,当查找到曲面纹理时,先将曲面uv放大到和纹理位图一样大小的尺寸,然后获取对应纹理图像上的颜色作为曲面上该点的漫反射率系数
2.背面剔除算法原理:
视矢量与小平面法矢量的点积大于等于零(n·v>=0),cosα>0,表面可见
1.使用四边形网格的顶点计算面矢量并归一化
2.使用四边形网格的第一顶点与视点,计算矢量并归一化
3.计算法矢量与视矢量的点积,如果其值大于等于零,则绘制该网格,否则剔除该网格
3.球体图像纹理映射原理
3.1读入位图
纹理来自于位图,将位图作为资源导入,位图由DIB格式自动转换为DDB格式,每行存储4个字节的颜色数据,将位图转储到一维颜色数组中,就可以根据曲面网格点与位图去查询位图像素点的颜色,并将其作为材质的漫反射率和环境反射率,从而实现了将位图绑定到物体表面上
4.算法步骤
1.将图像纹理加载到资源标签页中,将位图数据保存到一维数组中
2.定义revolution回转类,读入顶点表和表面表,圆环面全部细分为四边形网格
3.将位图绑定到回转体的顶点上
4.根据光源的位置,数量,视点的位置,材质属性,构造三维光照场景
5.使用画家算法,剔除回转体的不可见网格
6.使用三维透视投影算法,将回转体三维多边形投影为屏幕三维四边形
7.根据网格点的法矢量,插值计算小面内每一点的法矢量,将纹理作为该点的材质,调用光照模型计算小面内该点的光强
8.使用定时器改变圆环的转角生成旋转动画
2.相关算法
PhongShader算法:对顶点的法矢量进行插值,得到小面内每一点的法矢量。对小面内的每一点都调用光照模型计算光强。计算光强需要四个参数,视点位置、当前点三维坐标、当前点法矢量、当前点的材质属性。如果当前点的材质的漫反射率取自一幅图像的相应点,这就为该物体添加了纹理。
向量线性插值计算:
v(t)=(tEnd-t)/(tEnd-tStart)*vStart+(t-tStart)/(tEnd-tStart)*vEnd;
t表示第一个向量的x(y)方向单位向量,tStart表示第一个点的x(y)方向单位向量,tEnd表示第二个点的x(y)方向单位向量,vStart起点的法向量,vEnd表示第二个点的法向量。
计算光强公式:
I=Ie +Id+Is =kaIa+f(d)[KdIpmax(N·L,0)+ksIpmax(N·H)^n^]
计算物体表面上任意一点P的光强I时,必须确定物体表面的单位矢量L、单位中分矢量H、单位法矢量N以及材质的漫反射率kd。当光源位置和视点位置不变时,光矢量L和中分矢量H是一个定值。影响光强的只有漫反射率kd和单位法矢量N。
Zbuffer算法:通过使用处理深度缓冲器,若当前点的深度值小于缓冲器中的深度值,则说明当前点离视点近,使用SetPixelV函数绘制当前点,否则放弃当前点。
当前像素点的深度值:z(x,y)=-$\frac{Ax+By+D}{C}$,C≠0;
A,B,C代表法向量的坐标
3.模型
三、部分代码
1.导入位图,格式为bmp
2.Texture类
class CTexture |
3.在贝塞尔曲线类中绑定纹理对象
void CBezierPatch::Tessellation(CMesh Mesh)//细分曲面函数 |
22~27绑定纹理到四边形网格上,u、v数组是曲面四边形网格的顶点,quadrTu、quadrTv数组是相应纹理的顶点(没有计算四边形网格细分点的法向量,后续将使用球体的位置向量代替法向量)
4.ZBuffer
ZBuffer类中的PhongShader函数中,读取纹理位图的颜色数据,并将其设置为材质的漫反射率和环境反射率
//读入三角形每个顶点的坐标、点法向量和纹理坐标 |
class CZBuffer |
四、整体设计步骤
回转体模型主要分为四个回转体对象,十二个控制点,分别是revoBody1坛身主体1, revoBody2坛身主体2, revoBottom坛底,和revoLid坛盖

十二个控制点模拟四段三次贝塞尔曲线,每个回转体读入控制点(ReadCubicBezierControlPoint)分别调用回转类(CRevolution::DrawRevolutionSurface),DrawRevolutionSurface完成曲面绘制

在线框模型的基础上,添加了光照与材质以及纹理来实现将线框模型变为实体模型,这里是光照与材质
这里初始化光照,使用了一个光源

这里读入位图,为每个回转体设置纹理
这里使用的是球体图像纹理映射实现回转体的实体模型,将两张位图映射到四个对象上
CBezierPatch::Tessellation,这里是顶点的纹理绑定,一个回转体上贴四张图片
(往下滑看下PhongShader)调用ZBuffer算法进行填充
SetPoint读入三角形每个顶点的坐标、点法向量和纹理坐标
SortVertex对顶点排序
这里应用了PhongShader算法(ZBuffer类),法向量线性插值和纹理坐标线性插值算法,将纹理颜色作为材质的漫反射率和材质的环境反射率
LinearInterp纹理坐标线性插值计算,(LinearInterp)得到的当前点的归一化法向量(ptNormal),(LinearInterp) 通过对三角形跨度两端点的纹理坐标进行线性插值,得到当前点的纹理坐标
根据纹理地址使用使用GetTexture,定义纹理读取函数,使用纹理坐标读出纹素的颜色值
pMaterial->SetDiffuse(Texture.c);//纹理作为材质漫反射率 |

五、总结
通过本次课程设计,了解了微软是以从左上读入位图数据。而Ctexture类中从位图左下角开始读取,目的是为了保证位图正向绘制。
PhongShader算法中,利用了向量线性插值计算,通过对纹理坐标线性插值计算得到归一化法向量。通过对三角形跨度两端点的纹理坐标进行线性插值,得到当前点的纹理坐标。
Zbuffer算法中,利用了深度缓冲器,通过计算该点的深度值来判断是否绘制该像素点












