基于OpenGL与手绘系统的盆栽植物生成及其风动动画

  emmm,一不小心就半年没更了,最近翻到了本科毕设,挺有感触的,就拿出来写写。

Tip0: 代码写的时间过长,本文很少很少的细节地方与代码对不上,见谅。

Tip1: 要是拿了我的代码,留下个评论,点个赞可好。

程序源代码链接:https://pan.baidu.com/s/1hxCGDYFz0ubAEhPCj_3xuA 提取码:zv9o 

编译环境:Qt5.9.4

编译器:Desktop Qt5.9.4 MSVC2017 64bit

IDE:QtCreator

显卡:Nvida

一. 程序简介

    可对常见的单子叶类盆栽植物,如吊兰,君子兰等进行三维建模,利用手绘系统简单对单支枝叶的曲线造型做近似的模拟。同时建立简单的天气系统,创造盆栽在刮风,下雨天气下的形态变化动画。

    

图1 (a)吊兰
图1 (c)虎皮兰
图1 (b)君子兰
图2 (a)风动动画
图2 (b)雨天

二. 模块分解

 2.1 渲染

    渲染模块使用之前教程提供的技术,都是很基础的技术:

  1.  Blinn- Phong 光照模型
  2.  法线贴图 Normal Mapping 
  3.  阴影映射 shadow Mapping (使用GLSL 原生函数)

 2.2 枝叶建模

     使用在矩形网格上附加透明纹理的方式生成枝叶,如图3所示,通过依次弯曲小矩形的形式可以构造枝叶的弯曲造型。

图3 三角剖分化的矩形网格

    吊兰所用透明纹理与法线贴图如下所示,图4(c)为应用法线贴图之后的效果。

图4 (a)吊兰纹理
图4 (b)吊兰法线贴图
图4 (c)应用法线贴图

2.3 花盆建模

    用之前教程提过的,导入一个obj花盆模型

图5 花盆

2.4 手绘系统

  枝叶的弯曲主要由网格的弯曲实现,利用矩阵与网格坐标相乘,可以在局部坐标系种改变顶点的位置。如图6,使用矩阵Model0与v0,v1相乘,改变两个顶点位置。可以简单定义Model0是绕x轴正向旋转5度的旋转矩阵,则相乘后v0与v1两顶点的空间坐标同样绕x轴正向旋转5度。为保证网格弯曲的平滑性,Model1与Model2等其余旋转矩阵可由上一个矩阵迭代生成。如在Model0矩阵的基础上,再绕x轴旋转5度,生成Model1矩阵。

图6 迭代矩阵与坐标相乘

    手绘系统基于此思想,通过绘出的轮廓线条,计算所需迭代旋转矩阵数组中所有矩阵的旋转角度。为生成的枝叶弯曲的更加平滑,使用六次贝塞尔曲线对手绘线条进行曲线拟合,贝塞尔曲线控制点从手绘的线条种按点的密集程度进行筛选。如图7,黑色为手绘线条,红色为六次贝塞尔曲线控制点,蓝色为拟合后的曲线。将蓝色曲线均分为30个点,通过这些点计算旋转矩阵所需的角度,使用相邻两点在x与y坐标上的差值计算角的大小,则为一个旋转角度,图7 (b)为应用旋转矩阵之后的弯曲网格造型。

图7 (a)贝塞尔曲线拟合
图7 (b)弯曲网格

   简单绘制两线条,生成枝叶模型如下图所示。

   Tip2: 这里在应用法线贴图时有一个错误,因为法线贴图里的法线针对的是平面不弯曲网格。这里我将网格弯曲后,原则上应对法线贴图的相应部分做同样的弯曲,我当初试了几次,应该算错了,一直没改。

图8 手绘枝叶

2.5 其余功能

  2.5.1 均匀分配枝叶

    我每使用鼠标左键,以根部为起始方向,向左或向右绘出一条线条,在场景的YOZ平面,会进行相同方向的建模。如图9(b)所示。在绘出所有枝叶后,点击“移动”按钮,会将枝叶平均分配到花盆的四周,原理很简单,用360度除以枝叶的数量,得到枝叶的平均旋转角度,在此基础上,增加一些随机角度,则得到每枝枝叶的最终旋转角度。

图9 (a)手绘系统与场景的联系 
图9 (b)枝叶平行于一个平面
图9 (c)枝叶分配到四周

 2.5.2 增添枝叶

    如果要设计一盆有几百枝枝叶的盆栽,将其全画出来,是一件很愚蠢的事,手动狗头。

    

   如图10,简单画6个线条,设置“增补数量“为24,点击“计算”,则枝叶数量会扩充至24枝。原理是记录手绘线条的每组贝塞尔控制点,在这些控制点的坐标参数上增添微小随机量,得到一组新的控制点,生成新的贝塞尔曲线,从而得到一条新的枝叶模型。

图10 (a)简单绘图
图10 (b)扩充枝条
图10 (c)移动枝条


  2.6 天气系统

    Tip3: 天气系统,当初写这个就是个噱头,忽悠老师的,没用物理参数,较真的哥们可以跳过。

    天气系统分为两个,风动与下雨。下雨很简单,粒子系统做雨滴就完事了,没有参考价值

    风动是在做“平均分配枝叶位置”那得到的灵感,在移动的基础上,再增加一个绕x轴旋转的角度,将这个角度做成连续的,则动画就做出来了。这里我用组成贝塞尔曲线的30个绿色小点,点点之间在y值之上的差值,作为变换角度的参考。制作30个角度,作为动画演示之用。

图11 (a)风动
图11 (b)下雨

猜你喜欢

转载自blog.csdn.net/z136411501/article/details/90676440