目录
一、引言 4
二、 具体工作 4
2.1 光照纹理知识学习和简单建模练习,初步理解项目需求 4
2.2 需求理解和整体设计 4
2.3 摄像机类的修改 5
2.4 修改着色器以判断是否切割 5
2.5 改成三棱柱并编写成完整的类 5
2.6 固定视角以便于切割 6
2.7 鼠标控制刀具移动 6
2.8 贝塞尔曲线需求细化以及后续计划 6
2.9 刀具贴图 6
2.10 修改正交投影 7
2.11 画贝塞尔曲线 7
2.12 粒子效果 7
2.13 画夹具 7
2.14 背景 7
2.15 需求变更后的贝塞尔曲线 8
2.16 粒子优化 8
2.17 imgui 8
2.18 写报告 8
三、 工作问题及解决方案 8
3.1 建模demo以及分界线bug 8
3.2 三棱柱的侧面绘图的问题 9
3.3 性能优化 11
3.4 切割面的光照问题 11
3.5 键盘的“click”操作 11
3.6 鼠标移动刀具切割 12
3.7 切割的深度限制 12
3.8 深度与厚度 12
3.9 固定管线画点 12
3.10 贝塞尔曲线 12
3.11 imgui的集成问题 12
四、 键鼠操作说明 12
4.1 摄像机 12
4.2 调出/隐藏floating menu 12
4.3 开始切割 13
4.4 重置Reset 13
五、 参考资料 13
六、 后记 13
七、 附件 13
附件1 13
附件2 16
一、引言
这是我们计算机图形学的考试大作业。
其所谓“大”,不但在于它的体量大,包含了我们这学期学到的所有知识——基本绘图,着色器,三维建模,曲线绘制,光照,纹理,坐标变换等等;还在于它的开发流程长——从开始做大作业,到开始写这篇报告已经经历了近一个月的时间,期间还夹杂了其他学科大作业以及考试等等杂项,我也和助教进行了多次大大小小的交流。在这漫长的开发过程中,随着大作业的逐渐完善,我学到的知识也逐渐丰富了起来。
本次报告站在项目的终点往回看,以望尽力全面地展示大作业开发过程中的思路和灵感。
二、具体工作
2.1 光照纹理知识学习和简单建模练习,初步理解项目需求
前两次的平时作业都没有涉及到光照以及纹理,而且我开始做大作业的时候,图形学课还没有讲到光照计算,所以我又回到了OpenGL的教程官网[1]去学习光照和纹理相关内容。随着教程的引导,我自己上手建了一个简单的demo,了解了环境光,漫反射,镜面反射三种光的计算及组合,以及设计了平行光和几个点光源。然后还找到了自己满意的纹理图片,尝试了给模型贴图,同时,对于核心的光照变化问题,心里面有了一个解决办法的雏形——对不同的部分采用不同的纹理——用ps把两张图P到一张,然后通过修改纹理坐标去实现不同的效果。
同时,看遍了整个教程,我并没有发现能够满足我们的需求的建模教程——那些模型看起来高大上,但是都是固定的,无法交互修改。于是我意识到了一个问题,我们的建模或许不能够是像第一次作业的茶壶一样,导入固定的模型,而是要自己去画,手动建模才能够交互和修改。
于是我回去翻了翻三维建模的ppt,决定用旋转扫描的方法来建模——我们的车床本来自然就是一个旋转切削的工件,所以可以用一个很薄的小多边形面片,经过旋转得到初始的圆柱以及切削之后的模型。
此外还看了看教程网站上的2D游戏的例子,注意到了碰撞这个问题,可能和我们的刀具和工件的切削交互有关。
由于记忆中大一的车工的记忆已经有点浅了,为了理解刀具是如何切削移动的,我又去找了找车床相关的图片。想起来当初自己做过的倒三角等等切割操作,以及发现了刀具不止一种,可以有几种刀相互切换等等问题……
之后我用旋转扫描的方法建了一个demo,但是对于之后的刀具到底应该如何移动(要不要和现实一样?),如何切削交互(碰撞?倒三角?),贝塞尔曲线以及一些corner case等等问题,我有点难以抉择。要知道,早期的需求风险是很大的,如果理解出现了差错,那么不但可能会做很多返工,甚至会把原本简单的问题复杂化。于是,我整理了自己的想法和对于作业的疑问(见附件1),决定去请教一下助教。
2.2 需求理解和整体设计
首先,我的建模的思路是可以的,甚至可以适应那种切割速度不是无限快,能够展示出一圈圈的切割过程的样子。此外,助教还介绍了另一种思路,通过画无数个很薄的小圆柱来实现(圆柱的画法也是类似于画一个很多棱的棱柱),通过改变每个圆柱的半径来适应切割过程。虽然后者也有好处,不过我就采用了自己原本的想法罢了
此外,和助教交流后,清楚了几件事
1)刀具切割可以简化。
不会有我所谓的凹的情况,刀片上方的所有东西都被削掉
我可以限定bezier曲线在x方向是递增的。这样就不会出现所谓的凹的情况了。
2)把我的小面片从一个立方体改成三棱柱可能可以优化,因为重叠的部分由于深度相同,有一个机制是选择一个来展示,可能会冲突。
3)碰撞,不要做成碰撞,就是去改变点的高度。——维护一个数组,保留了点的高度。之后可能是根据bezier来算的。
4)关于改变面光滑与否的问题,可以加一个bool值去判断。或者我还有一种想法——在着色器里面去判断高度,然后改变bool,或者通过修改uniform——总之我希望的是,直接通过坐标是否小于一开始的情况来判断是否切割,而不需要其他的多余操作。
5)glut和glfw不兼容。所以我还是需要把所有点给出来,用一个统一的类去画。
然后理清思路,按照需求的优先级,主要分为几个部分——
1)建模:换成三棱柱,包装成完整的类
2)模型的变化交互
3)贝塞尔曲线
4)粒子化
其他的背景之类的都是次优先级的,可以放到之后再做。