Skip to content

2019 Fall semester Computer Graphics course final project.

Notifications You must be signed in to change notification settings

Gusabary/Shrine

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

47 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Shrine · 神庙

以开发的过程为时间线一点点讲起吧

Skybox 天空盒

在最一开始什么也没有的时候,首先想到的是弄个背景,第一反应肯定是天空盒,照着教程搞了一个上去,效果还行,唯一的缺点就是看上去 Camera 好像是悬空的一样。这是因为为了营造出玩家所处空间很大的假象,天空盒的一个重要特性就是不会随着 Camera 的移动而在观察空间移动,这种特性应用在前后左右以及上方五个方向没有什么问题,但是在下方这个方向就会出现悬空的效果,这不是我所期望的,后面会解决。

加入了天空盒的代码以后,main 函数立刻变得很臃肿,我寻思这才只是加了个背景代码就变得这么难看,于是抽象出去一个 Skybox 类,渲染循环里面只需要 skybox.draw() 就行了。

Eight-Diagram 八卦盘

一开始我是想用八卦盘做片头动画的,从远处旋转着飞过来然后消失在迷雾里,但是在这样的八卦盘上做 Bump mapping 有点麻烦就放弃了。

Camera 摄像机

这个项目 Camera 还是挺费力的,不仅需要像 fps 游戏那样,wsad 移动,鼠标调整视角。为了增强真实感,需要让 Camera 固定在地面这个平面上(所以下方这个方向必不可能用天空盒),还需要检测各种碰撞,不能让 Camera 跑进石头或是 buddha 里面等等。

由于需要实现手电筒的效果,所有模型的光源均来自摄像机。按下空格打开手电,再按一下关掉。

Temple 庙宇

既然项目名叫神庙,一座庙的模型必然是少不了的,在各大素材网站上兜兜转转、寻寻觅觅,看中了几个类似帕特农神庙那种样式的模型,但是无奈要么收费要么模型的格式 Assimp 支持不了,对于没有 Paypal 账户以及不会用其他模型导入库的我,只能稍稍降低标准,找到了一个还算可以的日式家居风格的模型,虽然乍一看上去和普通的日式阳台没什么两样,但是放一尊佛进去立马就变成神庙一样的存在了。

Book 书封

前面提到过,放弃用八卦盘做片头动画的想法后,只能用盗墓笔记的书封了。但是老师只提供了一张简单的纹理,要求却是要 Bump mapping,我寻思按照我的理解,Bump mapping 还需要有一张法向量贴图,无奈,只能自己做了。经过我一番仔细地观察,提供的这张纹理上的光照信息告诉我们,光源来自上方,那么纹理中白色的部分法向量就是偏向上方一点,黑色的部分就是法向量偏向下方一点。如果说 CV 这门课有什么用的话,它确确实实教会我一些图像处理的知识,我将原图中的灰色映射到法向量贴图中的薰衣草色(大概,rgb 值是 128,128, 256),这表示它们的法向量是径直朝外的,然后偏白的部分就把它们的 g 分量调高一些,表示法向量向上偏了一些;偏黑的部分就把它们的 g 分量调低一些,表示法向量向下偏一些,如此便能生成一张还算有用的法向量贴图了。

                           

应用到项目中,控制书封始终保持竖直,这张法向量贴图便能一直有效,然后让光源绕着书封做圆周运动,便能体现出书封的凹凸感。

书封向后运动,在这过程中,Camera 是不能动的,为了让玩家不至于丧失兴趣(因为这个片头动画的确很草率),控制书封移动速度越来越快,直至消失在迷雾中。

Fog 迷雾

在 shader 里设置一个按距离深灰色占比不断增大的混合,以营造出雾的效果。

Rock 岩石

找到一个还不错的岩石模型,因为神庙的模型有前后两个入口,正好可以放两块岩石在那里等着被炸。有一个细节是炸掉之前 Camera 是不能通过的,炸掉之后才可以。

爆炸后岩石碎掉的效果是通过几何着色器来完成的,在几何着色器中设置模型中每个面片在爆炸之后都沿着法向量移动,这样看上去就好像是岩石模型被炸碎了一样。但是由于几何着色器中对于整个面片的操作,导致手电筒的光打在上面的时候,边缘会呈现诡异的小三角,看着很刺眼,于是调小了手电筒的内圈,调大了手电筒的外圈,缓解了这个现象。

Ground 地面

前面说到必不可能用天空盒来做下方的背景,于是只能手动贴一个地面。地面是一个巨大的矩形,大到 Camera 按照设定的移动速度要走很久很久才会看到天空盒营造出的深渊,然后贴上天空盒六个纹理中地面的那张纹理,就和整个环境的风格一致了。但是还存在一个问题,就是虽然你几乎走不到地面的边缘,但是你还是能看到远处地面和天空盒明显的边界,我用了一个比较懒的方法就是把雾调得浓一些,这样就不明显了(

哦还有一点,一开始我是将纹理直接贴上去的,但是后来发现因为地面很大很大,只贴一张纹理会把其中的细节无限放大,这样这个纹理就会显得有点丑,于是采用 repeat 贴纹理的方法,在边处翻转,不仅能有效地控制纹理被放大的程度,而且也不会产生诡异的地面纹理跳变。

Buddha 佛像

关于佛像,我一开始尝试了导入老师提供的那个模型,Assimp 的确也能导入 PLY 格式的模型,但终归用着不顺手,还是换成了另一个 OBJ 格式的。导入的时候一开始那个纹理贴反了,导致整个佛像显得很奇怪,才发现是贴的时候忘记上下翻转了。

把佛像放置在庙中间,设置当门口的石头被炸碎且手电筒亮着的时候开始计时,在十秒的时间间隔中,佛像的材质会经历青铜到银再到金色的变化,亮度也会逐渐变亮,为了达到很亮很亮的效果,甚至光照参数都超过了 1.0,就离谱。

Bomb 炸弹

为了更好的避免很多问题,设置只有当站在石头附近的一块区域时,按 B 才会有炸弹飞过去,炸弹和岩石碰撞后会触发上面所说的几何着色器的操作。

炸弹是从 Camera 稍上方飞过去的,因为塞尔达里面林克就是举着扔炸弹的(

Audio 音效

加了几个音效让场景更加真实。首先是整个环境的 bgm,因为这个项目名 Shrine 就是来自塞尔达中神庙的英文,所以 bgm 情理之中选了塞尔达中神庙的 bgm,我很喜欢,因为每次打神庙意味着多一个勇者试练证。只有 bgm 是循环播放的,其他只播放一次。

然后是爆炸的音效,会在炸弹碰撞到岩石的时候播放。还有开关手电筒以及佛像吸收满光照变成纯金后的音效。

FrameBuffer 帧缓冲

由于加载时间过长,画面从纯白突然一下转移到场景中显得有些突兀。

联想到雾效果是一个与空间相关的混合,于是用帧缓冲的机制实现了一个苏醒的效果——与时间相关的混合。

p.s. 特别感谢这位学长的仓库,代码结构有拿来做参考

Last-modified date: 2020.1.17, 9 p.m.

About

2019 Fall semester Computer Graphics course final project.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published