首先,让我抱怨“ greeble”是从字典中被淘汰的一个可怕的词。
好吧,从灵魂中去除石头,我们转向解释。 Greeble是添加到模型的细小重复细节,以使其具有规模感和某种美感。 得益于经典科幻电影,蘑菇已变得很流行,在电影中,物理雕塑常常是“模特”:
如果您已经从我的
拉伸教程中了解了如何拉伸程序网格,那么您将了解如何添加蘑菇。 将简单的
蘑菇添加到网格中可以通过将所有网格多边形
挤出为
任意长度来实现 。
但是,您可能已经注意到,上面的教程仅关注拉伸的三角形,而本文开头的图像是方形蘑菇。 我必须调整网格,以便将其划分为四边形,并且许多网格通常由具有三个以上索引的多边形组成。 因此,在本教程中,我们将学习如何
拉伸具有n个索引的多边形并将此算法应用于整个网格以创建蘑菇。 我们还学习了几种方法来改变蘑菇状算法,以获得不太统一的结果。
表面法线
首先,让我们找出如何计算具有任意n个索引的多边形的法线。 如果我们可以假定此多边形是
平面的 ,也就是说,它的所有顶点都在同一平面上,则此过程与计算具有三个索引的多边形的法线没有什么不同。
表面法线是垂直于多边形表面的方向,可以通过获取
沿多边形边缘指向的两个向量的
向量积来计算。
然后我们对该向量进行
归一化 ,使其长度为1,因为从法线到曲面,我们只需要方向而不是长度。
函数getFaceNormal(网格,多边形)
Vec3 v1 =网格:getVertex(多边形[1])
Vec3 v2 =网格:getVertex(多边形[2])
Vec3 v3 =网格:getVertex(多边形[3])
Vec3 e1 = v2-v1
Vec3 e2 = v3-v2
Vec3正常= e1:十字(e2)
返回正常值:normalize()
结束
如果我们不能自信地假定多边形是平面的,那么上面介绍的算法将首选前两个索引所在的平面。 为了更准确地表示多边形指向的方向,我们可以取
边的所有矢量积的
平均值 :
函数getFaceNormal(网格,多边形)
Vec3 n = Vec3(0,0,0)
对于我= 1,#poly -2做
Vec3 v1 =网格:getVertex(多边形[1])
Vec3 v2 =网格:getVertex(多边形[1+ i])
Vec3 v3 =网格:getVertex(多边形[2+ i])
n:加((v2-v1):十字(v3-v1))
结束
返回n:归一化()
结束
显示平面四边形拉伸的示例。挤压成型
现在我们有了关于表面法线的信息,可以在法线方向上拉伸多边形了。 简而言之,为了拉伸多边形,我们通过沿表面法线方向移动旧顶点来创建新顶点。
更多详细信息:
- 沿正常方向在旧峰“上方”创建新峰 。
可以如下计算新顶点:
(旧峰的位置)+(法线方向)
这会使旧位置沿表面法线方向“移动”。
例如,看上面的图像, v1在其上沿法线方向移动到v5。 - 创建四边形以连接新顶点和旧顶点。
应当注意,对于新多边形中的每个索引,都会创建一个新的四边形。
例如,看一下从v8,v7,v3和v4创建的四边形 。 - 用新顶点创建的新多边形替换旧多边形。 例如,看一下从v5,v6,v7和v8创建的四边形。
函数extrudePoly(网格,polyIndex,长度)
int [] poly = mesh.polys [polyIndex]
int [] newPoly = []
Vec3 n = getFaceNormal(网格,多边形)
-(1)创建拉伸顶点
对于j = 1,#poly do
局部p =网格:getVertex(多边形[j])
newPoly [#newPoly + 1] =#mesh.verts
-长度确定挤出的长度
网格:addVertex(p +(n *长度))
结束
-(2)带有四边形的线迹挤压侧面
对于j0 = 1,#poly做
本地j1 = j0%#poly + 1
网格:addQuad(
聚[j0],
聚[j1],
newPoly [j1],
newPoly [j0]
)
结束
-(3)将现有的面移至凸出的顶点
对于j = 1,#poly do
mesh.polys [pi] [j] = newPoly [j]
结束
结束
均匀采蘑菇。所有网状蘑菇
现在我们有了getSurfaceNormal()函数和extrude()函数,蘑菇化非常容易! 我们只需
将extrude()函数应用于每个网格多边形 。 我们使用
随机长度的挤出,以便每个挤出的多边形的尺寸略有不同,从而产生质感。 下面显示的算法应用于上面显示的多维数据集,该多维数据集完全由四边形组成。
功能greeble(mesh)
对于我= 1,#mesh.polys做
-这些随机值是任意的:p
浮点长度=随机:getUniformRange(0.1,1.0)
挤出多边形(网格,i,长度)
结束
返回网格
结束
恭喜,我们如雨后春笋般赚了。 但是我们可以做更多! 现在,如雨后春笋般非常均匀。 这是两个修改示例,使之更加有趣。
修改1:替代品的存在取决于偶然性
这非常简单:只需滚动模具以确定是否应将蘑菇形应用于每个多边形。 因此,蘑菇变得不太均匀。 下面显示的算法应用于上面的多维数据集。
对于我= 1,#mesh.polys做
<strong>如果是随机的:机会(0.33),则</ strong>
浮点长度=随机(0.1,1.0)
挤出多边形(网格,i,长度)
结束
结束
返回网格
结束
修改2:添加挤出比例
这需要更改挤出算法。 创建拉伸多边形的顶点时,可以
将它们朝多边形的中心减小随机数量,以使对象看起来更有趣。
首先,我们的extrude()函数必须接收一个附加参数,该参数确定新多边形的变窄量。 我们将其定义为称为
scale
Vec3。 为了将顶点移向中心,我们用
scale
的值
在顶点的
原始位置和
多边形中心之间进行
插值 。
(如果您需要了解用于查找多边形中心的算法,建议您快速跳转至
三角剖分教程,并阅读有关中点三角剖分(质心三角剖分)的信息。)
-找到多边形的中心
Vec3 c =网格:getFaceCentroid(poly)
对于j = 1,#poly do
局部p =网格:getVertex(多边形[j])
newPoly [#newPoly + 1] =#mesh.verts
自我:addVertex(
math.lerp(cx,px,scale.x)+ nx *长度,
math.lerp(cy,py,scale.y)+ ny *长度,
math.lerp(cz,pz,scale.z)+ nz *长度
)
网格:addVertex(p +(n *长度))
结束
现在,您可以通过按每个多边形缩放一个随机值,在蘑菇状算法中使用它。 这样我们就得到了上面显示的图像。
功能greeble(mesh)
对于我= 1,#mesh.polys做
浮点长度=随机:getUniformRange(0.1,1.0)
Vec3比例=(随机:getUniformRange(0.1,1.0),
随机:getUniformRange(0.1,1.0),
随机:getUniformRange(0.1,1.0))
拉伸多边形(网格,i,长度,比例)
结束
返回网格
结束
结束
太好了,我们到了尽头! 希望本教程对您有所帮助。