700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 计算机图形学期末大作业 虚拟场景搭建+层次建模移动

计算机图形学期末大作业 虚拟场景搭建+层次建模移动

时间:2019-03-11 20:44:43

相关推荐

计算机图形学期末大作业 虚拟场景搭建+层次建模移动

肝了两个星期,天空盒还是挺难实现的,还有各自奇奇怪怪的bug,以及层次建模需要的obj...

这个期末大作业主要是结合了以往的实验和参考了LearnOpenGl 和一些大佬的优秀作品:

计算机图形学 使用OpenGL的场景建模_opengl建模_晴夏。的博客-CSDN博客

南邮 | 计算机图形学大作业:Skybox + Shadow volume_Wonz的博客-CSDN博客

深大计算机图形学大作业之虚拟场景建模_AkagiSenpai的博客-CSDN博客

深圳大学计算机图形学期末大作业——OpenGL glfw库实现简单的Minecraft游戏_Anakin Skywalker RM 00的博客-CSDN博客(如要侵删联系)

演示视频:链接:/s/1mqT3yrhY31AeCXD-c81iUQ?pwd=1234

提取码:1234

具体实验内容和要求

参考实验2.3,实现物体的变换,允许用户通过键盘或者鼠标实现场景中至少两个物体的控制(移动,旋转,缩放等等)。

参考实验3.1,完成相机变换。

通过交互控制物体

参考实验3.3和实验3.4,实现光照效果、材质、阴影等。

用户交互实现视角切换完成对场景的任意角度浏览

参考实验4.1,为场景中至少两个主要物体添加纹理贴图 。

添加光照、材质、阴影效果

学生可以通过层级建模( 实验补充1和2)的方式建立多个虚拟物体,由多个虚拟物体组成一个虚拟场景,要求在程序中显示该虚拟场景,场景可以是室内或者室外场景;场景应包含地面。

添加纹理 方块/棋盘格的渲染和方块向下移动

虚拟场景:

立方体贴图-天空盒实现

(天空盒是参考:LearnOpenGL - Cubemaps)

首先讲一下天空盒的原理,立方体贴图是一种纹理,包含6个单独的2D纹理,每个纹理形成立方体的一侧:纹理立方体,假设我们有一个1x1x1单位立方体,方向向量的原点位于其中心。使用橙色方向向量从立方体贴图中采样纹理值看起来有点像这样:

因为立方体贴图包含6个纹理,每个面一个纹理,所以我们必须调用glTex图像2D六次,具体如下图展示:

归根结底可以理解天空盒就是一将一个立方体的 6 个面贴上对应的纹理,然后用这个立方体将相机包裹住,如果你将这六个面折叠成一个立方体,你会得到一个完全有纹理的立方体来模拟一个巨大的空间世界,示例图如下:

下面给出创建立方体贴图的具体实现函数loadCubemap(vector<std::string> faces):

然后我们将按照枚举的顺序在向量中加载适当的纹理路径: (下面是三种不同的贴图) 我们把天空盒作为立方体地图加载CubeMapTexture我们现在终于可以将它绑定到一个立方体上:

立方体顶点着色器

因为天盒是在立方体上绘制的,所以我们需要另一个VAO、VBO和一组新的顶点,用于纹理3D立方体的立方体贴图可以使用立方体局部位置作为其纹理坐标进行采样。当立方体以原点(0,0,0)为中心时,其每个位置向量也是来自原点的方向向量。这个方向向量正是我们在特定立方体位置获得相应纹理值所需要的。因此,我们只需要提供位置向量,而不需要纹理坐标,所以顶点着色器:

立方体贴图着色器

因为立方体贴图直接利用立方体的坐标作为方向向量进行纹理采样,而无需纹理坐标,于是我们的着色器发生了一些变换。我们最好利用一组新的着色器来管理这些特殊情况。我们创建 skybox 系列着色器。其中顶点着色器仍然负责完成 mvp 变换,值得注意的是,我们直接将变换后的坐标作为采样的方向向量,传递到片元着色器中:

除此之外,我们需要另外绘制出立方体的各个顶点:

然后再创建并编译shader,和调用天空盒所存储的VAO数据:

着色器的配置:

就像被一个真实的世界包围一样,随着鼠标的移动,视线也随着移动,最后效果如下:

然后为了实现更好的动态背景,简单意思就是让天空盒动起来,仿佛世界是在运动的,我在这里通过TIME和特定的转动角度,从而使天空盒看起来是在运动的;

代码实现原理是在渲染的同时,也让天空盒以不同的角度移动;

下面先提前构建了物体和地面来查看移动的差别:

可以看到在大概同样的位置,天空盒是在相对移动的

(前提是天空盒贴图纹理是那种纯天空的,否则效果看起来就像单纯把图片放大缩小一样)

层次建模

这是最常见的建模模型构图:

这里我构建了以下的模型大致框架:

大概代码实现参照了实验4.2机械臂和4.3机器人,如下面展示:

然后这里再参照实验3和实验4.3,构建了一个矩阵栈

接下来,使用TriMesh数组,对层级建模的每一个物体进行绑定,并且在此定义object准备绑定。

在init函数当中,对所有的层级建模物体进行初始化。

首先是定义Man中的TriMesh,对其进行初始化,然后进行对文件的读取,最后将文件与物体进行一个绑定。

在display函数中,是对物体进行拼接的地方,在此我写了一个drawMulMesh函数,将物体进行拼接。

首先渲染身体,这是机器人的中心部分。

首先,modelMatrix代表了这个身体物体的变换矩阵,可以通过这个改变ModelMatrix来改变身体部件。

接下来的body函数是在原本modelMatrix的基础上,对身体进行一个变换。然后将物体调用painter的drawMesh进行渲染。

再将本身身体的modelMatrix放入栈中,方便返回。然后对头部进行设计。

在此是设置头部与身体处的连接位置,也就是若要进行旋转,则在该位置进行旋转,并且通过rorate函数进行旋转。然后再到head函数当中,设置关节节点与物体的位置,使得完美的契合。

设置完毕头部后,因为头部下面没有任何的部位了,所以此时将modelMatrix恢复成身体的样式,再进行接下来操作。

接下来的操作与上述大体相同,当某个部位下方没有任何部位后,则将栈中的变换矩阵返回,再进行后续操作。这样子通过栈可以实现层级建模。最终效果如下:

嘎嘎因为不会建模,随便在网上搜刮了的obj,最后勉强a+

最终效果如下:

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。