求知若饥,虚心若愚
纹理映射坐标会储存在顶点上(纹理(uv)展开是美术软件负责的),一般uv坐标会归一化到[0,1],但采样可以超过这个范围,纹理的平铺模式将决定如何处理超出采样范围的情况。不同图形API对于采样坐标系不一样,unity采用和OpenGL一样的左下角模式。
单张纹理
实践
1 | Shader "UnityShadersLearn/Chapter7/SimpleTexture" |
纹理的属性
-
Texture下复选框Alpha from Grayscale:透明通道的值由每个像素的灰度值计算
-
平铺模式Wrap Mode:Repeat(超出1的部分舍弃整数按小数继续采样)、Clamp(超出部分取最大值,负数取0)。
1
2
3//shader中还需要对纹理坐标变换
o.uv = v.texcoord.xy * _MainTex_ST.xy + _MainTex_ST.zw;
// o.uv = TRANSFORM_TEX(v.texcoord, _MainTex); -
滤波模式Filter Mode:纹理由于变换产生拉伸时怎么处理
通常纹理缩小更复杂,多个像素将会对于一个目标像素,以及需要处理抗锯齿。
mipmapping:多级渐远纹理,空间多了33%来节省远处物体的内存
- Point,采样像素通常只有一个,图像有种像素风格
- Bilinear,找到4个临近像素采样进行线性插值
- Trilinear,在Bilinear基础上在多级渐远纹理之间混合,如果不开启mipmapping则没有区别
-
最后使用POT纹理,即大小为2的幂,对内存占用和GPU读取速度都有帮助
凹凸映射
高度纹理
高度图存储的是强度值,用于表示模型表面局部的海拔高度。好处是很直观看到地形的高低,坏处是计算更加复杂,需要计算像素的灰度值来偏移表面法线。通常会和法线映射一起使用,用于给出表面凹凸的额外信息。
法线纹理
由于法线分量范围在[-1, 1],而像素分量范围在[0, 1],所以一般都会做如下映射:
所以在shader中采样需要逆映射回来正确的值(正常情况下,但有些用了压缩算法可能不一样)
- [ ]
模型空间的法线纹理 - [x] 切线空间的法线纹理
模型空间下更加直观,实现也简单,但使用切线空间可以将纹理应用到不同的网格上(记录的是相对法线),还可以进行UV动画(水或者火山熔岩),可压缩的(Z方向总是正方向可以通过XY推导)
模型顶点的切线空间。其中,原点对应了顶点坐标,x轴是切线方向(t),y轴是副切线方向(b),z轴是法线方向(n)
左图:模型空间下的法线纹理。右图:切线空间下的法线纹理
实践
在切线空间下计算
1 | Shader "UnityShadersLearn/Chapter7/Normal Map In Tangent Space" |
在世界空间下计算,尽管需要更多的计算,但在需要使用Cubemap进行环境映射等情况下,就需要用这种
1 | Shader "UnityShadersLearn/Chapter7/Normal Map In World Space" |
当使用UnpackNormal函数计算法线纹理中的法线方向时,需要把纹理类型标识为Normal map
当勾选了Create from Grayscale后,Unity会根据高度图来生成一张切线空间下的法线纹理
渐变纹理
使用渐变纹理可以控制漫反射光照的结果。1998年Gooch等人发表了一篇论文《A Non-Photorealistic Lighting Model For Automatic Technical Illustration》中最初提到这个技术,在这篇论文中,作者提出了一种基于冷到暖色调的着色技术,用来得到一种插画风格的渲染效果。使用这种技术,可以保证物体的轮廓线相比于之前的传统漫反射更加明显,而且能提供各种色调变化。现在很多卡通风格的渲染都使用了这种技术。
使用不同的渐变纹理控制漫反射光照,左下角给出了每张图使用的渐变纹理
1 | Shader "UnityShadersLearn/Chapter7/RampTexture" |
Wrap Mode分别为Repeat和Clamp模式的效果对比,这是由于浮点数精度原因,可能取到1.00001,就映射到头部颜色了。
遮罩纹理
- 遮罩运行我们可以保护某些区域,使它们免于某些修改
- 使模型表面某些区域的反光强烈一些,某些区域弱一些,来获得更细腻的效果
- 制作地形材质使需要混合多张图片,控制如何混合这些图片
- 原理是某个通道×某种表面属性值后,如果为0则保护表面不受这种属性的影响
1 | Shader "UnityShadersLearn/Chapter7/Mask Texture" |