视频加载失败

Shading 着色3

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

Barycentric Coordinates 重心坐标#

在一个二维三角形ABC内,某点(x,y)(x,y)满足:

αA+βB+γC=(x,y) \alpha A+\beta B +\gamma C = (x,y)

其中α+β+γ=1\alpha + \beta + \gamma = 1,则称(α,β,γ)(\alpha,\beta,\gamma)为该点的重心坐标

  • 当α,β,γ≥0\alpha , \beta , \gamma \geq 0时,则(x,y)(x,y)在三角形内部
  • 三角形重心的重心坐标:(1/3,1/3,1/3)(1/3,1/3,1/3)

重心坐标插值#

设△ABC\triangle{ABC}中A,B,CA,B,C点各自有属性V1,V2,V3V_1,V_2,V_3,则三角形内某一点的属性:

V=αV1+βV2+γV3 V = \alpha V_1 +\beta V_2 +\gamma V_3

其中α+β+γ=1\alpha + \beta + \gamma = 1,则称(α,β,γ)(\alpha,\beta,\gamma)为该点的重心坐标
由于重心坐标不能保证投影后坐标不变,因此理论上重心坐标的插值必须在3维空间中插值。 但实际上,在投影后的2维三角形上进行重心坐标插值有许多好处

GPU 在光栅化阶段主要需要回答两个问题:

  1. 屏幕上的某个像素采样点是否位于三角形内? => 重心坐标可解
  2. 如果位于内部,应该如何插值该点的深度、颜色、纹理坐标等属性?

实际上,我们一样可以在2维进行重心坐标插值,只需要对2维的重心坐标作一个修正,就可以还原为3维的重心坐标。
这就是透视正确插值

透视正确插值#

设屏幕空间计算出的重心坐标为:

(λA,λB,λC) (\lambda_A,\lambda_B,\lambda_C)

三个顶点在透视投影后的齐次坐标的ww分量分别为

wA,wB,wC w_A,w_B,w_C

则对应的透视修正为:

βi=λi/wiλA/wA+λB/wB+λC/wC \beta_i = \frac{\lambda_i/w_i}{\lambda_A/w_A+\lambda_B/w_B+\lambda_C/w_C}

这就是修正后的重心坐标,对应的就是三维空间中真正的重心坐标

纹理#

  • 纹理上某个点的(u,v)(u,v)即是将像素的颜色设为对应纹理坐标的颜色
  • texel 纹理上的像素

纹理过小#

  • 导致一个texel映射到多个pixel
  • 解决方案:双线性插值

双线性插值#

纹理过大#

  • 本质:屏幕像素相对于纹理的采样频率太低

    会导致“走样”问题 解决方案:

  1. 抗锯齿(MSAA、DLSS)
  2. MipMap

MipMap#

  • 做范围查询
  • 先预生成不同分辨率图,在像素映射纹素时查询。
  • 生成MipMap时会不断像素除以2来获得新的像素图,直到不能再分。MipMap会分级,原先的纹理即为第0级 求MipMap Level D:
L=max((dudx)2+(dvdx)2,(dudy)2+(dvdy)2) L = max(\sqrt{(\frac{du}{dx})^2+(\frac{dv}{dx})^2},\sqrt{(\frac{du}{dy})^2+(\frac{dv}{dy})^2})D=log⁡2L D = \log_{2}L

举例:假设1个像素映射到4个纹素,这时候应该在D=2D=2级的更粗糙的纹理图上找对应的像素(这个纹理图上的一个像素由上一级的相邻4个像素平均合并而成)

三线性插值#

问题:当需要查询MipMap1.8层对应的纹素时,该怎么办?
解决:先在上下夹着的两层分别作双线性插值,再在层与层之间作一次线性插值

其他过滤方法#

  • RipMap 各向异性过滤:水平和竖直都分别压缩
  • EWA Filtering

纹理的应用#

纹理的本质:内存+对内存作各种形式的区域查询
纹理不只可以存颜色,还可以存高度,存法线等等信息

环境光贴图#

只记录光源方向,没有光源位置信息

  1. 球贴图:环境光记录到球上,使用时展开球面

存在两极的扭曲问题

  1. 立方体贴图:将环境光记录到立方体上,便于展开

TBN矩阵#

将世界空间变换到切线空间
设T B NT\space B\space N分别为世界坐标下法线、切线和副切线向量:

TBN=[TxBxNxTyByNyTzBzNz] TBN = \begin{bmatrix} T_x & B_x & N_x \\ T_y & B_y & N_y \\ T_z & B_z & N_z \end{bmatrix}TBN−1=TBNT TBN^{-1} = TBN^T

Bump map 凹凸贴图#

通过修改法线来影响着色,通过纹理定义点相对高度的移动,对模型法线作一个扰动
计算(三维):

  1. 原有的表面法线n(p)=(0,0,1)n(p) = (0,0,1)
  2. 计算两个切向量:
dp/du=c1[h(u+1)−h(u)] dp/du = c_1[h(u+1)-h(u)]dp/dv=c2[h(v+1)−h(v)] dp/dv = c_2[h(v+1)-h(v)]
  1. 新的法线为(−dp/du,−dp/dv,1)(-dp/du,-dp/dv,1),然后归一化

需要将世界空间变换到切线空间

Displacement map 位移贴图#

不同于凹凸贴图,位移贴图会真正改变模型的顶点位置

  • 要求:模型相对于贴图要足够细致(不然就会“走样”)

其他应用#

  1. 预计算环境光纹理
  2. 体渲染

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

Profile Image of the Author
机巧叶片
给互联网留下一点微小的贡献
公告
欢迎来到我的博客!这是一则示例公告。
分类
标签
最新动态
站点统计
文章
26
分类
6
标签
22
总字数
27,977
运行时长
0 天
最后活动
0 天前
站点信息
构建平台
Cloudflare Pages
博客版本
Firefly v6.16.8
文章许可
CC BY-NC-SA 4.0
文章目录