1.纹理采样 2.采样器 1.纹理采样 采样就是GPU为了给屏幕上的一个像素上色, 去纹理贴图里"查取并计算对应颜色 / 数据" 的操作, 一次查取+ 计算就是一次 采样, 多张纹理就是多次采样a. 纹理贴图 给3D 模型贴的图( 漫反射、法线、高光图) , 本质是一张存满颜色/ 数据的像素格图片, 比如一张1024 ×1024 的木纹图, 就是1024 ×1024 个小格子, 每个格子有自己的颜色值, 这张图存在"GPU显存(仓库)里" b. UV坐标 给3D 模型表面的每个点都标了一个"纹理贴图的地址" , 比如UV ( 0.5 , 0.5 ) , 就是纹理贴图正中间的那个像素格, 相当于模型表 面的点和纹理贴图的像素格做了一一绑定 c. 屏幕像素 游戏画面最终显示在屏幕上的一个个小点, 比如1080P屏幕就是1920 ×1080 个点, GPU的核心工作之一, 就是给每一个屏幕像 素算出最终要显示的颜色1 ) . 采样的完整流程 假设现在要渲染屏幕上的一个像素( 比如立方体表面的一个屏幕点) , GPU要给它上色, 这个上色查数据的过程就是一次采样, 全 程对应工人取货 a. 接任务: GPU拿到这个屏幕像素, 通过3D 模型的计算, 得到这个像素对应的模型表面点的UV坐标, 比如UV ( 0.5 , 0.5 ) , 相当 于工人拿到了"去仓库取货的具体地址" b. 去仓库取货( 显存读取) : GPU根据UV坐标, 去显存( 仓库) 里找到对应的纹理贴图, 定位到该UV坐标对应的纹理像素格相当于 工人跑到仓库, 按地址找到对应的货物货架 c. 验货/ 加工( 插值计算) - 理想情况: UV坐标刚好精准对应纹理的一个像素格, 直接取这个格子的颜色就行( 工人直接拿货架上的货) - 实际情况: 模型缩放/ 旋转/ 拉伸后, UV会变形, 一个屏幕像素可能对应纹理的多个像素格, 或多个屏幕像素对应纹理的一 个像素格( 比如把小纹理贴到大模型上, 纹理被拉伸) , 这时GPU会做插值计算, 比如取周围几个纹理像素格的颜色平均值, 得 到一个"平滑的颜色值" , 相当于工人发现货架上的货不匹配, 需要把几个货拼一拼/ 加工一下, 才能得到能用的成品 d. 完成任务: GPU把计算好的颜色值赋值给这个屏幕像素 —— 工人把加工好的货送到车间( GPU计算单元) , 完成一次取货多次采样的例子 如果这个屏幕像素不仅要漫反射颜色, 还要法线信息, 高光信息, 就需要3 张纹理贴图( 漫反射图、法线图、高光图) , 此时GPU 要给这个像素上色, 就要按同一个UV坐标, 分别去3 张纹理里各做一次"查取 + 计算" 相当于工人为了完成一个"上色任务" , 要 跑3 次仓库, 取3 次货, 做3 次加工, 自然比跑1 次的开销大得多 而屏幕上有几十万甚至上百万个像素, 每个像素都要做多次这样的操作, GPU的"工人" 就会不停跑仓库, 显存带宽( 仓库到车间 的运输通道) 就会被占满, 这就是采样次数多导致开销高的核心原因2.采样器 采样器( Sampler) 是GPU中专门负责执行"纹理采样操作的专用硬件单元 + 规则配置器" , 对应之前的仓库比喻, 采样器就是仓 库专属的取货工人+ 加工台, 这个工人只干"按UV取纹理数据 + 按规则插值/处理" 这一件事1 ) . 采样器的两个作用 采样器不只是"无脑干活的工人" , 还能按开发者设定的规则执行采样, 这两个作用缺一不可且后者是Unity/ Shader开发中我 们能实际配置的部分 a. 硬件层面: 专属执行采样的核心操作, 全程负责纹理采样的两大核心步骤, 替GPU通用单元省算力- 按Shader传入的UV坐标, 从GPU显存中精准定位纹理贴图的对应数据, 完成显存带宽的高效读取( 专用的读取通道) - 对读取到的纹理数据执行插值/ 过滤计算, 得到最终要传给片元着色器的颜色/ 数据 b. 配置层面: 定义采样的"行为规则" 我们在Unity/ Shader中设置的纹理过滤方式、寻址模式, 本质都是给采样器配置执行规则相当于给"取货工人" 定好怎么取, 怎 么加工的规矩, 工人会严格按规矩干活, 不同规矩对应不同的画面效果和开销 这也是采样器配置器属性的体现, Unity Shader中我们定义的sampler2D, 其实就是纹理贴图+ 绑定的采样器的组合体, 早期 GPU纹理和采样器是分开的, 现在为了开发便捷合二为一, 比如sampler2D _MainTex, 就是把主纹理和对应的采样器绑定, 我 们在Inspector面板给纹理设置的过滤/ 寻址模式, 最终都会传给这个采样器2 ) . 采样器的2 个核心配置规则 这两个规则是采样器的核心, 直接决定采样的画面效果和轻微开销差异, 也是Unity中给纹理设置的关键参数, 用之前的类比 讲就是"工人的操作规矩" a. 过滤模式( Filter Mode) : 工人怎么加工纹理数据, 插值规则 解决的是屏幕像素 UV 和纹理像素不精准匹配的问题, 比如纹理被拉伸/ 缩小, 采样器按此规则做插值计算分三种核心类型- Point ( 点过滤) : 工人直接取UV最近的那个纹理像素, 不做任何插值, 画面会出现像素化, 锯齿, 但开销最低- Linear ( 线性过滤) : 工人取UV周围4 个纹理像素, 计算平均值作为结果, 画面平滑、无锯齿, 开销比Point略高, 是Unity默认 的模式, 适合绝大多数场景( 漫反射、法线图等) - Trilinear ( 三线性过滤) : 在Linear基础上, 对纹理的多级LOD ( 纹理金字塔) 也做线性插值 b. 寻址模式( Wrap Mode) : 工人UV 超出纹理范围时怎么处理( 边界规则) 纹理的UV坐标默认范围是0 - 1 , 如果Shader中计算的UV超出这个范围( 比如UV= 1.5 ) , 采样器按此规则处理, 核心类型- Repeat ( 重复) : 工人把纹理平铺重复, UV= 1.5 就取纹理0.5 的位置 —— 适合地板、砖墙等需要平铺的纹理, 直接把这张箭头 纸一张张一模一样叠着贴- Clamp ( 夹紧) : 工人把超出的UV限制在0 或1 , 超出部分直接取纹理的边缘像素 —— 适合人物贴图、LOGO 等不需要平铺的纹 理, 避免边缘出现拼接瑕疵- Mirror ( 镜像) : 工人把超出的UV做镜像翻转, UV= 1.5 取0.5 的镜像位置, 贴完第一张( 箭头右) , 把纸翻个面( 左右翻转) , 再 贴第二张( 箭头左) , 第三张再翻回来( 箭头右)