雅克比矩阵微分与纹理映射

2021.12.13
昨天跟一个哥们聊天讲到面试图形学过程当中有人问到什么是雅克比矩阵微分;上网查了一下,雅克比矩阵微分是在微分场景下找到两个微分空间基底的线性变换矩阵。
 
 
【切空间就能够其理解为微分空间】
切空间都是矢量空间,都有基底,因此这个线性变换就是矩阵。在欧氏空间子空间的开集上,切空间就是某个。
因此把Jacobian矩阵当作切空间之间的基底之间的线性变换,
而矩阵的行列式的值的几何意义:是矩阵对应的线性变换先后的面积比。
这也是为何积分中变换坐标时前面会乘以一个Jacobian矩阵的行列式。
 
下面举了个例子,对于机械臂来讲若是每次都用xy的直角坐标来表示整个过程位置比较麻烦,因此采用角度和臂长来表示比较容易。同时又知道二者之间转化关系。那么咱们问每次两个角速度变化时,xy的变化速度是多少?这时候就能够利用雅克比矩阵来计算每次角速度变化对xy的变化速率是多少。也便是由角速度的微分空间变换到了直角坐标系的微分空间。
 
 
雅克比行列式在图形学中的纹理映射中也有用到。参考文章: https://zhuanlan.zhihu.com/p/268618021
纹理映射一个须要处理的问题是纹理的抗锯齿问题。
 
好比上图将纹理贴到一个平面,当随着观察角度不一样,会出现纹理的锯齿现象。解决方案是使每一个像素不是点样本,而是使用当前屏幕2d像素计算出覆盖的纹理空间图像面积中全部像素的平均值
那么怎么计算一个像素覆盖多少纹理空间的面积?
一个像素所对应的纹理范围称为像素的纹理空间覆盖区,要计算这个覆盖区是挺复杂的一个事情,由于这个物体的表面有很大关系,表面多是一个曲面。并且随着观察角度和位置不一样,同一个屏幕像素的纹理空间覆盖区是不同的。
 
上图总能够看到屏幕像素对应纹理空间不是一个矩形,而是不一样的四边形,可能仍是有曲率的。要计算这个曲面的覆盖像素比较麻烦。
那么这里计算这个覆盖区,即利用微分思想作一些近似。
下面有些绕,咱们能够把屏幕的像素想象成一个微分单元,这个微分单元实际上对应咱们渲染物体表面的一个点,这个点会对应一个纹理坐标。这里要注意,虽然纹理坐标咱们是在直角坐标系下定义的,但实际上纹理空间并不必定是一个直角空间,可想象一个图片贴到一个曲面上,确定是弯曲的,因此下图中纹素的真正走向实际上是弯曲的线。因此从一个屏幕空间到一个纹素空间也不是线性的。好比看下图
 
可是当对于屏幕像素这个极小的微分单元下咱们能够认为是线性的。这个映射过程就是uv左边分别对屏幕的x方向和y方向求导数。那么在该点处纹理坐标分别投影在屏幕xy方向构成了一个平行四边形。
即:
雅克比矩阵为:
这时候的雅可比矩阵定义是屏幕空间的像素变化与纹理空间变化的线性变换。
更专业的几何解释是:
因此这时候要作纹理抗锯齿就是在屏幕空间位置处的像素大小对应的纹理坐标导数定义的平行四边形轮廓范围内的纹素颜色的平均值。
那么接下来只要找出这个平行四边形覆盖的纹素便可。
 
这里让我想起glsl中的dFdx和dFdy两个函数,就是用来计算一个量在此点的屏幕空间方向的导数。
固然硬件这里的计算仍是利用屏幕像素来作微分单元进行的。
这里可以计算,是由于GPU是以一个wrap来进行并行处理的,一个wrap来不一样的显卡架构上是不同的,有的是2x2的像素有的是32x32的像素。因此这里的偏导数就是像素块中变量的差值来计算出来的。dFdx表示的是像素块中右边像素的值减去素块中左边像素的值,而dFdy表示的是下面像素的值减去上面像素的值。
说到这里到能够考虑利用偏导数作一些图像处理,好比对于地图中某些要素在俯视图下出现锯齿问题,那么在片元着色器下,能够根据偏导数的大小决定是否绘制。
再好比焦散那篇文章中,文档:WebGL 水波及焦散(刻蚀)的渲染总结.n...
根据两个变量在偏导数上的乘积比来作一些决策:
如今再回到纹理采样这个问题上,上面说到只要找到纹理空间那个平行四边形的覆盖区域就好了。可是即便是这个平行四边形,仍然是极其昂贵的计算,因此在这个基础上又作了一些近似。好比双线性插值,实际上是利用纹理坐标点的周围的四个像素并根据必定的权重来计算颜色值。
可是即便是双线性插值也是很昂贵的计算,须要一些硬件的支持。因此有的高性能系统有专门的纹理采样硬件来支持。
双线性插值是一种近似,因此有的时候并非很好。也就诞生了其余的一些辅助的方法。好比mipmap和各向异性。(虎书中把这个查找过程称为滤波)
 
 
 
纹理挺坑的,说到这里还要介绍一个纹理的透视插值问题。这问题我以前有了解过,可是看一些图形库好像也没有专门处理这部份内容,不知道是否是硬件来处理了,因此没有太多关注。
这个能够看下面这篇文章,我先不肯定这个过程是图形管线本身修复的仍是须要开发者来修复。貌似看到的各类图形库都没有本身处理过这个问题。
 
相关文章
相关标签/搜索