法线贴图
2016-06-14 19:52
302 查看
1. 个人理解法线贴图
在做动画的时候,面会变形,顶点关系改变了,即面的形状,方向改变了,如果面上存在一个固定的坐标系,那当物体变形,移动,旋转时,这个坐标系必定跟着面一起运动,那么在这个坐标系里的某个点或向量(比如我们把高模法线转换到这个坐标系里),不需要变动,当整个面发生变化时,我们只需要计算面上的坐标系到世界坐标系的转换矩阵,那么定义在这个面上的点或坐标(固定的),乘以这个矩阵即可得到在世界中的坐标,这个坐标如何构造目前对我们不重要,请务必理解这个概念.我们不过是寻求一个局部坐标系,局部坐标系中的点坐标,乘以局部坐标系到世界坐标系的转换矩阵(这个矩阵是低模渲染时动态计算的的),得到局部坐标系中的点在世界坐标系中的坐标,这样法线贴图中存储的固定的值(法线方向),才能进行有意义的计算。
看到这里很明显的,这种做法需要数千个不同的定义在面上的坐标系。低模上有多少个面,就得有多少个这样的坐标系。这种方法的计算量自然是比object space normal map要大一些的,在低模的每个面上,要构造出这个坐标系。这个坐标系术语里称为tangent space。
法线贴图保存的是高模的object space内的方向然后再转换到tangent space,所以在vertex shader中,我们必须先把光线先转换到object space,再转换到tangent space.这样才能保证最终计算时,光线与法线是基于同一个坐标系的,这也是你在很多normal map的shader里,看到类似ToOjectSpaceDir(lightDir)之类函数的原因,正是要把光转换到object space。
低模上的这个tangent space,也必须与高模上的坐标系tangent space。因为低模上的一个面,可能对应了高模上的几个面(精度高),按照新方法每个面都有一个局部坐标系,那对于低模上的每个面,高模因为存在好几个面,就会出现好几个局部坐标系,这肯定是不行的.所以高模所用的tangent space,就是低模上的,生成法线贴图,必定会确认高模上哪些面都对应低模上的哪个面,然后高模上的这几个面的法线,都会转换为低模这个面上所构建的tangent space的坐标.这样,当低模变形时,即三角面变化时,它的tangent
space也会跟着变化,保存在贴图里的法线乘以低模这个面的tangent space到外部坐标系的转换矩阵即可得到外部坐标,顺便再提一点,高模保存的这个法线,是高模上object space里的法线,看到这里你该明白这是自然而然的。你搜索文章时可能会看到什么把光转换到tangent space里,确保处于同一个坐标系下的话.确实是这样.但初次接触却还是模糊.我以为确保tangent sapce重合及做法,才是让人顿悟tangent space的诀窍点.
总结:法线纹理的RGB通道存储了在每个顶点各自的Tangent Space中的法线方向的映射值。
2. UnpackNormal 的作用
因为一个向量每个维度的取值范围在(-1, 1),而纹理每个通道的值范围在(0, 1),因此我们需要做一个映射,即pixel = (normal + 1) / 2。这样,之前的法线值(0, 0, 1)实际上对应了法线纹理中RGB的值为(0.5, 0.5, 1),而这个颜色也就是法线纹理中那大片的蓝色。这些蓝色实际上说明顶点的大部分法线是和模型本身法线一样的,不需要改变。
总结一下就是,法线纹理的RGB通道存储了在每个顶点各自的Tangent Space中的法线方向的映射值,所以,UnpackNormal 就是把RGB中(0, 1)的值转换实际用的(-1, 1)的法线的值。
参考网址:
写给笨人的法线贴图原理 :
http://www.cnblogs.com/flytrace/p/3387748.html
【Unity Shaders】法线纹理(Normal Mapping)的实现细节 : http://blog.csdn.net/candycat1992/article/details/41605257
在做动画的时候,面会变形,顶点关系改变了,即面的形状,方向改变了,如果面上存在一个固定的坐标系,那当物体变形,移动,旋转时,这个坐标系必定跟着面一起运动,那么在这个坐标系里的某个点或向量(比如我们把高模法线转换到这个坐标系里),不需要变动,当整个面发生变化时,我们只需要计算面上的坐标系到世界坐标系的转换矩阵,那么定义在这个面上的点或坐标(固定的),乘以这个矩阵即可得到在世界中的坐标,这个坐标如何构造目前对我们不重要,请务必理解这个概念.我们不过是寻求一个局部坐标系,局部坐标系中的点坐标,乘以局部坐标系到世界坐标系的转换矩阵(这个矩阵是低模渲染时动态计算的的),得到局部坐标系中的点在世界坐标系中的坐标,这样法线贴图中存储的固定的值(法线方向),才能进行有意义的计算。
看到这里很明显的,这种做法需要数千个不同的定义在面上的坐标系。低模上有多少个面,就得有多少个这样的坐标系。这种方法的计算量自然是比object space normal map要大一些的,在低模的每个面上,要构造出这个坐标系。这个坐标系术语里称为tangent space。
法线贴图保存的是高模的object space内的方向然后再转换到tangent space,所以在vertex shader中,我们必须先把光线先转换到object space,再转换到tangent space.这样才能保证最终计算时,光线与法线是基于同一个坐标系的,这也是你在很多normal map的shader里,看到类似ToOjectSpaceDir(lightDir)之类函数的原因,正是要把光转换到object space。
低模上的这个tangent space,也必须与高模上的坐标系tangent space。因为低模上的一个面,可能对应了高模上的几个面(精度高),按照新方法每个面都有一个局部坐标系,那对于低模上的每个面,高模因为存在好几个面,就会出现好几个局部坐标系,这肯定是不行的.所以高模所用的tangent space,就是低模上的,生成法线贴图,必定会确认高模上哪些面都对应低模上的哪个面,然后高模上的这几个面的法线,都会转换为低模这个面上所构建的tangent space的坐标.这样,当低模变形时,即三角面变化时,它的tangent
space也会跟着变化,保存在贴图里的法线乘以低模这个面的tangent space到外部坐标系的转换矩阵即可得到外部坐标,顺便再提一点,高模保存的这个法线,是高模上object space里的法线,看到这里你该明白这是自然而然的。你搜索文章时可能会看到什么把光转换到tangent space里,确保处于同一个坐标系下的话.确实是这样.但初次接触却还是模糊.我以为确保tangent sapce重合及做法,才是让人顿悟tangent space的诀窍点.
总结:法线纹理的RGB通道存储了在每个顶点各自的Tangent Space中的法线方向的映射值。
2. UnpackNormal 的作用
因为一个向量每个维度的取值范围在(-1, 1),而纹理每个通道的值范围在(0, 1),因此我们需要做一个映射,即pixel = (normal + 1) / 2。这样,之前的法线值(0, 0, 1)实际上对应了法线纹理中RGB的值为(0.5, 0.5, 1),而这个颜色也就是法线纹理中那大片的蓝色。这些蓝色实际上说明顶点的大部分法线是和模型本身法线一样的,不需要改变。
总结一下就是,法线纹理的RGB通道存储了在每个顶点各自的Tangent Space中的法线方向的映射值,所以,UnpackNormal 就是把RGB中(0, 1)的值转换实际用的(-1, 1)的法线的值。
参考网址:
写给笨人的法线贴图原理 :
http://www.cnblogs.com/flytrace/p/3387748.html
【Unity Shaders】法线纹理(Normal Mapping)的实现细节 : http://blog.csdn.net/candycat1992/article/details/41605257
相关文章推荐
- Kinect结合Unity3D引擎开发体感游戏(一)
- Unity3D中脚本的执行顺序和编译顺序
- Unity3D动态对象优化代码分享
- Unity3D获取当前键盘按键及Unity3D鼠标、键盘的基本操作
- Unity3d获取系统时间
- unity3d发布apk在android虚拟机中运行的详细步骤(unity3d导出android apk)
- Unity3D游戏引擎实现在Android中打开WebView的实例
- unity3d调用手机或电脑摄像头
- Unity3d发布IOS9应用时出现中文乱码的解决方法
- 分享一个开源的网络游戏服务器架构—HouHai
- Unity3D插件详细评测及教学下载
- Unity3D上路_01-2D太空射击游戏
- Unity3D上路_02-第一视角射击游戏
- Unity3D上路_03-塔防游戏
- Unity3D上路_04-基础资源介绍
- Unity3D上路_05-网络相关