Shader 学习笔记 20151105

Segment 0 回顾

  • Object-space normal map和tangent-space normal map区别。
    Object-space normal map里面的法线向量值是参考object坐标系搞出来的,而tangent space normal map里面的法线向量值是先在高模Obj对应的低模Obj上面每一个点建立一个坐标系,这个坐标系叫做tangent space(一般Z轴就是低模上这个点的法线,X,Y轴分别是uv坐标的方向),之后,把高摸上每一点的法线向量转换到这个tangent space里面,这样形成的一个map就是tangent space normal map。这样看来tangent space normal map里面每一个点本质上记录的其实是一个偏差,也就是该点处低模法线方向和高模法线方向之间的差别(请注意,这只是个比喻,方便理解而已,实际上记录的根本不是两个向量差,因为如果记录的是向量差,那么整个概念还是一样的,但是算法却差别很大了。真正的tangent space normal map是将高模的法线值存进低模的tangent坐标系当中,这样在拿tangent space normal map去蒙皮的时候,只需要在所需蒙皮的物体的每一个点的tangent space里面把原来的法线值删除,更换成tangent space normal map的值就好了)
    下图是obj-space normal map和tangent space normal map的实际样子。

    这里写图片描述


  • 明白了Obj-space normal map和tangent space normal map之后,总要知道为何搞了这两种吧,于是看了很多文章叙说Object space normal 和 tangent space 优缺点之类的,大家都说一些什么Obj的效率高、tangent的适用广。看得不甚了了,觉得都是结论,我自己总是没抓住实质,直到自己亲手用笔画了画才豁然开朗。

    请看下图
    这里写图片描述

    在这个图里面,我们有一个原始的球。从这个球上面当然能扒出一张法线贴图(这里为了简便,我默认这个球每个顶点的法线方向是正常的,也就是说垂直于每个顶点的),你可以扒一张Obj space normal map,也可以扒一张tangent space normal map,此时没啥影响。

    接下来我们要用这两张normal map去贴我其他项目里面的物体。

    如果,此时贴的还是一个球,那么Obj space normal map和 tangent space normal map都可以,不管我这个新的球是旋转过、平移过、缩放过(一般我们所谓的旋转、平移、缩放都是在world space做的。但是此处、对于这个球来说,我们讲的是在它自己的Obj space里面做旋转、平移、缩放),球被贴完图之后,看起来还是原来的样子,并没有什么区别。

    接下来,刺激的事情发生了,假设我把这个球做了变形(deform),变成了上图右侧的那种棍子状。那么这时候用Obj space normal map和tangent space normal map分别去贴这个棍子的时候,毫无疑问贴完之后会有不同。会有啥不同呢?为了方便,我们就默认Obj space的原点就是物体的质心吧,如果我们用Obj space normal map去贴棍子,这样棍子上面每一个点的法线值都会被替换成Obj space normal map上面对应点的法线值(举个例子,左上角那个点的法线方向指向左上方,贴到棍子上去之后,毫无疑问在棍子上面对应点的法线就被替换了,棍子上的法线就指向了左上方),贴完之后样子就是图里面的A;如果我们用tangent space normal map去贴,就会贴成B图。因为在用tangent space normal map贴的时候,我们是在棍子上面每一个点的tangent space里面贴的,而不是在棍子的Obj space里面贴的。还是拿左上角那个点举例,首先取得棍子上左上角那个点的tangent坐标系(很好取,Z轴 为棍子模型左上角这个点的模型法线法线,X,Y分别为uv方向),取完坐标系之后自然就能得知在这个点的tangent坐标系里面它的原始法线方向是(0,0,1),接下来就根据uv坐标去找tangent space normal map里面对应点的值,很容易就可看出此时tangent space normal map里面对应的值就是(0,0,1)(因为光滑球面么,法线一定是垂直的呀),然后就拿tangent space normal map里面这个值替换掉之前的原始值,大功告成,这就是B

    好了,从人类的本能来看,一个金属球被捏成棍子之后,反光是啥感觉?绝对不可能是A,一定就是B。这符合人类直觉。如果我们故意搞成A的话,一个光源照在棍子上之后,我们肉眼看到的就是一个圆形的光斑,这明显不符合现实;而做成B的话,一个光源照在棍子上之后是一条竖着的光斑,真实的很(想象一下在太阳下面拿一个金属棍和金属球,他们的反光是啥感觉)。
    所以对于变形(deform)来说,明显tangent space normal map好。同理,当搞什么uv_texture动画时(水流动,岩浆流动) ,那必须是tangent space好用啊。
    也有人谈过说tangent space normal map在变形变的厉害的地方,譬如说一个尖角处会有缝合问题,这个就不是我现在能操弄的了,要等待未来继续学习的结果。

猜你喜欢

转载自blog.csdn.net/mconreally/article/details/49663753