Phi*_*sen 7 3d mesh unity-game-engine
鉴于Unity和C#中的网格(它本身是通过合并更简单的基础网格实时创建的),我们怎么能在运行时将它变成一个平滑的,几乎像布料网格版本一样?不完全凸起的版本,但更圆润,柔化锋利的边缘,桥接深的间隙等.理想情况下,当"平滑角度"法线设置应用于导入的对象时,曲面也会如此.谢谢!
*网格设置由人员及其具体事先预知.它的所有基本形状部分(在我们合并它们之前)都是已知的.如果有助于解决方案的话,基础部件也可以保持未合并状态,如果有一个运行时解决方案可以快速应用包装器mash,即使基本部件随时间改变其变换,但是静态一次性转换,这将是非常好的也会很棒.
(一些相关的关键字可能是:行进立方体算法和元球,骨骼上方的皮肤,网格过滤器转换,平滑着色器,软化,顶点细分.)
有很多方法可以获得类似的东西,所以你可以选择你喜欢的方法:
行进立方体
这个算法很容易使用,但结果总是继承它的块状"风格".如果这是你想要的外观然后使用它.如果你需要更平滑和/或像素完美的东西,那么寻找其他方法.
Ray Marching和有符号距离函数
这是非常有趣的技术,可以给你很多控制.您可以使用简单的立方体/圆柱体/等代表您的基础部件.方程式并将它们与简单的数学混合在一起
在这里你可以看到一些例子:http: //iquilezles.org/www/articles/distfunctions/distfunctions.htm
这里最好的是它设置非常简单,你甚至不需要合并你的基础部分,你只需将数据推送到渲染器.更糟糕的是,它可能在渲染部分时难以计算.
旧学校网格修改
在这里你有最多的选择,但它也是最复杂的.您从基本部件开始,这些部件本身没有太多数据,因此您可能应该使用CSG Union操作将它们连接到一个网格中.
拥有此网格,您可以计算基元的邻居数据:
等等
有了这些数据,您可以执行以下操作:
等等...
实际上有很多细节可能对您有用,您只需要测试一些细节,看看哪一个给出了首选结果.
我要从一件简单的事情开始:
使用这种方式,您还有两个不同的阶段:计算和渲染,因此使用动画执行此操作可能会变得太慢,但只是渲染网格将比Ray Marching方法更快.
希望这可以帮助.
编辑:
不幸的是我从来没有这样的需要,所以我没有任何示例代码,但在这里你有一些伪代码可以帮助你:
你有你的网格:
Mesh mesh;
Run Code Online (Sandbox Code Playgroud)
顶点邻居数组:
对于任何顶点索引N,triNeighbors[N]将存储由边连接的其他顶点的索引
List<HashSet<int>> triNeighbors = new List<HashSet<int>>();
int[] meshTriangles = mesh.triangles;
// iterate vert indices per triangle and store neighbors
for( int i = 0; i < meshTriangles.Length; i += 3 ) {
// three indices making a triangle
int v0 = meshTriangles[i];
int v1 = meshTriangles[i+1];
int v2 = meshTriangles[i+2];
int maxV = Mathf.Max( Mathf.Max( v0, v1 ), v2 );
while( triNeighbors.Count <= maxV )
triNeighbors.Add( new HashSet<int>() );
triNeighbors[v0].Add( v1 );
triNeighbors[v0].Add( v2 );
triNeighbors[v1].Add( v0 );
triNeighbors[v1].Add( v2 );
triNeighbors[v2].Add( v0 );
triNeighbors[v2].Add( v1 );
}
Run Code Online (Sandbox Code Playgroud)
现在,对于任何单个顶点,使用索引,N您可以计算其新的平均位置,如:
int counter = 0;
int N = 0;
Vector3 sum = Vector3.zero;
if( triNeighbors.Count > N && triNeighbors[N] != null )
{
foreach( int V in triNeighbors[N] ) {
sum += mesh.vertices[ V ];
counter++;
}
sum /= counter;
}
Run Code Online (Sandbox Code Playgroud)
这段代码中可能存在一些错误,我刚刚完成了但你应该明白这一点.