图形1.3纹理
纹理
纹理–贴图
一种可供着色器读写的结构化存储形式
- 纹理的出现
- 牺牲几何细节
- 降低建模工作量
- 减少储存空间
- 增加读取速度
- (使用图像数据源来修正或模拟物体表面)
- 牺牲几何细节
纹理管线
模型空间位置-(投影函数-纹理映射)-纹理坐标(UV)-通讯函数-新纹理坐标-纹理采样(避免依赖纹理读取)-纹理值
投影函数
- uv值的计算,就是texture mapping的投影方式(展UV)
- 特殊情况
- 环境贴图的采样
通讯函数
- 对纹理坐标进行扩展。例如平移、缩放、旋转或控制图像的应用方式
依赖纹理读取
有两个定义。其一是移动设备上,当PS中手动计算了纹理坐标而不是用VS中传入的值时会变成依赖纹理读取,在老的移动GPU(不支持GLES3.0)上,没有依赖纹理读取的shader会跑的更高效,因为纹素数据可以被提前获取。另一个定义则更早,在早期的桌面GPU上,当一个纹理的坐标基于另一个纹理的结果时。例如用法线贴图中获取的法线来访问一张立方体贴图,这样的功能是受限制的,如今虽可以使用但是也是有一定的性能影响的。
纹理采样设置
Warp Mode
- 决定UV在[0,1]之外的表现形式
- Repeat,Mirror,Clamp,Border
- GL-Warpping Model包装模式
- DX-Texture Addressing Mode纹理寻址模式
Filter Mode
- 最近邻Nearest
顾名思义,就是找到最接近的像素颜色
- 双线性插值Bilinear
- 双三次插值Bicubic(立方卷积)
取周围临近16个像素——除了周围四个直接相邻像素点的影响,同时考虑临近像素的变化率的影响
- 兰索斯插值
取64个像素
- Quilez光滑曲线插值
2x2纹理组,使用smoothstep和quintic曲线
用这两种曲线对纹理坐标进行处理后进行双线性插值
但是我怀疑是否是用曲线插值直接代替线性插值
Texture Magnification/Minification
其实对于纹理放大对应的还有纹理缩小,但是本质是一样的,都是纹理像素和屏幕对纹理采样的频率差别太大导致的。

纹理太大,会出现颜色丢失与闪烁、摩尔纹
纹理太小,则出现走样
解决方法
- Supersampling(点查询)
- 消耗大
- Mipmap(范围查询:快速、==近似、方形范围==)
- 消耗的内存比原先多1/3
- Supersampling(点查询)

假如L是4个像素,那么D=2,也就是说,在第2层的mipmap上,这个区域会对应一个像素
- mip之间的过渡——场景中的mip层级是不连续的
- Trilinear interpolation

- Mipmap的限制
- Overblur

屏幕映射到纹理上的形状并不是标准的正方形

- 解决方法:各向异性过滤Anisotropic Filtering
- Ripmaps
- 对于矩形的查询有更好的结果
- 但是对于倾斜的形状仍然无法解决

- EWA filtering
- 多次查询会更消耗
- Summed-Area Table积分图

- Unity/Ue4中的各向异性过滤
- 并不总是使用Ripmap
- 重用已有的Mipmap,屏幕像素反向投影到纹理空间,通过覆盖方块==最短边==来确定level
- 较长的边创建一条各向异性线,按照过滤等级沿着这条线多次采样并合成。(过滤等级越高,采样次数越多,消耗越大)
优化与纹理应用
优化
- CPU优化——降低DrawCall——减少命令缓冲区的命令

纹理图集、纹理数组、无约束纹理——避免渲染时频繁改变纹理带来的消耗
- 纹理图集
- 把若干小纹理合并成大纹理

- GPU渲染优化——纹理压缩
- 减少资源在CPU中解压缩的过程
- 减小包体,减轻数量级、带宽计算压力
- 提高内存使用效率
其他应用
- CubeMap立方体贴图
- 使用从原点出发的方向向量进行采样

- Bump Mapping凹凸贴图
- 不增加顶点的情况下改变几何表面法线
- Displacement Mapping位移/置换贴图
- 曲面细分、对顶点进行位置移动
- Environment Lighting
- Store microgeometry
- Procedural textures
- Solid modeling
- Volume rendering
- 。。。
参考资料
[1]https://www.bilibili.com/video/BV1sA411N7z3 【技术美术百人计划】图形 1.3 纹理的秘密
[2]https://www.bilibili.com/video/BV1X7411F744 GAMES101-现代计算机图形学入门-闫令琪