原文:Krita tutorial: how to create a normal map and displacement, height maps etc.
在这个教程里(需要krita 4.4.8以上版本),我们将看到如何从一张照片创建displacement(置换贴图)、height(高度图)、normal(法线贴图)、roughness(粗糙度)、specular maps(高光贴图)。这些贴图在3d渲染中起着重要的作用,比如表示物体表面形变(置换图),或近似模拟物体表面细节(高度图、法线图),或者精确表示那些表面反射光、那些不反射(高光图、粗糙图)。
要注意的是,有时这些贴图之间的界限很模糊,比如高度图在一些shader中也被当成置换贴图来用,因为灰度数据同样能用来实时表示物体表面mesh的变化;另一方面,置换贴图也能被定义为高度图,比如地形、山脉。而且,在一些缺失法线信息的场合,高度图还能被当做bump map(凹凸贴图)以替代法线贴图。
这里将用来计算置换的叫做置换贴图,用来表示凹凸的叫做高度图,且不要和法线贴图混淆。
This is the first of a series of tutorials that will show us how to transform a photo into a set of maps to use with the Blender program to create a more or less realistic wall, equipped with writings, coli, molds, ivy and all that makes a wall seem more "lived in".
让我们从Krita中打开一张墙面照片开始,对于还不熟悉Krita这个软件的可先阅读相关文档:
https://www.graphicsandprogramming.net/eng/tutorial/krita/krita-basic-guide/krita-tutorial-introduction,把对应的图层命名为“diffuse”(diffuse有时也被叫做albedo、color,是一种用来表示漫反射的贴图,且不含高光反射效果,可以理解为物体表面不含任何光照的颜色)
为了能重用这张图,通过“Ctrl+J”复制图层,并命名为diffuse base
这里我们用了一张原始照片,但是良好的diffuse图是不应该包含任何阴影、光亮、背光区域的(会影响其他贴图效果),最好能提前处理掉。
什么是displacement map:
displacement map是一种灰度贴图(一般由8位字节表示,对应256个灰度,也有用16、32位来表示更多细节的情况),其中间值(不含任何偏移信息)为gray(16进制:#808080),最深的值为黑、最浅的值为白,大部分shader将这个值和高度对应。
在3d建模软件中,置换贴图被用来实时修改模型表面形状,通常配合高度图、法线图来获得立体效果。我们这里将砖面顶部定义为纯白色,混凝土部分定义为纯黑色,且还需要在图片中将砖面、混凝土分出来方便进一步处理。
在Krita中生成displacement map:
使用“Contiguous Selection Tool”这个工具能够依据颜色进行扩选、或剔除
同时在“Tool Options”面板中将“Fuzziness”值设为23
这样就能将混凝土部分单独选中
然而砖块下阴影部分中的混凝土没有被选中
那么就将“Fuzziness”值设为13,限制颜色模拟范围,同时按住“SHIFT”键(扩选),耐心的将处在阴影中的混凝土一个个选中。如果期间不小心选中的砖块,再按住“ALT”键,减选对应部分。
保持“SHIFT”键不放,还能通过其他工具,如框选、手动选择,来加快操作。
为了改善选择效果,还能使用笔刷;事实上,如果观察图层,会发现此时已经自动创建了一个图层,其对应着当前的选择。
这时如果选择图层,为选中部分会被红色显示出来,可以用笔刷(如Basic-1、Airbrush_Soft,白色、100%不透明)或橡皮擦,来绘制选择区域。
通过右键选中区域,并选择“Transform > Smooth”,平滑选择区域
就能获得
砖块的边缘应当由稍许模糊,右键选中区域“Transform > Feather Selection”,“Feather Radius”设置为2(也可以通过“Shrink”、“Grow”来调节选区)
一番操作下来就能清晰的看到砖块选区
和“Selection Mask”图层相对应
这样就能单独处理砖块、混凝土部分
但是我们需要先对“diffuse base”图层去色:先影藏selection mask图层
选择“diffuse base”图层,再通过面板下方+号边的下拉框,为其添加一个“Filter Layer”图层
在弹出面板选择“Adjust > Desaturate”滤镜,并选择“Average”选项(图像生效前都必须保持选中状态)
确认、应用
复制“Selection Mask”,并点击眼睛图标,使其可见
再次通过面板下方+号旁的下拉列表
创建一个“Paint Layer”,命名为“Dark Mortar”(快捷键F2重命名),将复制的Selection Mask拖动到这个层
选择“Dark Mortar”层,选择填充工具(位于左侧面板,快捷键“F”)
选择黑色
填充整个图层
选择“Copy of Selection Mask”层,右键菜单“Convert > To Transparency Mask”,将其转换为半透明遮罩
半透明遮罩使黑色图层只影响混凝土部分,而不影响砖块
我们给“Dark Mortar”设为80%,使得混凝土部分隐约可见
然后选择“Dark Mortar”以及关联的“Transparency Mask 1”,“CTRL+J”复制,并命名为“Light Bricks”,和“Transparency Mask 2”
选择“Transparency Mask 2”,“CTRL+I”反选;这样就能隐去混凝土、显示砖块部分。然后将整个“Light Bricks”图层填充白色,并设置不透明为60%,以便将砖块部分凸现出来。
这样就获得了displacement map置换贴图
那么现在就必须要对图像做模糊操作,因为置换贴图中的颜色边缘过于锐利,会导致凸出部分呈现90度锐角,会拉升diffuse贴图,此时就需要对图像进行软化。这里也并不需要担心丢失细节,因为置换贴图的目的只是表达砖块的形状,细节将由bump map进一步呈现。
添加一个滤镜图层“Blur > Gaussian Blur”,并将Horizontal radius、Vertical Radius设置为大约20px
获得这样一个置换贴图
然后导出“File > Export”,为“displacement_map.jpg”,再到其他3d建模软件中查看结果(这里我们用blender,加displace修改器)
保存文件“File > Save As”,“displacement_map.kra”
什么是Bump Map:
现在我们将创建高度图、法线图,这两者也被认为是bump maps(凹凸贴图)。在3d建模、渲染软件中,这两者提供物体表面细节,虽然他们不生成立体模型,但通过光照、阴影来表现立体效果;这样就能让你的模型用更少的面表现更多的细节,尤其是在电子游戏中。由于这些细节其实是假象,所以模型本身精度并不受到dump map影响。
什么是height map:
就像上面所提,heightmap和displacement在文件格式上很相似,但在图形学上不同,前者有更多的细节,对物体描述更精确。
它们同样被保存为8位、256色灰度图,从黑到白,表示物体表面每个像素的具体深度,白色表示凸、黑色表示凹,灰色取中间。
在3d环境中,高度图对灯光、阴影影响很大,所以你需要小心使用,必要时配合高光图(specular map)来解决shader上的问题。
和置换图不同,高度图有更多的细节,且不能被当做置换图来形变物体,所以混凝土、砖块的灰度值差距不能像之前那样大。
在Krita中创建高度图:
继续打开之前创建的displacement map,删除“Filter Layer 1 (Gaussian Blur)”,将“Dark Mortar”层不透明值设到40%
将“Light Bricks”层不透明值设到25%
那么就得到Height map
导出“height_map.jpg”
并保存文件“File > Save As”,为“height_map.kra”
什么是normal map:
就像之前凹凸贴图、高度图那样,法线贴图是一种小、而密集的凹凸贴图,如物体表的凹槽、抓痕、空洞等的细节。它实际上是一种图,不影响物体几何形状,但影响光照表现,以此达到节省物体多边形数量的目的。
在3d环境中物体由各个表面组成,每个表面各个点的矢量夹角来表示法线,进而参与物体表面的光照计算。相对于物体本身的真实形状(下图黑色部分),法线贴图为物体表面提供一层虚拟的扰动信息(下图蓝色部分)。
法线贴图是一种RGB(三色)贴图,每个像素表示其对应真实表面法线的相对面向。数学上,物体表面每一个点的切平面(事实上又叫“tangent space normal map”),由垂直该点的矢量构成。贴图就是有每个像素所代表的单位矢量,用RGB三分量代替矢量x、y、z,所组成。每个颜色代表不同的相对方向。在右手坐标系中,只表示面向外边的矢量,则有:
X:-1到+1、Red对应为0到255
Y:-1到+1、Green对应为0到255
Z:0到-1、Blue对应为128到255(右手系、z值向内)
那么用rgb表示的矢量图主要呈现蓝紫色(blue-violet predominance)。
一个normal map的矢量默认值(0、0、-1)被映射为(128、128、255)。这个颜色表示面向观察者,呈现亮蓝色,表示对应的表面没有任何形变。这个颜色通常占据normal map大部分区域。
在Krita创建normal map:
新建Krita文件,加载墙面照片,命名“diffuse”
图层面板+号旁下拉列表添加滤镜图层,选择“Edge Detection > Height to Normal Map”弹出窗口
在这里能看到几个选项:
- 三个不同的方法:Prewitt(生成较强的效果)、Sobel(更微弱的效果)、Simple(快速计算)。这里选择Sobel,因为并不需要太锐化的形状
- 用以计算高度的channel。我们这里用Blue,因为这里用来表示砖块裂痕已经足够,最好测试各个channel,选择最合适的
- 我们也没有改变水平、垂直半径的值,增加这些值会加强立体表现
- 特别要注意的是三个轴向的选择,默认X+、Y+、Z+,然后按OK生成
保存文件“normal_map.kra”、导出“normal_map.jpg”到blender查看效果,然而,这里看到混凝土比砖块更突出
右键选择刚才创建的滤镜层、或F3,选择“Properties”
修改Y轴朝向,使得X+、Y-、Z+组合
得到法线贴图
在blender中再次验证,发现表现更合理了
保存文件“normal_map.kra”、导出“normal_map.jpg”
什么是Roughness Map:
物体表面各个位置并非一样,有些光滑、有些粗糙,有些甚至是很多细小物件紧密组成。光线照射到表面不同粗糙位置,会产生不同反射效果。Roughness map也是灰度图,用以控制物体表面的反射形状,例如是硬表面、还是漫反射(这里漫反射表示模糊、粗糙的表面)
在一些你可以下载贴图网站,有时用“Gloss”代替“Roughness”,实质是一样的,只是将贴图值取反。
在Krita中创建roughness map:
就我们这个例子,墙面的混凝土部分很明显是粗糙的,同样砖块也不是新的、还有损坏,墙上的尘土同样会增加粗糙效果。
加载“displacement_map.kra”,删除“Filter Layer 1 (Gaussian Blur)”
为了获得高的粗糙度,就需要同时调高混凝土、砖块的亮度。所以将“Light Bricks”不透明调到58%,“Dark Motra”不透明调到0%,得到如下
另存文件“roughness_map.kra”,导出“roughness_map.jpg”
什么是Specular map:
在计算机图形学实时渲染中,用以确定高光反射强度,可节省场景内光照运算,或特殊场合下强制表面反射(例如刚拿出冰箱的饮料,起雾、且还有冷凝水流)。有光泽的表面用白色表示、平淡的用黑色表示,还能用来增强一些强调区域(如在昏暗灯光下,一些看不到的东西)
高光贴图一般用来表示那些需要反射、那些不需要,在PBR材质中表现并不真实(这种场合建议用Roughness替代)。
使用Krita生成specular map:
在我们这个例子中,没有需要特别反射的区域,所以并不需要生成reflection map。但这个贴图可以用在表现潮湿的墙面,这种情况下砖块比混凝土反射更多,整个墙面使用统一的高光是不合适的,需要对混凝土、砖块进行区分。
打开“height_map.kra”
如果你希望砖块反射更多,那么调高“Dark Mortar”不透明度为53%
同时添加一个“Levels”滤镜,“Filter Layer > Adjust > Levels”,添加一些差异,调整滑块Shadows value为16,midtones为0.506
再添加一个滤镜层“Adjust > HSV/HSL Adjustment”,“Lightness”设为-45,少许软化反射
保存“specular_map.kra”,导出“spcular_map.jpg”。
下载示例中的资源:
https://www.graphicsandprogramming.net/prjfiles/diffuse_map.jpg
https://www.graphicsandprogramming.net/prjfiles/displacement_map.jpg
https://www.graphicsandprogramming.net/prjfiles/height_map.jpg
https://www.graphicsandprogramming.net/prjfiles/normal_map.jpg
https://www.graphicsandprogramming.net/prjfiles/roughness_map.jpg
https://www.graphicsandprogramming.net/prjfiles/specular_map.jpg