关于蒙皮(vertex-skinning)的零散收集

      游戏开发 2009-12-26 13:52:00

汤锴(42350817)  13:49:53
关于最近计算蒙皮(vertex skinning)的一些经验:

1 蒙皮可以在CPU或GPU端计算,各有优缺点,具体采用哪种算法要看实际情况,可以参考: http://www.gamedev.net/community/forums/topic.asp?topic_id=452770

2 如果在GPU端计算蒙皮,就要受到unifrom register数量的限制,因此每次draw primitive时骨骼数量有严格限制,一般来说不超过16根。而一个模型几乎肯定会超过16根骨骼,所以必须对mesh分组,按16根骨骼分成一组。

3 如果在CPU端计算蒙皮,有几个东西需要考虑,首先必须针对memory和cache优化(可以看我等下发的聊天记录),使用多流,然后如果硬件有VFPU可以用SSE指令进行运算本身的优化

4 如果美术认为骨骼动画支持缩放很有必要,那么就必须计算matrix inverse transpose才可以正确变换normal和tangent(我等下发的聊天记录里也有这个)

5 变换position可以用vec3tranform就行了,不需要考虑w,因为没有projection;而matrix inverse transpose其实只需要matrix33,因为translation对于normal没有意义
汤锴(42350817)  13:51:07
汤锴 12:58:08
 http://www.gamedev.net/community/forums/topic.asp?topic_id=541273
汤锴 13:09:50
 http://www.lighthouse3d.com/opengl/glsl/index.php?normalmatrix

最后的结论:
So when can we be sure that M is orthogonal? When we limit our geometric operations to rotations and translations

也就是如果骨骼支持缩放,就必须计算MIT
但是我看到很多游戏都是直接拿M来变换法线,估计它们的骨骼动画都没有支持缩放?
lyk 13:15:05
意思是不是非单位正交变换法线后会不正确 
汤锴 13:15:36
对,好像最后推出来的scale是反的,但是rotation保持不变
汤锴 13:15:52
除非scale都是unit scale
lyk 13:16:11
顶点数据变换应该是对的? 
汤锴 13:17:13
其实就是用来变换position的matrix,如果只有旋转平移,就可以直接拿来变换normal,如果有非单位缩放,就必须计算mit才正确
汤锴 13:17:39
彭小雨那边说我们骨骼动画需要支持缩放,所以没办法
lyk 13:17:53
那我们可以拆开成(quaternion or matrix33, scale,translation) 
汤锴 13:18:03
那不是更费了。。。
lyk 13:18:11
不会啊 
汤锴 13:18:17
本来一次vec3transform就结束了
汤锴 13:18:30
现在还要多几步运算
lyk 13:19:04
scale三次乘,trans三次加,matrix33本来也要省点 
lyk 13:19:26
变化法线和切线的时候会省回来吧 
汤锴 13:20:42
哦,变换法线本来就可以用matrix33,我以前的代码写的不够高效

可以这样优化:
对于每一根骨骼,计算mit时,只需要matrix44inverse33 -> matrix33transpose

然后对于每一个定点的normal或tangent:vec3transformnormal use a mat3
汤锴 13:20:55
法线不需要translation
lyk 13:21:24
对啊,法线不需要scale,和translation 
汤锴 13:21:34
法线需要scale的
汤锴 13:21:58
但这个scale和position matrix的scale是反的
汤锴 13:22:30
也就说可以这样
mit = mat_rotation * mat_scaling_it

但总之要求一次it
lyk 13:23:08
法线scale有点怪喃,scale法线的模就不是1,这样有什么用吗? 
汤锴 13:23:23
 http://explodedbrain.livejournal.com/112906.html

这里最后有个解释
汤锴 13:23:42
当然最后要单位化回来的
汤锴 13:24:22
所以说如果x,y,z的scale都一样,对normal做scale就没有意义
汤锴 13:24:26
但是问题就是不一样
汤锴 13:24:32
比如一个怪物的手臂伸长
lyk 13:26:09
那你准备杂个做喃? 
汤锴 13:27:08
既然美术觉得骨骼动画缩放很有必要,那只好支持

原来的代码这样稍微优化一下:
matrix44inverse33 -> matrix33transpose -> vec3transformnormal use a mat3
汤锴 13:28:46
另外我给你发的第一个链接也解释了为什么自己计算normal或tangent会不一定正确,因为max的smoothing group不一定是采用的vertex在各个face的normal相加再平均的方法,而是可能更复杂
汤锴 13:29:40
这个时候还需要vertex-face map数据

而且美术也有可能手动调整normal,这时候用任何算法计算出来都和直接导出来的不一样
汤锴 13:31:31
然后那天SSE优化之后没有效果,还存在另外一种可能性:

我看到一篇文档提到,cpu skinning的时候,memory读写的开销可能会远大于计算本身,这个时候优化计算本身的代码可能就没有效果

它建议首先应该针对cache优化
lyk 13:31:58
关健还是导出时候法线有错,法线一错有时候都搞不懂是shader写错了还是美术错误,手动调法线这种不太好,法线使用只要和我们material需要的法线一致就行了 
lyk 13:32:43
对,骨骼太多我觉得对cache影响很大 
汤锴 13:33:08
对,法线导出有时候反掉确实是一个问题

那天我已经把那个导出object space下normal的插件上传了,如果继续用下来没有问题就可以解决法线反掉了
汤锴 13:33:30
之前那种导出成wavefront obj再导进来的方法确实很麻烦
汤锴 13:33:49
而且那样一导,materail信息都没有了。。。
lyk 13:34:11
DOOM3里面有个函数,TransformCoord(matrix44 mat, s3dVector3* vert, s3dVector3* out, s32 count );我觉得我们的顶点能这样发送进这个函数可能会有点提升 
lyk 13:34:50
澎晓雨那个记忆估计经常出错 
汤锴 13:35:33
呵呵,美术始终不能像程序那样思考问题

这次骨骼应该会减少不少,美术减面以后骨骼数量肯定也能减少
我看到DOOM3这一类游戏也就80左右的骨骼数
汤锴 13:35:41
主要我们是古装。。。
lyk 13:35:45
这个函数最后可以用汇编优化 
lyk 13:35:49
恩 
汤锴 13:35:53
TransformCoord(matrix44 mat, s3dVector3* vert, s3dVector3* out, s32 count );
汤锴 13:36:53
这个函数的意思是不是就是可以把position作为一个单独的数据流,一下变换很多个顶点的position,然后是normal,tangent...

而不是先变换一个顶点的positon,normal,tangent,然后再下一个顶点。。。
汤锴 13:37:13
要求一定要用多流吧
lyk 13:37:44
恩,主要是骨骼矩阵一直在cache里面,cache优化比较好一点 
lyk 13:37:46
恩 
汤锴 13:38:07
这个改动对于插件还有点大,不过我也觉得有意义
lyk 13:38:41
DOOM3是多流,我们也不一定就照都做,但优化cache的思路是对的 
汤锴 13:38:55
多流的话,不仅骨骼矩阵一直在cache里面,顶点数据也更连续,应该是会提高很多
汤锴 13:39:05
这个很有意义,我记下来
汤锴 13:39:36
对了,这个文档
汤锴 13:40:06
 http://realtimecollisiondetection.net/blog/?p=73
汤锴 13:40:14
我觉得很有意思,不知道你看了没有
lyk 13:40:36
没有,我显这个BLOG的图总是显不出来 
汤锴 13:40:48
没有图也可以看的,那个图没啥意义
汤锴 13:41:27
它总的意思就是用着色树,或者比如让美术用maya的材质系统自由发挥,最后不一定是好事
lyk 13:41:49
renderman 的shader tree确实太难了对于美术,有种类似的叫做 abstract shader tree我觉得还更有意义一些 
汤锴 13:42:00
因为美术不懂程序,出来的东西往往很不优化,产生的乱七八糟的shader很多
汤锴 13:42:13
exposing a programming language, whether graphical or not, to a nonprogrammer is rarely the right thing to do.

这句话我觉得很经典
汤锴 13:42:38
还有这个

Yes, programmer guy, this means that exposing LUA to your designers is bloody retarded on your behalf.
lyk 13:43:46
这个我还是觉得,unreal 3那天打开看了一下,连个乘法都要美术拖 
汤锴 13:44:05
我觉得我们现在的方法,对于我们的具体项目情况是最好的

首先我们项目没那么复杂,应该最后材质没有那么多

其次我们的美术显然不如那些欧美的美术强大
lyk 13:44:21
对美术要求太高了 
汤锴 13:44:26

汤锴 13:44:34
行,那我先走了,还没吃饭
lyk 13:44:43
好 


 

标签集:TAGS:
回复Comments() 点击Count()
喜欢就顶一下

回复Comments

{commentauthor}
{commentauthor}
{commenttime}
{commentnum}
{commentcontent}
作者:
{commentrecontent}