本章内容
- 创建一个闭合的cube mesh
- 给cube添加带弧度平滑的边缘
- 定义法线
- 使用sub-meshes(子mesh)
- 创建一个常规shader
- 合并碰撞体
1.合成一个cube
上一章https://mp.csdn.net/postedit/89474068我们已经实现了一个平面mesh。一个cube由6个平面组成,我们可以由6个上一章实现的平面修改位置和方向后组成一个cube,这种方法看起来挺好,但是其实并不实用,虽然我们也可以过 Mesh.CombineMeshes
这个函数合并这6个mesh,但是我们最好还是一次性创建这个cube。
2.创建cube的顶点
一个cube中的顶点可以分为三类。角上的顶点(下图3),边上的顶点(下图2)以及面上的顶点(下图1)
具体每个种类多少其实就是算数学题,具体如何算的可以参考原文,最后计算定点数量代码如下
之后再计算每个顶点的位置,最后结果如下
3.添加三角形
具体实现方法类似之前的文章,但是涉及更多的数学知识,这里不细讲了,大体思路是先计算cube四周的四个面,之后计算上面(top)和下面(bottom)。最后效果如下
4.使边缘圆滑
基于之前的代码,重新创建一个类命名为RoundedCube,并添加一个Roundness变量用于控制圆滑程度
这回我们要自己计算法线。先定义法线数组
创建一个函数,用于计算法线以及使得顶点沿着法线位置变化形成弧度
计算法线的原理是依据roundness参数形成一个更小的cube,大cube和小cube之间顶点的向量差就是大cube上该点的法线。如下图所示:
通过roundness参数,来确定大cube上每个顶点对应的小cube位置
最终结果
5.拆分Mesh
如何计算UV使得其可以渲染纹理?我们可以将总的三角形列表拆分成多个子mesh(三角形列表),其之间共用一些相同的顶点,这也使得我们可以使用不同材质去渲染每一组子三角形列表。
创建三个子列表
计算每个三角形列表
不再是设置mesh.triangles
而是设置子mesh
如果只设置一个材质,那么会发现只有两个面会渲染(一组)
在mesh render中material array设置三个材质,会得到正确结果
6.渲染Gird
我们可以使用shader,在shader中指定如何计算使用一个纹理而代替在mesh中存储uv信息。
Unity中默认shader的代码如下:
因为我们mesh中没有uv信息,我们需要在shader中计算,所以我们在顶点着色器中计算uv信息,并将其传入到surface shader中
通过使用shader中的keyword,我们可以控制shader的渲染
根据所设置的keyword提供支持
根据所选keyword设置来进行uv计算
可以看出同一个shader通过设置keyword来提供三个material对应的效果
但是能看出来grid line没有和四边形完全对应上,更糟的是因为我们使用的是世界坐标系,当我们旋转和移动这个cube的时候效果会更奇怪。
我们需要使用的是在圆滑之前原始的cube中的顶点位置,因此我们通过将其存储在mesh中传入shader。因为我们这个例子中vertex color channel没有用,所以我们就用它来存储这个信息。
在shader中使用color channel存储的信息进行计算
7.添加碰撞体
添加一个碰撞体时候的样子
为平坦的部分添加box collider(共三个)
为圆滑边缘添加capsule collider(12个)
最后的效果
https://thumbs.gfycat.com/RingedCornyBlesbok-mobile.mp4