Shading 着色3
1076 字
5 分钟
Shading 着色3

Barycentric Coordinates 重心坐标
在一个二维三角形ABC内,某点满足:
其中,则称为该点的重心坐标
- 当时,则在三角形内部
- 三角形重心的重心坐标:
重心坐标插值
设中点各自有属性,则三角形内某一点的属性:
其中,则称为该点的重心坐标
由于重心坐标不能保证投影后坐标不变,因此理论上重心坐标的插值必须在3维空间中插值。
但实际上,在投影后的2维三角形上进行重心坐标插值有许多好处
GPU 在光栅化阶段主要需要回答两个问题:
- 屏幕上的某个像素采样点是否位于三角形内? => 重心坐标可解
- 如果位于内部,应该如何插值该点的深度、颜色、纹理坐标等属性?
实际上,我们一样可以在2维进行重心坐标插值,只需要对2维的重心坐标作一个修正,就可以还原为3维的重心坐标。
这就是透视正确插值
透视正确插值
设屏幕空间计算出的重心坐标为:
三个顶点在透视投影后的齐次坐标的分量分别为
则对应的透视修正为:
这就是修正后的重心坐标,对应的就是三维空间中真正的重心坐标
纹理
- 纹理上某个点的即是将像素的颜色设为对应纹理坐标的颜色
- texel 纹理上的像素
纹理过小
- 导致一个texel映射到多个pixel
- 解决方案:双线性插值
双线性插值
纹理过大
- 本质:屏幕像素相对于纹理的采样频率太低
会导致“走样”问题 解决方案:
- 抗锯齿(MSAA、DLSS)
- MipMap
MipMap
- 做范围查询
- 先预生成不同分辨率图,在像素映射纹素时查询。
- 生成MipMap时会不断像素除以2来获得新的像素图,直到不能再分。MipMap会分级,原先的纹理即为第0级 求MipMap Level D:
举例:假设1个像素映射到4个纹素,这时候应该在级的更粗糙的纹理图上找对应的像素(这个纹理图上的一个像素由上一级的相邻4个像素平均合并而成)
三线性插值
问题:当需要查询MipMap1.8层对应的纹素时,该怎么办?
解决:先在上下夹着的两层分别作双线性插值,再在层与层之间作一次线性插值
其他过滤方法
- RipMap 各向异性过滤:水平和竖直都分别压缩
- EWA Filtering
纹理的应用
纹理的本质:内存+对内存作各种形式的区域查询
纹理不只可以存颜色,还可以存高度,存法线等等信息
环境光贴图
只记录光源方向,没有光源位置信息
- 球贴图:环境光记录到球上,使用时展开球面
存在两极的扭曲问题
- 立方体贴图:将环境光记录到立方体上,便于展开
TBN矩阵
将世界空间变换到切线空间
设分别为世界坐标下法线、切线和副切线向量:
Bump map 凹凸贴图
通过修改法线来影响着色,通过纹理定义点相对高度的移动,对模型法线作一个扰动
计算(三维):
- 原有的表面法线
- 计算两个切向量:
- 新的法线为,然后归一化
需要将世界空间变换到切线空间
Displacement map 位移贴图
不同于凹凸贴图,位移贴图会真正改变模型的顶点位置
- 要求:模型相对于贴图要足够细致(不然就会“走样”)
其他应用
- 预计算环境光纹理
- 体渲染
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!









