【技术美术图形部分】纹理基础2.0-凹凸映射
目录
凹凸贴图/映射 bump mapping 概念
What——通过纹理的方法产生表面凹凸不平的视觉效果
Why——假装视觉效果,可以节省性能
How——高度贴图/法线贴图
1 高度贴图 height mapping
优点
缺点
2 法线贴图 normal mapping
2.1 模型空间
模型空间储存法线的优点
2.2 切线空间
切线空间储存法线的优点
2.3 世界空间
3 制作中如何使用法线贴图
3.1 实际中法线贴图的使用流程
3.2 法线烘焙
4 如何从高度图/纹理生成法线纹理
5 光照计算中的坐标转换
学习的教程
【技术美术百人计划】图形 1.3 纹理的秘密_哔哩哔哩_bilibili
辅助书籍参考
《Real-Time Rendering 3rd》提炼总结 -毛星云
《Unity Shader入门精要》-冯乐乐
上一篇博客链接
【技术美术知识储备】纹理基础1.0(结合RTR4)
1.0中过了一遍单张纹理如何应用——纹理管线的内容,2.0这部分继续来说说凹凸映射这部分内容。
凹凸贴图/映射 bump mapping 概念
涉及凹凸贴图,我在之前学习Games101的时候就写过一篇学习法线贴图的文章,内容很简单:GAMES101学习-法线贴图学习笔记
What——通过纹理的方法产生表面凹凸不平的视觉效果
凹凸贴图思想最早由Jim Blinn提出的,后来的Displacement Mapping(位移贴图),Norma Mapping(法线贴图),Parallax Mapping(视差贴图)和Relief Mapping(浮雕贴图)等都是基于凹凸贴图思想进行的改进,考虑的越来越全面,效果越来越好。
在一切之前,必须要提醒的是:
凹凸贴图(无论是高度贴图还是法线贴图),它不会改变模型的细节,只是增加光照互动的细节!因此,对于不受光照的物体,凹凸贴图并不起作用。
原理
通过改变表面光照方程的法线,而不是表面的几何法线(法线贴图),或者对每一个待渲染的像素在计算光照之前加上一个高度图中找到的扰动(高度贴图),来模拟凹凸不平的效果。
目的
给光滑的表面在不增加顶点的情况下,仅使用一张纹理来修改模型表面的法线,增加一些凹凸的细节变化。
Why——假装视觉效果,可以节省性能
为什么要用凹凸贴图?
我认为很多时候,想要实现一些褶皱、波浪、碎石地面的凹凸不平等粗糙表面的效果,如果不需要精确到物理效果的细节,可以让他们只是视觉上看上去是真的,不需要真的做出来(节省性能)。那就很容易想到:可以用一个贴图去假装这样的视觉效果。
How——高度贴图/法线贴图
值得注意的是,《Unity Shader入门精要》里描述实现凹凸贴图bump mapping有以下两种方法:
- 高度贴图 height mapping
- 法线贴图 normal mapping
但正常发展认为Bump mapping思想是法线贴图的鼻祖,高度贴图是属于最早开始提出的一个实现凹凸效果的一种方法。
这两种表述方法并不影响凹凸贴图的学习,本篇博客采用《入门精要》里的描述方式进行接下来的叙述。
其次,很多地方在描述贴图时就指的是某张纹理(例如“切线空间的法线贴图一般是蓝色的...”这种 描述),也不必钻牛角尖,但本篇博客是将纹理map和贴图mapping分开描述了,提前说一下以免产生困惑。
1 高度贴图 height mapping
是实现凹凸效果的一种方法,比较古早了。使用高度图来实现凹凸贴图,高度图中储存的是强度值(intensity),表示表面的局部高度。例如《提炼总结》中列举的波浪高度纹理:
优点
很直观,它就是一张储存了256种不同黑白灰的灰度图,只告诉软件一件事:凸起还是凹陷。
颜色越白(灰度大于50%)表示越凸,越黑(灰度小于50%)表示越凹进去,灰度为50%则不会有凹凸效果。
缺点
缺点还是很明显的,它计算复杂!在渲染中不能直接获得表面法线,还需要根据灰度值再计算一次才能得到法线——需要消耗更多性能。
2 法线贴图 normal mapping
法线贴图储存表面的法线信息,法线贴图需要的这些法向量信息可以由高度图得到。法线纹理直接储存为常规的RGB图像,RGB通道分别对应着表面法线方向的X、Y、Z坐标。
但由于法线方向分量的范围在[-1, 1],但像素的分量范围在[0, 1](RGB值,0->0, 1->256),因此储存法线信息在法线纹理中会做一次映射:
例如,模型空间(法线纹理的三种空间之一,后续会讲述)中的法线normal(0, -1, 0)映射后就成了像素pixel(0.5, 0, 0.5)紫色。
当纹理管线中采用Shader通过采样纹理图像获取纹理值的步骤时,会再次将采样得到的结果值反映射回法线方向:
既然涉及到法线,不难想到该如何定义法线方向坐标?
事实上,法线有三种不同类型空间,又分别对应着三种不同类型空间的法线纹理。
2.1 模型空间
模型空间(object space)有时又被叫做对象空间,它俩一个意思。建模师们建立的模型默认的顶点信息都是模型空间的,基于模型空间储存的法线信息就很直接了——把修改后的模型表面的法线信息储存在一张纹理中。
模型空间储存的法线信息是绝对的,它不会随着模型在场景中旋转、缩放而有所改变。
模型空间储存法线的优点
- 更直观
实现起来简单、直观。模型空间储存的法线纹理往往是五颜六色的,因为模型表面的法线方向往往是各个方向的,如下图模型空间和接下来要介绍的切线空间的法线纹理对比(左侧):(图源法线贴图那些事儿 - 知乎 (zhihu.com))
- 突变少
UV缝合处以及尖锐的边角部分更加的平滑,这是由于模型空间下储存的纹理信息是同一坐标系下的法线方向,边界处可以通过插值获取,可以平滑变换;
- 自由度低
仅能应用于创建基于的模型,因为模型空间下储存的法线方向是绝对的;
2.2 切线空间
切线空间(tangent space)其实也是我们实际制作中最常用的坐标空间。切线空间是基于模型每个顶点为原点构造的一个局部坐标系,位于表面之上。表面除了储存顶点和法线外,还储存了切线tangent和副切线bitangent:
- z轴是模型顶点本身的法线方向(n)
- x轴是顶点的切线方向(t)
- y轴是顶点的副切线方向(b,可由z和x轴叉积得到)
由这三个轴组成了切线空间的空间基TBN矩阵(在后续计算光照进行空间转换时会用到)。
这么一看,切线空间的法线纹理其实就是储存了每个顶点各自切线空间中法线的扰动方向。
如果顶点没有什么凹凸效果,那么顶点在切线空间中的法线就是z轴本身(0, 0, 1)经过映射后得到(0.5, 0.5, 1)->(128, 128, 256)就是浅蓝色:
由于凸凹效果其实就是对顶点原法线施加一个微妙的扰动,大部分顶点法线都是原法线。因此,我们看到的切线空间的法线纹理都是呈现大片的浅蓝色,例如上面模型空间已经出现过的(右侧):
切线空间储存法线的优点
- 自由度高
相比于模型空间的法线纹理,切线空间都是基于顶点自己的,都是相对的法线信息,这就意味着这张纹理可以应用于多个完全不同的网格上。
- 可重用
使用一张切线空间的法线纹理,就可以用到同一个模型的不同面上,例如一块砖的六个面可以共用同一张法线纹理。
- 可进行UV动画
可以通过移动一个纹理的UV来实现凹凸移动的效果,可以用于水、岩浆等流动的物体简单动画。
- 可压缩
上面已经讨论过,Z轴永远是正向的,那么我们就可以只储存每个点的XY信息,Z通过推导得到即可,这一点模型空间就没办法做到。
因此,一般我们都选择切线空间下的法线贴图
2.3 世界空间
对于法线纹理的储存坐标空间来说,基于世界空间的法线纹理一般只适用于静态、大型的模型,比如宏大的地形等,不做太多的转换。
但对于后续进行的光照计算,世界空间和切线空间一起是最为常用的两种空间。
进行光照计算时,我们需要将法线纹理储存的法线和顶点坐标信息,以及光照方向、视角方向信息等变换到同一个空间下,基于同一套坐标系再进行光照计算。这时候世界空间就参与进来了。
目前为止的一些困惑
纹理知识学习到这里,我自己有这样两点困惑:
- 目前为止获取的信息很散,所以,法线贴图到底在哪个流程参与到渲染中的?
- 假设我现在搜索得到了一张墙的纹理图片,我怎么给他加上法线纹理?
下面就大概来说一说这两个问题,首先是法线贴图如何使用?
3 制作中如何使用法线贴图
前面说的都是一些理论的东西,这次让我们结合实际制作看看法线贴图的使用过程。
一开始我们怎么介绍法线贴图的目的来着?——作为凹凸映射的一种方法,为了让模型渲染的更加真实好看,有凹凸感。
当然了,法线贴图并不是必须的。如果不使用法线贴图,为了让模型渲染的更加真实,一般会选择制作成面熟比较多的高模(这里尚且不探讨用面数界定高、低模正确与否),但这会带来一个问题——计算量大,消耗性能。因此,采用法线贴图能达到即渲染更加真实,又节约性能的目的。
3.1 实际中法线贴图的使用流程
建模师们会制作面数较少的低模和面数较多的高模,低模用来正常走纹理管线——展UV,高模用来获取法线纹理——记录下这个高面数模型的表面法线信息并储存在一张纹理中,此时得到了法线纹理。接下来,真正参与渲染的模型本体其实是低模,渲染时用上高模的法线信息,就达到了让低模具备高模渲染效果的目的。
描述成一个流程大概就是:
制作低模、高模 -> 低模展UV(1.0纹理管线已提到)-> 高、低模烘焙法线 -> 渲染
3.2 法线烘焙
这部分的叙述参考了法线2:烘焙法线贴图 - 知乎 (zhihu.com)
烘焙法线就是把高模的法线方向以像素的形式储存在低模的表面上,也就是上述流程中后面低模获取高模信息的过程。烘培程序从低模开始投射基础光线,跟随顶点法线搜索高模。
随意找了一篇blender中进行法线烘焙的文章简单几步搞定Blender法线烘焙! - 知乎 (zhihu.com)
读完后就能对建模软件中进行法线烘焙的流程有了个大致的了解,至于法线烘焙遇到的一些问题以及细节的过程,这里就不做过多的介绍了。
4 如何从高度图/纹理生成法线纹理
这就是上面提到的第二个问题: 假设我现在搜索得到了一张墙的纹理图片,我怎么给他加上法线纹理?
其实就是拿到了一个仅包含基础色信息的纹理,我想要捏造出来他的凹凸信息。
随手一百度,其实有很多种不同的方法了:有从PS里滤镜->转法线图的方法、有把灰度图直接当成高度图再转法线纹理的方法、有先给图片去色转成灰度图,再转成法线纹理的方法。
以上是手动的方法,还有一些图片转纹理的软件,例如Texture Maker、Normal Map Generator等。
5 光照计算中的坐标转换
在讲世界空间时就提到了:进行光照计算时,我们需要将法线纹理储存的法线和顶点坐标信息,以及光照方向、视角方向信息等变换到同一个空间下,基于同一套坐标系再进行光照计算。
法线纹理基于切线空间,那么可选的光照计算方法无非这两种:
- 在切线空间下计算光照
- 在世界空间下计算光照
这部分我认为实践记录更清晰,因此后续会单独开一篇博客来讲二者的计算过程(涉及到了TBN矩阵等内容),这里仅谈谈渲染光照计算中需要涉及到坐标转换这么一个事情。
【技术美术图形部分】纹理基础2.0-凹凸映射相关推荐
- 【技术美术图形部分】2.2 模型与材质基础
记录之前膜拜一下这节课的大佬,才大三,我一个研二菜狗留下不学无术的泪水! May佬提到,这次课程安排的目的是给美术同学一个缓冲的空间,我的话在写这篇学习笔记就尽量加入一些自己的理解. 友情提示!才发现 ...
- 【技术美术图形部分】图形渲染管线3.0-光栅化和像素处理阶段
写在前面 开始学习<入门精要>第八章透明效果后,接触到了渲染顺序.透明度测试这些概念,才发现之前的渲染管线总结忘掉了光栅化和像素处理这两个阶段的学习记录,怪不得没什么印象...赶紧写一篇补 ...
- 【技术美术图形部分】PBR全局光照:理论知识补充
写在前面 最近做东西的流程是这样的,想实现一个风格化森林小场景,场景体现的主体是风格化树和交互草 --> 于是用了两天时间学SpeedTree做树模型 --> 用了两天时间SD做了树干贴图 ...
- 【技术美术图形部分】纹理基础1.0-纹理管线
目录 1 纹理三大问 1.1 What--针对物体表面属性进行"建模" 纹理 Texture 纹理值 Texture Value 纹素 Texels 1.2 Why--降低建模工作 ...
- 【技术美术图形部分】关于前向渲染和延迟渲染
学习参考 [技术美术百人计划]图形 3.4 延迟渲染管线介绍 <Unity Shader 入门精要> 1 Unity的渲染路径 关于渲染路径,我在图形渲染管线1.0中就提过了,但只是初步的 ...
- 【技术美术图形部分】2.3 HLSL常用函数
--介绍HLSL常用函数,API的使用. 想要成为合格的技术美术,一定要具备Shader开发能力,满足性能的需求,无论是技术美术的哪一个方向,HLSL都是需要点满的技能点. 参考 微软官方HLSL库: ...
- 【技术美术图形部分】图形渲染管线2.0-GPU管线概述几何阶段
图形渲染管线1.0 [技术美术知识储备]图形渲染管线1.0-基本概念&CPU负责的应用阶段 在上一篇中,从渲染分类开始介绍了什么是渲染流水线.为什么要有流水线以及流水线如何进行的,还介绍了CP ...
- 【技术美术图形部分】PBR直接光部分:Disney原则的BRDF和次表面散射模型
写在前面 补充去年遗漏下的知识.很多叙述都是参考了众多大佬的文章!因为是作为个人学习总结的博客,所以直接卑微的借鉴过来了,后面会给出所有参考的文章. 另外,放上一个忘了在哪一篇知乎评论里的截图: 说的 ...
- 【技术美术图形部分】AO理论及优化 AO贴图如何参与渲染
写在前面 昨天从美术的角度出发,对AO贴图参与到次世代建模流程中的过程进行了学习.今天从图形学角度学习环境光遮蔽. 封面图截取自实时渲染GI|Ambient Occlusion:AO.SSAO.HBA ...
- 【技术美术图形部分】图形渲染管线1.0-基本概念CPU负责的应用阶段
渲染分类 谈渲染管线之前,我想有必要看看渲染的分类.渲染可以按不同的分类依据进行分类: 按照渲染时机可以分成实时渲染(除了用于3D游戏还多用于工业仿真方面,注重交互性和实时性)和离线渲染(离线渲染多用 ...
最新文章
- [A Dangerous Maze LightOJ - 1027 ][概率题]
- R语言多因素有交互方差分析(Two-Way ANOVA)实战:拟合多因素有交互方差分析模型、分析不同分组的差异TukeyHSD、多因素有交互方差分析的结果总结
- JS脚本实现CSDN免登陆免关闭广告插件自动展开“阅读更多”内容
- java 取绝对值_Java实现一致性哈希算法,并搭建环境测试其负载均衡特性
- 阿里云引领云原生进化 | 云原生生态周报 Vol. 60
- QuickStart系列:docker部署之MariaDB
- 创新将会出现在云端,边缘还是其他地方?
- linux 网桥的管理和搭建
- java string 转 inputstream_String和inputstream互转【转文】
- 系统磁盘空间满的一个问题
- android样式文件,Android学习笔记样式资源文件
- Unity3d + UGUI 的多分辨率适配
- jfinal使用配置文件注意事情
- 华为 GaussDB 首席架构师 武新离职,出任易鲸捷CEO
- ParkingEE智能化停车服务平台
- QT5 Drilldown的柱状图
- android获取手机信息的权限,如何开启获取手机信息权限
- 通过调用接口查询ISBN的图书信息
- poi XWPFDocument 实现word中内容换行
- 安全框架-SpringSecurity