【CG物理模拟系列】粒子法--表面生成手法(下)

来源:互联网 发布:微信炸群软件免费 编辑:程序博客网 时间:2024/04/28 01:41

这一篇来说说 网格生成方法 中的 Screen Space Mesh 法。

Screen Space Mesh 

一般情况下,从隐函数曲面中提取出记载着表面数据的三角形网格面(mesh)时,我们常用像Marching Cubes这样的方法,把3D空间划分成数个3D网格单元(grid),然后在每个单元内生成mesh。与之不同,Screen Space Meshes(SSM)[1]则是一种在2D屏幕空间中生成mesh的方法。

SSM的处理对象是从粒子中生成的隐函数闭曲面。当我们用三角形mesh来表示物体的形状时,人眼看不到的面是没有绘制必要的,我们常用的OpenGL等3D API图像绘制中一般都会实现这样的隐面消除功能。SSM法也与之类似,由于没有必要绘制隐面,这个方法先从3D空间的粒子投影到2D屏幕空间后生成的深度图中,生成2D的mesh,然后再对进行逆投影处理,只生成从视点能看到的那部分由三角形构成的mesh。另外,通过给深度图添加平滑过滤器,可以得到类似元球技术(Metaball)这样的渲染。

3D Marching Cubes的计算量与各轴的分割数n的三次成比例,而由于SSM是在2D空间中生成mesh的手法,计算量只和n的2次相关。


输入

SSM的处理对象是粒子数据,输入数据可分为粒子的坐标和投影变换矩阵两部分,表示如下。

  • 粒子坐标 : ssm.eq1.gif
  • 投影变换矩阵 : ssm.eq2.gif

固定参数如下所示:

  • 屏幕间隔 : ssm.eq3.gif
    屏幕空间的grid大小。
  • 粒子半径 : ssm.eq4.gif
    屏幕空间中的粒子半径。
  • 平滑化系数 : ssm.eq5.gif
    深度图平滑化的过滤器大小和轮廓平滑化的迭代次数。
  • 深度阈值 : ssm.eq6.gif
    深度值的网格化阈值。比这个阈值大的深度值所在的grid才进行mesh化处理。

处理步骤

深度图表示为:

ssm.eq7.gif

各grid的深度值则用ssm.eq8.gif表示。grid分割数,是由屏幕间距ssm.eq9.gif和屏幕大小(ssm.eq10.gif)按照如下方式计算。

ssm.eq11.gif
screen_space.jpg深度图

下面对从ssm.eq12.gif中生成屏幕空间mesh的方法进行叙述。


生成深度图

首先,ssm.eq8.gif的初始值设为ssm.eq13.gif。之后对所有粒子的中心坐标,半径实施投影变换。首先,将中心坐标乘以投影变化矩阵,得:

ssm.eq14.gif

然后,将其变换成[-1, 1]的正规化坐标系。

ssm.eq16.gif

由于网格面(mesh)的生成要ssm.eq17.gif为基础,这里不对其进行正规化处理。随后,半径处理也用上述方法,

ssm.eq18.gif

这里的ssm.eq19.gif是投影变换矩阵中的各项元素。 ssm.eq20.gif是所有粒子的通用项,可以提前计算好。

使用粒子的中心坐标和半径对深度值进行更新。

ssm.eq21.gif

这里,

ssm.eq22.gif

另外,ssm.eq23.gif是满足下式范围内的单元。

ssm.eq24.gif

这里,ssm.eq25.gif

这样的话便可以从所有的粒子中生成深度图了。


深度图的平滑化

我们把用户设定的过滤器幅度ssm.eq26.gif乘以Binomial过滤器,来进行深度图的平滑化处理(ssm.eq27.gif时,使用深度值中心前后的三个深度值)。首先,把最初ssm.eq28.gif的所有深度值的x轴方向用1元过滤器进行过滤。然后同样方法处理y轴方向。同时,过滤器只应用于与中心深度值之间的差小于ssm.eq29.gif的深度值。


轮廓节点检测

这一节介绍mesh外侧轮廓上的节点检测。这里所说的节点是指网格边(grid edge,轮廓边)上的点。这里的grid是根据Marching Squares法生成mesh所用的grid,用之前深度图用的grid不同。但是,简单起见,下面把这两者的grid分辨率当作一种进行说明。

通过比较相邻grid的深度值,可以判断出边是否与轮廓相交,然而如果仅把深度值有限和无限的边界当作轮廓的话,像下图这样,本来不相连的部分便会自动连接(图中蓝线)。为了生成红线这样的mesh,我们使用深度阈值ssm.eq29.gif来进行轮廓节点检测。

ssm_silhouette.jpg轮廓上的mesh

与深度图生成的时候类似,首先扫描各粒子所在的grid边缘,然后使用圆与线段的交叉判断,计算与粒子边界相交的边和节点,以及节点的深度值ssm.eq17.gif。得到的边缘为轮廓边缘的条件如下。

  • 边缘端点的深度值间的差比ssm.eq29.gif大,此时,轮廓边缘内存在一个轮廓节点。

另外,满足

  • ssm.eq30.gif 平均边缘深度值(下图左)
  • 边缘中已经储存有轮廓节点的情况下,ssm.eq31.gif存储轮廓节点的深度值(下图右)

的节点,也被当作轮廓节点存储在边界中。轮廓节点所在的轮廓边缘的两个端点深度值将在之后用到。

ssm_silhouette_a.jpgssm_silhouette_b.jpg轮廓节点的选择(两个同心圆的点是轮廓节点)

mesh顶点生成

顶点生成可以分为下面三种情况。

  • 不为ssm.eq13.gif的grid节点:1个mesh内部顶点
  • 两端点的深度值分别为ssm.eq13.gifssm.eq32.gif的轮廓边缘上的轮廓节点:1个mesh轮廓顶点-外部轮廓 
  • 两端点的深度值都ssm.eq32.gif的轮廓边缘上的轮廓节点:2个mesh轮廓顶点(front vertex 和 back vertex) - 内部轮廓

front vertex的坐标,深度值与轮廓边缘储存的轮廓节点相同。 back vertex的坐标与对应的front vertex相同,深度值可以根据相邻grid节点的深度值的外推求出(如下图)。

ssm_front_and_back_vertex.jpgfront vertex 和 back vertex

三角形mesh生成

参照下图。三角形间的间隙表示有轮廓顶点的位置。另外,外部轮廓中,排除含有深度值为ssm.eq13.gif的顶点所在的三角形。图7,11,13,14的样例中,粒子被分成了3层,所以额外需要一个back vertex储存,而图15则被分为了4曾,所以要追加额外的2个back vertex储存。

ssm_mesh.jpg三角形mesh样例(1)


轮廓平滑化

轮滑的平滑化处理,是通过把各轮廓顶点坐标替换成相邻顶点与原来坐标值的平均值来实现。但是,mesh生成样例0的情况下,顶点不变。

3D空间的逆投影 

也就是把屏幕空间内的2Dmesh反推到3D空间的运算。对于各mesh进行如下处理。 

ssm.eq33.gif

这里的 ssm.eq34.gif

ssm.eq35.gif

运行结果

在立方体形状中随机生成粒子,通过SSM生成的mesh结果如下。

ssm_dmap.jpg

左侧是mesh生成结果,右侧是其深度图。屏幕大小为 640x640 ,深度图的grid间隔h=8。过滤器大小为3,粒子数5000。

深度图上的mesh绘制如下。

ssm.jpg

侧面看的结果如下。

ssm2.jpg

深度图清晰度100x100左右的时候,可以在CPU上实时运行,运行时间与GPU相差无几。 当清晰度为300x300时,CPU版运行速度约0.15sec/frame,GPU版约0.05sec/frame(Core i7 2.93GHz, GeForce GTX580)。


[1] M. Muller, S. Schirm and S. Duthaler, Screen space meshes, Proc. SCA2007, pp.9-15, 2007.
1 0
原创粉丝点击