6.Shading(纹理映射、其他应用))
纹理映射
- 在物体的不同位置定义不同的属性,用来定义点的不同属性(例如漫反射系数)
- 把地球仪表面的“皮”,剪开平铺就是一个平面。
- 所以说任意三维物体的表面摊开就是二维平面。
纹理映射座标
- 在美术人员建模时,通常会在建模软件中利用纹理展开技术把纹理映射座标(texture-mapping coordinates)存储在每个顶点上。
- 纹理映射座标定义了该顶点在纹理中对应的2D座标,通常用(u,v)表示,u表示横向座标,v表示纵向,俗称UV座标。
- 纹理大小可以是多种多样的,可以使256x256或者1024x1024,但是顶点UV座标范围通常被归一化到
。
问题
已知三角形三个顶点的UV坐标,怎么获得三角形内部的某个像素点的UV坐标呢?
──插值
重心座标
为了在三角形内部对各个属性做插值,我们引入了重心坐标。
- 为什么要引入插值?
可以指定三角形内部任意顶点的值
在三角形上获得平滑的变化值
- 什么属性可以用以插值获得?
纹理、颜色、向量等属性
- 怎么做插值?
引入重心坐标
- 三角形所在的平面内的任意一个点(x,y)可以用αA+βB+γC来表示,A,B,C都为某个点。
- (α,β,γ)用来表示三角形的重心坐标,当满足α+β+γ=1时;表示该点(x,y)在三角形所在的平面内。
- 当 α,β,γ都>=0,时,该点一定在三角形内部。
- A点自己的重心坐标为(1,0,0)
- 重心点与三个顶点相连后获得三个三角形,Aa表示顶点A对面的(不相邻A点)的三角形。
- α=A顶点对面三角形Aa的面积/(三个三角形的面积)
特殊点:三角形重心
- (x,y)的重心坐标为(1/3,1/3,1/3),因为三个三角形的面积相等。
任何一个点的重心坐标通用公式
利用重心座标插值
- VA,VB,VC可以为各种属性,例如坐标,材质、颜色,深度等。
- 但是,在投影变换下,重心坐标不能保持不变。
- 所以如果要插值三维空间中的属性,我们应该取三维空间中的坐标(ABC),重心坐标V也是三维中的坐标,做完插值后再做投影变换。
把纹理应用到渲染中
- 对于每一个栅格化屏幕样本(通常是像素的中心点)
- 三角形任意点的纹理坐标(u,v)可以通过插值获得
- 获得纹理颜色=texture.sample(u,v)
- 就可以认为该纹理颜色为漫反射的系数Kd
纹理放大
- 上图展示的是低分辨率的纹理,放大后的效果,三图对应了三种不同的处理方法
- 对于平面上的任意一个点,我们可以获得其纹理上的对应位置,该位置不一定是整数,需要四舍五入,在一定范围内查找一个相同的纹理上的像素,叫做 texel,得到了第一图Nearest,因为一定范围内的像素都是同一个texel。
- 图二为双线性插值后的结果。
- Bicubic,取了16块像素,做插值计算,更高的计算量。
双线性插值
红点表示实际的屏幕像素位置,黑点表示缩放后的图像像素位置,我们发现实际像素位置与图像像素并不匹配,所以我们需要插值计算实际屏幕像素的颜色。
- 红点表示在纹理中映射的某一个点的位置
- 我们取离红点最近的4个像素
- 取红点距离左下角顶点
,宽和高分别是s和t(大小0~1之间) - 定义操作“线性插值
,x=0时,结果=v0,x=1时结果=v1,说明该线性插值是像一个滑动块,在v0和v1之间滑动,x=0.5时,结果=0.5v0+0.5v1
-
通过线性插值操作,对u1和u0的长度做线性插值操作,(水平方向)
-
同理竖直方向,高度做线性插值操作(竖直方向)
纹理缩小
- 纹理要是过大会引起更大的问题
- 如果我们按之前的做法,纹理坐标插值出任意一个点的坐标,把值写回像素。会得到图二。
- 远处有摩尔纹,近处有锯齿。
产生这种现象的原因:
- 近处的像素覆盖的纹理区域较少,而远处的一个像素覆盖了一大块的纹理。
- 不能通过插值某一个点来表示整块纹理的颜色。
怎么解决:
1.超采样,可行,但是资源消耗过多。
- 质量高,但成本高
- 高度缩小时,像素足迹中有许多纹素
- 像素中的信号频率太大
- 需要更高的采样频率
2.引入Mipmap
Mipmap
- 范围查询很快,但是不是很准
- 仅仅是近似的方形的范围查询

- 原图层级level0=128128大小
- level1为 纹理长宽都除以2,level1=6464,依次类推各个层级
- 我们从原图一直生成了一系列的图,而生成的图通过等比数列计算:
我们通过mipmap获得了一系列图的大小仅为原图的1/3
怎么做范围查询
- 图一为 屏幕像素坐标,蓝色点有一些邻居,红色点也有邻居。
- 图二为 纹理的坐标图
- 把图里中的像素点和其邻居,映射到纹理中去,得到图二。
- L取的是所测像素映射的纹理空间中的 相邻4个点中距离最大的那个值
- 在纹理空间中以L为边长的正方形被看做 屏幕像素坐标中1单位像素缩放后的结果
- 根据D=logx(L)去查询 mipmap的值。D表示mipmap的层级
- 简化流程:根据模型跟摄像机的距离,计算出不同层级的mipmap来告诉屏幕该怎么渲染

- 上图是我们使用mipmap的实际渲染效果
- 发现渲染有颜色上的断层,渐变的效果不连续
- 这是因为我们设置的mipmap层级都是整数的层级,在不同距离下会使用相同的整数层级mipmap
怎么查询mipmap1.8层的具体数据?
- 三次线性插值:两次查询,一次修正
- 再做一次线性插值!
- 要查询1.8层,我们可以获得第1层的数据,获得第2层的数据,分别对这两层做线性插值
- 然后对这两层的数据再做一次线性插值。
- 三次线性插值后的效果
mipmap的局限性

- 之前的图使用mipmap处理后,远处出现了模糊
- mipmap只能查询正方形方块
各向异性过滤
- mipmap相当于等比缩放,在上图中是对角线部分的图
- 各向异性过滤把不同长宽比的图像都存储下来,在不同缩放尺寸的快速查询效果会比mipmap更好
- 对于矩形的查询更优化,对于长和宽单独按比例缩放生成各层纹理图。
- 存储空间是原图的3倍,GPU,显存的压力增加了一些,计算量增加不多。
EWA过滤
- 任意不规则形状,拆成圆形,再查询。
- 查询计算量较大。
纹理的其他应用
凹凸贴图
例子:本来如果是想表现一个平滑的球体,2、3百个三角形就能拼出来,但是如果要表现一个凹凸不平的三角形,如上右图,如果使用模型拼出,就需要几何倍数的三角形了,这时候使用凹凸贴图就能很好解决这个问题。
- 通过人为的制造假的法线,通过纹理映射,获得了假的着色结果,可以让人觉得有凹凸的结果。
- (如上左图)凹凸贴图(法线贴图)两者意思一致。
凹凸贴图怎么实现?
- 下图中黑线表示原纹理贴图,黄线表示凹凸贴图
- p点表示原贴图的法线方向,n表示凹凸贴图的法线方向。
- 人为地改变了法线的方向,导致人眼看到要凹凸的感觉。
怎么求凹凸贴图的法线方向?
- 蓝色线为法线贴图表面
- 原始表面法线n(p)=(0,1)
- 对法线贴图点P处求导
- 法线与切线相互垂直,可得法线
导数定义
位移贴图

- 凹凸贴图是逻辑上的高度改变,而位移贴图则是物理上的高度改变(改变了顶点的位置),二者的区别就在此处,可以通过物体阴影的边缘发现这点。
- 要求模型的三角形足够细,三角形顶点的间隔能更得上纹理的高度变化(类似采样频率)
阴影贴图Shadow Mapping
拓展学习:转载自https://blog.csdn.net/xiaoge132/article/details/51458489
性质
- 如果一个点不在阴影里则,这个点必须同时满足被摄像机和光源观察。
- 这里主要研究的是点光源
点光源下的阴影

- 假如在点光源摆设一个摄像机,对场景做投影变换,即可获得一副图
- shadow mapping保存了点光源处对于物体的深度图

- 然后从摄像机视角投影出一幅深度图
- 对比点光源处的深度图和摄像机处的深度图
- 若两者的深度一致则是光照位置,若不一致则是阴影
注意:
- 光源投影出的阴影图分辨率会影响阴影的效果,类似采样频率过低(游戏中的阴影质量选项)
- 理论上只能适合于 硬阴影
三维噪音贴图+实体建模
- 定义一个三维空间中的噪声函数,来表现裂痕。
提供预先计算的阴影
- 左图为普通的shading着色。
- 中图为计算好的环境光遮蔽的纹理。
- 右图为左图乘以中图的结果。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 【.NET】调用本地 Deepseek 模型
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库