本篇介绍
使用纹理可以表示比较复杂的图形,比如磨损的金属,粗糙的皮肤,有褶皱的衣服等,而纹理映射也不是简单的坐标映射下就行,最容易想到的就是直接映射其实就是冲采样,会有走样问题。本篇就看下纹理映射涉及的问题。
查找纹理值
根据原始图像的像素坐标转换成对应的问题坐标,那纹理上对应坐标的值就是需要给图像渲染的值,如下所示:
image.png
这本质上就是一个从图像到纹理坐标的映射。 最简单的实现就是坐标按比例映射:
image.png
这样的确也有效果,一个实际的应用效果如下:
image.png
但是对于图像和纹理像素差异大,而且观察角度比较刁钻的场景就不太行了,走样会比较明显,如下所示:
image.png
看到这儿可以看出纹理映射的2个关键问题了:
- 建立纹理坐标映射函数
- 确定对应坐标的纹理值并且不引入过多的走样
纹理坐标函数
纹理坐标函数用来做坐标的映射,在选择坐标函数的时候,,有几点需要考虑: Bijectivity:不同的点最好对应不同的纹理坐标 Size distortion: 在图像上两点的距离应该和对应纹理坐标的距离比例固定 Shape distortion:图像变形不能太严重,比如对于一个圆,对应的纹理坐标也应该是一个圆 Continuity:图像上相邻的点对应的纹理坐标也应该相邻
接下来看几种常见的映射函数,对应的测试图像如下:
image.png
Plannar Projection 方法是:
image.png
对应的效果是:
image.png
Spherical Coordinates
这时候的物体最好是球体,对应的公式如下:
image.png
对应的效果如下:
image.png
Cylindrical Coordinates
对于柱状物体,用类似柱状的映射方法会效果更好:
image.png
对应的效果如下:
image.png
Cubemaps
还有一种方式是把坐标映射到6个立体声面上,然后针对各个面找对应的问题坐标:
image.png
OpenGL用的方法如下:
image.png
插值纹理坐标
通过插值的方式也可以做纹理映射,通过记录纹理的三角形顶点坐标,就可以通过重心定理插值了。
image.png
不过会引入Size Distortion,如果图像和纹理的三角形面积差不多,那么差异会小一些,如果面积区别大,那么对应的差异也会很明显。 如下图所示:
image.png
人脸上灰色的正方形,鼻子处明显会小于太阳穴处。
当图像和纹理大小不一样的时候,比如纹理映射函数计算出的坐标超过了纹理的范围,这时候就可以采取一些措施,或者是返回一个默认值,或者是进行回绕。
image.png
下面是回绕的效果:
image.png
透视纠正插值
在映射的时候,还需要考虑到视图的场景,如下图所示:
image.png
左边是正确的结果,右边是错误的,在计算纹理坐标的时候就需要考虑到透视的场景,方法如下:
image.png
连续和接合
有时候连续性是避免不了的,这时候就需哟啊引入接合处,表示纹理坐标会突然变化。不过结合处也需要对一些场景进行特殊处理。在球面映射的时候,如下图所示:
image.png
对于左边的地球,在插值处涉及到了经度变化,这时候插值就可能不是相邻点插值,而是反方向绕地球一圈,比如167E到179W,这时候就需要在接合处共享纹理坐标,在遇到167E到179W场景时,不需要绕地球一圈,只需要按照167E到181E处理即可,也就是右边的效果。