位置: 编程技术 - 正文

法线贴图原理(法线贴图应该贴在哪里)

编辑:rootadmin

推荐整理分享法线贴图原理(法线贴图应该贴在哪里),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:法线贴图原理解析,法线贴图的作用是什么,法线贴图应该贴在哪里,法线贴图的作用是什么,法线贴图的原理,法线贴图的原理,法线贴图的作用是什么,法线贴图的原理,内容如对您有帮助,希望把文章链接给更多的朋友!

 我算个笨人吧.笨人以前弄懂一些东西后,讲给笨人听往往更有效.看之前请自行具备图形学关于光照的基础知识.

  >>  world/object space normal map

  我们先讲基于世界或模型坐标的法线贴图(world/object space normal map).不常用,但是基础.

  首先,请无视你之前google到的所谓通过Photoshop生成法线贴图类&#;文章,美术除外.那只是一种利用近&#;hack的手法利用法线贴图原理.无助于理解真正的过程.不过看完这文章后,你应能理解Photoshop的这种做法的来历.

  不搞清法线贴图的生成原理,是无法正确理解之后shader中的计算使用的.法线贴图的出现,是为了低面数的模型模拟出高面数的模型的"光照信息".光照信息最重要的当然是光入射方向与入射点的法线夹角.法线贴图本质上就是记录了这个夹角的相关信息.光照的计算与某个面上的法线方向息息相关.

  我们知道计算机里的模型,是通过多个多边形面组合来近&#;模拟一个物体的.它不是圆滑的.面数越多,则越接近真实物体.光照到某个面当中的一点时,法线是通过这个面的几个顶点通过插&#;得到的.插&#;其实也是为了模拟这个点"正确"的法线方向,不然整个面所有点的法线一致的话,光照上去,我们看到的模型夸张点就像一面面镜子拼接起来了.但法线插&#;不可避免的仍然会失真.模型的面数越高,失真的程度自然越小.要是能无限细分到人&#;看不出的地步,根本不用插&#;了.

  面数高,需要计算的量和内存需求就高.前辈找到了法线贴图(前身是凹凸贴图)这个办法,使低模能够近&#;享受高模的光照细节信息.代价是有的,就是需要一个记录这些信息的文件.这是程序中常用的存储空间换计算时间的做法.3D程序中偏爱使用这个手法.谁叫存储硬件的单位价&#;比计算硬件的单位价&#;降低速度快很多呢.

  显卡包括包括与之相辅的图形api,读的数据最初来源是图片.所以记录这个信息的文件就被我们保存为图片&#;式.法线贴图后边2个字就这么来的.很好你已经明白一半了.

  我们再来弄清另一半.

  因为面数少,低模上某个区域的一个面,可能就是高模上相同区域的几个面.看下图的高模与低模的对比(为了简便我们抽象为2维的线段)

上边凹凹凸凸的曲线表示高模.下边比较平滑的表示低模.因为高模细节多,所以在某段区域它的方向变化自然比平平板板的低模多.上图看不懂我表示无能为力.

  看到这图,一些人应该有所感觉了.没感觉也不要紧,接下再来.

  不管高模还是低模,反正最后还是要被上色的.假设模型已经被渲染完成有颜色了,现在我们想象用剪刀把模型展开(类&#;给动物扒皮的过程),得到2张差不多一样大小的皮,毕竟面积不会差太多.高模的皮当然肤白体嫩精度高,低模的皮就有些糙了.现在再想象这么个过程:逐渐把高模的皮移到低模的皮上方一定高度直到水平重叠.

  现在这个样子你有感觉没有?没感觉也不要紧,接下再来.

  虽然模型精度不一样,无论如何,这2张皮每一点都是有颜色了的(插&#;的功劳).两张皮上相同一点的颜色,高模这张皮上的更真实,因为在计算最终颜色信息所依赖的法线,高模上的点比低模上的点更精确.我们如何给低模这张皮美容,使它能够接近高模的效果呢?换句话说,找到办法,使土肥圆演变为黑木耳,质变为白富美是不可能的,那得下辈子.

  办法很暴力.现在再想象你用一根针,从上往下,刺穿高模的皮,再刺到低模的皮.保证针垂直,这样就刺到同一点了.再想象如果这针有魔力的话,它刺穿高模皮的过程中,盗取了一些信息,传送到低模皮上边.低模皮依靠这些信息计算,成功蜕变为黑木耳.这些信息是什么呢?当然是法线信息了.现在高模这张皮被密密麻麻插满了针&#;,换句话说,保存高模泄漏来的信息,必定是点对点的.即这张皮上的每个点,都得被保存.所以法线贴图跟原始的贴图是一样大小的,贴图内每个点都保存了对应高模某个点的法线信息.实际的计算,只会关心由贴图里得来的法线信息,低模上的那些法线,被抛弃了.

  现在这个样子你有感觉没有?没感觉也不要紧,接下再来.

  如何赋予这根针魔力呢?宅男们,甘道夫是帮不了你的忙的.伟哥也帮不了你.只有数学,才能拯救世界...

  为什么我之前强调垂直呢?不只是为针能扎到同一点.现在请把这个过程,想象到上图中.图中的箭头,表示高模上某个点的法线方向.如何记录这个方向信息?现在请想象逐渐把高模和低模重叠在一起,为了方便想象,低模小一些被高模包住了.或者你干脆想象高模的面在低模面的正上方,或一个圆球里有一个内切的正多面体.再想象有一束光线(针的等价物),从上往下照射,把高模上的法线投射到低模上.

  现在你有感觉了吧.

  前戏大功告成,现在我们来处理稍微细节些的问题了.这是一个投影过程.但是影子是2维的啊?向量是由x,y,z三个分量构成的.高模上某点投影到低模上对应点所在平面,只剩2个分量的投影了.好比我们现在只知道法线在x-y平面的投影方向,那在z轴的方向呢?只要我们确保投影前法线是单位向量,那很简单z=1-x*x-y*y.这样我们还可以省下保存z的空间.其实我们既然已经知道这个法线方向(高模object space内的法线方向),而且被单位化了,直接保存也是可以的.投影过程只是个思想实验,实际是不会有什么光线由上到下投射的.

法线贴图原理(法线贴图应该贴在哪里)

  到此可以明确了,"正统"的法线贴图生成,是高模,低模不可缺一的.因为没有高模就不知道法线方向,没有低模,就不知道高模上某点的法线对应于低模上哪个点.

  因为某点的法线信息是被保存到法线贴图上对应像素点的.实际计算是把法线x,y,z方向大小映射到颜色空间rgb里.就是把x&#;存在r里,把y&#;存在g里,把z&#;存在b里.因为rgb是8字节为单位的.所以高模的法线信息存储到像素里是要丢失精度的.而且前面计算高模与低模对应点也不可能完全匹配到,本来就是个模拟过程.自然法线贴图也不是无敌的.

  现在我们可以回答之前的Photoshop根据diffuse贴图生成法线贴图的问题了.实际的diffuse贴图是根本没有包含模型上的法线信息的.因此它根据diffuse贴图得出的法线贴图根本就是错误的.但为什么能够应用呢?请想象高模的精度高的吓人,高到渲染后把高模皮扒下来后,就成了一张照片.再想象之前高模上的贴图是布满了铁锈.于是你就得到了一张铁锈照片.Photoshop处理这张铁锈照片,其实是根据一些算法(sobel等等)把颜色&#;转化为梯度&#;,近&#;模拟了法线.因为我们其实不关心铁锈的精确分布,像那么一回事就可以了,所以这种情况下如此处理是可以将就的,坑坑&#;&#;效果最适合如此做法.photoshop这种脱离高模低模的做法容易让人迷惑,导致新手以为法线是从diffuse贴图上来的,或者干脆被阻断了思路.

  我们上边计算法线贴图所用到的法线,又是从哪里来的.如果这个法线方向,是处于世界坐标中的(world space),那称为world space normal.如果是处于物体本身局部坐标中的,那称为object space normal.很容易想象,world space normal一旦从贴图里解压出来后,就可以直接用了,效率很高.但是有个缺点,这个world space normal 是固定了,如果物体没有保持原来的方向和位置,那原来生成的normal map就作废了.因此又有人保存了object space normal.它从贴图里解压,还需要乘以model-view矩阵转换到世界坐标,或者转换到其他坐标取决于计算过程及需求.object space normal生成的贴图,物体可以被旋转和位移.基本让人满意.但仍有一个缺点.就是一张贴图只能对应特定的一个模型,模型不能有变形(deform).

>>  tangent space normal map

  为解决适应变形的normal map,我们仍能从这两种方法中得到启示.world space normal直接保存的是世界坐标系中的高模法线方向.因此低模取出该点法线就可以直接使用,前提是低模的世界坐标系与高模一致,一点旋转都不能有,不然法线方向就改变了.object space normal保存的是模型空间坐标系中的高模方向,低模取出该点取出来法线,还需要乘以所在的model-view矩阵,转化为低模的世界坐标系中的方向,也就是说低模端还需要做一个运算.因此即使低模任意旋转也不怕,有model-view矩阵可以把法线贴图中的&#;转换两者效率由高到低,灵活度由低到高.问题来了,我们是否能找到高模上的另外一个坐标系统,使低模变形也时也能较正确的变换法线到世界坐标系中?

  我们考察一下object space.当一个低模旋转时,因为是刚体不变形,相当于每个点都乘以一个旋转矩阵R,之后各点关系保持不变.实际上,我们保持物体不旋转,将object space的坐标系(x,y,z三个轴)旋转,得到的结果是一样的.这个关系相信大家都能理解.换句话说,法线针对于object space是固定不动的,物体保持在object space固定,只管跟随坐标系的移动,旋转就行了.现在我们想象低模的某个点需要变形时,那原则上也可以通过让object space坐标系乘以某个变形矩阵T来达到.但是不同的点有不同的变形,不可能存在一个矩阵T即适合这个点又适合这个点.因此object space坐标系是不能用的.会有哪个单一的坐标系能存在一个所有点都共用的变形矩阵吗?显然无法想象.

  变形时,顶点关系改变了,即面的形状,方向改变了.如果面上存在一个固定的坐标系,那当物体变形,移动,旋转时,这个坐标系必定跟着面一起运动,那么在这个坐标系里的某个点或向量(比如我们把高模法线转换到这个坐标系里),不需要变动.当整个面发生变化时,我们只需要计算面上的坐标系到世界坐标系的转换矩阵,那么定义在这个面上的点或坐标(固定的),乘以这个矩阵即可得到在世界中的坐标.这个坐标如何构造目前对我们不重要,请务必理解这个概念.我们不过是寻求一个局部坐标系,局部坐标系中的点坐标,乘以局部坐标系到世界坐标系的转换矩阵(这个矩阵是低模渲染时动态计算的的),得到局部坐标系中的点在世界坐标系中的坐标.这样法线贴图中存储的固定的&#;(法线方向),才能进行有意义的计算.

  看到这里很明显的,这种做法需要数千个不同的定义在面上的坐标系.低模上有多少个面,就得有多少个这样的坐标系.这种方法的计算量自然是比object space normal map要大一些的.在低模的每个面上,要构造出这个坐标系.这个坐标系术语里称为tangent space.

  object space normal map的中,低模的object space坐标系与高模中的object space坐标系是重合的.所以不需要构建,所以低模上某点才能直接用高模的法线替换自己的法线.坐标系重合这个概念很重要.新方法中,低模上的这个tangent space,也必须与高模上的坐标系tangent space.因为低模上的一个面,可能对应了高模上的几个面(精度高),按照新方法每个面都有一个局部坐标系,那对于低模上的每个面,高模因为存在好几个面,就会出现好几个局部坐标系,这肯定是不行的.所以高模所用的tangent space,就是低模上的.生成法线贴图,必定会确认高模上哪些面都对应低模上的哪个面,然后高模上的这几个面的法线,都会转换为低模这个面上所构建的tangent space的坐标.这样,当低模变形时,即三角面变化时,它的tangent space也会跟着变化,保存在贴图里的法线乘以低模这个面的tangent space到外部坐标系的转换矩阵即可得到外部坐标.顺便再提一点,高模保存的这个法线,是高模上object space里的法线,看到这里你该明白这是自然而然的.你搜索文章时可能会看到什么把光转换到tangent space里,确保处于同一个坐标系下的话.确实是这样.但初次接触却还是模糊.我以为确保tangent sapce重合及做法,才是让人顿悟tangent space的诀窍点.

  上图稍微清楚一些了.曲线表示高模,P点处有TBN坐标系.线段表示低模,M点处有T'B'M坐标系.高模上P点处的法线转换到TBN坐标里,与N的夹角为NPN'.低模处取出这个法线为N'',与低模的PM(面法线)夹角为PMN''.可以看到这2个夹角是近&#;的.所以渲染时高模上的法线,是基于低模上的这个坐标系运算的.你可能会说,我这的TBN不就是实际的高模面上的左边吗?别忘了很可能几个高模的面挤在一起对应一个低模的面,高模的这个TBN必然是经过一种“插&#;”或“平均”得来的,实际上也会跟低模有些相关性,以求最匹配的效果。具体如何得来未深究,有高手可否告知否?

  当我自己想到上边这段话时,tangent space的法线贴图原理就豁然开朗了.接下来我们构建这个tangent space坐标系.

  面在动时,tangent space也得跟着动.面上的垂直法线是跟着动的,因此这个法线N可以作为tangent space的一个坐标轴.非常非常需要注意的是,这里所说的面上垂直法线,不是指插&#;所得来的法线,那个法线正是是我们需要保存的内容.N单纯就是指垂直于这个面的方向.

我们考察上图,对于一个三角面,它的边V2V1,V3V1,V3V2我们总是能够确定的.边也定会在变形时跟着动.因此我们可以选择一条边作为tangent space的第二个坐标轴T.第三个坐标轴就简单了,直接根据叉积来B=T * N.这个坐标轴就订好了.其实,坐标轴的选定几乎可以是任意的,只要你能够确保每次都能构建出来.比如你可以先选择V1V3,V1V2作为坐标轴,N=V1V3 * V1V2.这里N恰好和前面一样方向.但如此一来这个坐标系中V1V2,V1V3不是垂直的,不正交的坐标基在矩阵运算中是不方便的,还得正交化.因此我们选择第一种最直观最清晰最方便的方法.

  既然三个坐标轴都确定了,那构建object space到tangent space的矩阵O-TBN就简单了,我们把T,B,N单位化,分别作为tangent space的x,y,z轴.根据三个坐标基我们构造矩阵如下:

 O-TBN =

高模上object space内的某点法线(不会是world space的,否则旋转就露相),乘以这个矩阵,即得到tangent space内的法线方向,再把这个&#;映射到rgb空间,存为贴图即可.这个矩阵为什么是这样,这是题外话了.我简略说一下:object space的三个坐标轴(1,0,0),(0,1,0),(0,0,1)乘以这个矩阵,必须刚好为tangent space中的坐标轴,很自然矩阵就是上边的样子.而object space其他点的坐标都是x,y,z三个单位坐标的线性组合.所以这个矩阵对于其他点必定是正确的.

  实际上在vertex shader中,我们只能知道当前顶点的信息,三角形的另外两个顶点我们是不知道的.但现代的shader能够为顶点提供一个tangent信息,表示在顶点处的切线.你可以想象一个足球上经过某点的切线.因此我们会把顶点的tangent方向作为上边的T向量.这也是tangent space叫这个名称的由来.你会看到很多文章中提到纹理的u,v方向.因为面上某点的u,v是沿各条边线性插&#;的,所以u,v方向与边的方向相同.其实我们现在已经有现成的tangent可以用了.

  现在我们可以分析为什么tangent space法线贴图是偏蓝色了.因为对于高模上的面来说,因为精度太高(面很小,而且周围的面相对它的方向很平滑),所以这个面渲染时计算机认为这个面的"弯曲"程度很小,即面上各个点插&#;得来的法线相互间偏差很小.基本跟整个面的垂直方向不会差太多.因此在tangent space里,这些法线都跟z轴偏差较小.而z轴是被保存在贴图里的b字节处(蓝色通道)里.所以贴图显示出来的颜色就偏蓝了.

  好了,现在高模面上各点的法线&#;,都转换为低模上的tangent space坐标了.现在我们考虑具体的低模上的渲染计算了.假设在低模上的某个面我们计算出了这个矩阵,并取出了面上某点的对应在法线贴图里法线&#;.现在需要计算光照.我们可以把光向量转换到tangent space里做计算.也可以把得到的法向量转换到world space与光向量进行计算.结果是一样的.实际考量,你会发现后一种方法不好.因为对于面上的每个点,都要计算一次normal到world space的准换.而前一种方法,对一个面上的所有点,只要计算一次光向量到tangent space的计算.然后再考虑到vertex shader与fragment shader的流程,你会发现刚好我们可以在vertex shader计算光线到tangent space的转换,在fragment sader取出法线&#;与前面得到的tangent space里的光线方向做计算即可.这里提醒一下,一般verteix shader中我们得到的光线方向是基于world space的,而法线贴图保存的是高模的object space内的方向然后再转换到tangent space,所以在vertex shader中,我们必须先把光线先转换到object space,再转换到tangent space.这样才能保证最终计算时,光线与法线是基于同一个坐标系的.这也是你在很多normal map的shader里,看到类&#;ToOjectSpaceDir(lightDir)之类函数的原因,正是要把光转换到object space.

  实际做法可能会有些复杂.比如有些模型是镜像对称,贴图也是镜像对称的,计算时会省去另一半等等.这时如何处理看具体的法线贴图生成软件和处理它的引擎(shader)了.基本原理还是上边所说的.

  tangent space normal map适应变形的这种能力,使它不仅能够应用在原来的模型上边,甚至可以应用在变形严重的不同模型上.即法线贴图有一定的脱离原来模型使用的能力.比如你模拟出了一个高精度的粗糙花岗岩平板表面,得出的法线贴图可以应用到圆柱模型上边.类&#;photoshop的直接根据花岗岩表面照片生成法线贴图也是能够使用的.因为目地就是为了微小的扰动法线生成凹凸不平的表面.虽然这个表面并不是正确的还原一个真正存在的花岗岩表面.但图形学不就是一个模拟过程,能足够真实的欺骗我们的&#;睛就行.其实这种粗糙表面微小扰动只是应用之一.你搜到一些处理的好的图片,不仔细看你会发现低模的怪物会以假乱真体现出高模才有的平滑弯曲.

  以上是法线贴图的原理.因为该原理的应用范围很广,也能够串起很多知识点,是非常&#;得搞清楚的.我当初在学习法线贴图过程中,没有看到能够讲的让我清晰明白整个过程的.遂作此篇.

好文章要大家分享,原文地址:

Unity3D发布开源免费插件Antares扩展包 最近unity3D又发布了一套开源扩展包Antares,让我们快来看看这个扩展包到底都新增了哪些功能。Antares资源浏览器和它的附加包是一个基于C#的Unity3D编辑

“原状”类人动画编写根运动脚本 (Scripting Root Motion) 教程:为原状类人动画编写根运动脚本(ScriptingRootMotion)有时您的动画保持为原状,这意味着,如果您将其放入场景中,它不会移动上面的角色。换言之

Unity 4.2一些令我欣喜的新特性 Unity4.2发布带来了一系列或大或小的更新,增加免费Windows8/Phone的发布选项,增加免费版功能等重要的就不提了,官方的更新页面有大字介绍。大致看了

标签: 法线贴图应该贴在哪里

本文链接地址:https://www.jiuchutong.com/biancheng/383588.html 转载请保留说明!

上一篇:EasyTouch Broadcast messages选项在js和c#下的用法

下一篇:Unity3D发布开源免费插件Antares扩展包(unity开发平台)

  • 超市的库存商品分类混乱怎么看出来的
  • 施工二级资质是什么意思
  • 用友T3资产负债表公式
  • 金蝶利润表没有数据怎么办
  • 未开票收入以后必须开票吗
  • 产品税率下调企业是否要到税务部门备案
  • 小规模纳税人购车可以抵扣多少税
  • 延迟付款确认是怎么回事
  • 金税三期如何报个税
  • 租赁到期日 英语
  • 增值税普通发票和普通发票的区别怎么交税
  • 小规模9万是含税吗
  • 同一个单位,应收应付都有,怎么调账
  • 非营利组织报销做账怎么做
  • 比赛奖金支出计入什么科目
  • 预收款没有发票怎么入账
  • 企业所得税减免税额计算公式
  • 工程承包付款最佳方式
  • 企业的银行利息收入要交企业所得税吗
  • 购买土地交易费用怎么算
  • 如何在vue项目中导入外部的包
  • 研发费用的归集范围
  • 把桌面文件放到虚拟机
  • thinkphp5开发教程
  • 建筑公司支付的预付款担保保函费怎么做账?
  • 收到融资款如何做账
  • php字符串操作函数
  • excel2019冻结
  • 其他应付款的会计科目
  • 没有审计报告的情况说明
  • php自定义header
  • thinkphp yii
  • php统计中文长度
  • vi命令模式下的常用命令有哪些?
  • 累计预扣法的适用条件
  • bash的主要功能
  • 主营业务收入和营业外收入的区别
  • 帝国cms视频教程
  • linux开启php服务
  • 代扣代缴个税手续费返还文件
  • sqlserver2005使用
  • mysql和sqlserver的sql语句一样吗
  • sql数据库聚集索引和非聚集索引的区别是什么?
  • 个体户是什么概念
  • 旅行社开具的发票可以作为福利费税前支出吗
  • 其他债权投资如何计提减值
  • 投资损失如何入账
  • 购买税控盘费用能全额抵扣吗
  • 定额发票是否可以盖公章
  • 产品质量问题扣款账务处理
  • 跨年度的银行未入账如何处理
  • 进项抵扣后的附加税
  • 税务销售滞后是什么意思
  • 打印银行电子流水发到别人邮箱,能看到我的账户余额吗
  • 公司团体体检一般什么价位
  • 租赁合同的印花税的计税依据
  • 如何使用费用分割单
  • 在哪找从平台消费的人
  • mysql 定点数和浮点数
  • 5分钟了解环保币gec
  • image driver
  • win8系统蓝屏后无法修复
  • fs是什么文件夹
  • neo是什么意思中文翻译
  • win7任务栏还原到下面快捷键
  • win10 ie桌面图标
  • 怎么激活win7旗舰版系统
  • linux在u盘中运行
  • Unity3D游戏开发标准教程
  • javascript数据结构
  • android点击按钮弹出对话框
  • python算法简单编程题
  • jQuery基于ajax()使用serialize()提交form数据的方法
  • jquery操作样式的方法
  • jquery div滚动条
  • python环境及基础语法
  • 江苏省增值税专用发票怎么开
  • 重庆市电子税务局发票查询
  • 国家税务总局2019年45号公告解读
  • 日本快递税率
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设