OpenGL之纹理过滤(Texture Filtering)、MipMap方法、纹理坐标

1.1 纹理过滤
OpenGL之纹理过滤(Texture Filtering)、MipMap方法、纹理坐标_第1张图片
像素、片元都是具有面积的,一个像素可能对应物体上的一小块区域,而物体上这个小区域对应于纹理图像上的一个小区域,因此一个像素的颜色可能来自于纹理中的一小个不规则区域,如果纹理的分辨率比较高,则这个区域可能包含多个纹元(纹理中的单元,即纹元),由这几个纹元的颜色确定这个像素的颜色的过程就叫做纹理过滤
OpenGL之纹理过滤(Texture Filtering)、MipMap方法、纹理坐标_第2张图片

1.2 一个像素一般不会正好对应于一个纹元(texel)。所以像素的颜色无法直接得到,需要经过一定的运算,这个过程就是纹理过滤

1.3 纹理过滤的几种情况

  • GL_TEXTURE_MAG_FILTER,如下左边;
  • GL_TEXTUER_MIN_FILTER,如下右边;
    OpenGL之纹理过滤(Texture Filtering)、MipMap方法、纹理坐标_第3张图片

纹理过滤的几种方式:

  • GL_NEAREST:选择距像素中心距离最小的texel的颜色作为像素的颜色;
  • GL_LINAR:选择距像素中心最近的四个texel的加权平均值作为像素的颜色;对于上述第一中情况,将会考虑邻居纹元的颜色;

采样上述方式,远处纹理会出现如下错误。
OpenGL之纹理过滤(Texture Filtering)、MipMap方法、纹理坐标_第4张图片

1.4 MipMap方法

当一个屏幕像素覆盖的纹理区域大于4个纹元甚至更多的时候,采用4个邻居的加权平均值作为像素颜色是不合理的。

1.4.1 mipmap方法

  • 首先对纹理进行预处理,生成不同分辨率的版本;
  • 纹理过滤时,首先选取合适的分辨率,然后进行Linear过滤;
    OpenGL之纹理过滤(Texture Filtering)、MipMap方法、纹理坐标_第5张图片
    假设,一个像素覆盖了四个纹元,那么就选择 1 4 \frac{1}{4} 41那张分辨率的图片就行。如果一个像素覆盖了的纹元数量在4~16之间,那么就在 1 4 \frac{1}{4} 41 1 16 \frac{1}{16} 161分辨率的图片各取一个值做加权平均即可。

1.4.2 对于GL_TEXTURE_MIN_FILTER方式,才需要采用mipmap方式
OpenGL之纹理过滤(Texture Filtering)、MipMap方法、纹理坐标_第6张图片
OpenGL之纹理过滤(Texture Filtering)、MipMap方法、纹理坐标_第7张图片

如下、各种方式,远处的效果,近处采用的都是相同的方式,主要对比远处,可知GL_LINEAR_MIPMAP_LINEAR效果最优,也被称做三线性过滤
OpenGL之纹理过滤(Texture Filtering)、MipMap方法、纹理坐标_第8张图片

1.4.3 mipmap层 的选择由系统自动完成,采用计算一个像素与其所覆盖的纹理区域的面积比例(取x、y方向上的最大缩放值),由此选定mipmap层。

1.4.4 mipmap的生成

  • 可以调用gluScaleImage()来逐级生成;
  • 通过glTexImage2D(GLenum target,GLint level,…)来进行加载;

更常用的方法是,调用如下方法,就可以生成所以mipmap层级并加载。

int gluBuild2DMipmaps(GLenum target,GLint components,GLint width,GLint height,GLenum fromat,GLenum type,const void* data);

//在OpenGL3.0之后,这个函数被提升到了核心库中;
glGenerateMimmap(GLenum target);

1.4.5 Mipmap存在的问题

  • 如果覆盖区域非常狭长,与正方形相差较大,效果不好。
  • 正方形、圆形各个法向尺度一样,为各向同性滤波;
  • 克服上述问题,可以采用各向异性滤波,即可以采用长方形来过滤;
    OpenGL之纹理过滤(Texture Filtering)、MipMap方法、纹理坐标_第9张图片
    如上图,途中黑白格为长方形时,采用各向异性滤波效果最优。

1.5 纹理坐标

做纹理映射,需要知道纹理坐标。纹理坐标可以自己指定、从模型文件中读取,也可以采用OpenGL自动生成纹理坐标。OpenGL中提供了五种自动生成纹理坐标的方式:

  • GL_OBJECT_LINEAR :
    • 设置三维空间中的一个平面;
    • 计算当前顶点与该平面的距离;
    • 以此距离作为一维纹理中的纹理位置,如果是二维纹理,则可以为s和t分别设置一个平面;
      OpenGL之纹理过滤(Texture Filtering)、MipMap方法、纹理坐标_第10张图片

三维空间中的一个平面由(p1,p2,p3,p4)四个参数即可确定一个平面,即:
p 1 ∗ x + p 2 ∗ y + p 3 ∗ z + p 4 = 0 p1 * x + p2 * y + p3 * z + p4 = 0 p1x+p2y+p3z+p4=0,三维空间中顶点到平面的距离计算为:
d = p 1 ∗ x + p 2 ∗ y + p 3 ∗ z + p 4 d = p1 * x + p2 * y + p3 * z + p4 d=p1x+p2y+p3z+p4,则GL_OBJECT_LINEAR中的纹理坐标计算:

g = p 1 ∗ x + p 2 ∗ y + p 3 ∗ z + p 4 ∗ w g = p1 * x + p2 * y + p3 * z + p4 * w g=p1x+p2y+p3z+p4w,一般w为1,即齐次坐标,则g就是距离。

  • GL_EYE_LINEAR :
    OpenGL之纹理过滤(Texture Filtering)、MipMap方法、纹理坐标_第11张图片

1.5.1 操作步骤为:

指定坐标生成模式
OpenGL之纹理过滤(Texture Filtering)、MipMap方法、纹理坐标_第12张图片
在OpenGL中,(x,y,z,w)表示的是顶点,(s,t,r,q)表示的是纹理坐标,(u,v,w)可以表示纹理坐标。

指定参参考平面的参数:
OpenGL之纹理过滤(Texture Filtering)、MipMap方法、纹理坐标_第13张图片
打开纹理自动生成的开关:
OpenGL之纹理过滤(Texture Filtering)、MipMap方法、纹理坐标_第14张图片

1.5.2 更常用的纹理坐标自动生成为:

  • GL_SPHERE_MAP
  • GL_REFLECTION_MAP
  • GL_NORMAL_MAP

可以实现类似于环境映射的效果,把环境映射到模型表面。

你可能感兴趣的:(OpenGL,图形渲染,OpenGL)