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


    1.1 纹理过滤
    在这里插入图片描述
    像素、片元都是具有面积的,一个像素可能对应物体上的一小块区域,而物体上这个小区域对应于纹理图像上的一个小区域,因此一个像素的颜色可能来自于纹理中的一小个不规则区域,如果纹理的分辨率比较高,则这个区域可能包含多个纹元(纹理中的单元,即纹元),由这几个纹元的颜色确定这个像素的颜色的过程就叫做纹理过滤
    在这里插入图片描述

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

    1.3 纹理过滤的几种情况

    • GL_TEXTURE_MAG_FILTER,如下左边;
    • GL_TEXTUER_MIN_FILTER,如下右边;
      在这里插入图片描述

    纹理过滤的几种方式:

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

    采样上述方式,远处纹理会出现如下错误。
    在这里插入图片描述

    1.4 MipMap方法

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

    1.4.1 mipmap方法

    • 首先对纹理进行预处理,生成不同分辨率的版本;
    • 纹理过滤时,首先选取合适的分辨率,然后进行Linear过滤;
      在这里插入图片描述
      假设,一个像素覆盖了四个纹元,那么就选择 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方式
    在这里插入图片描述
    在这里插入图片描述

    如下、各种方式,远处的效果,近处采用的都是相同的方式,主要对比远处,可知GL_LINEAR_MIPMAP_LINEAR效果最优,也被称做三线性过滤
    在这里插入图片描述

    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
    • 2
    • 3
    • 4

    1.4.5 Mipmap存在的问题

    • 如果覆盖区域非常狭长,与正方形相差较大,效果不好。
    • 正方形、圆形各个法向尺度一样,为各向同性滤波;
    • 克服上述问题,可以采用各向异性滤波,即可以采用长方形来过滤;
      在这里插入图片描述
      如上图,途中黑白格为长方形时,采用各向异性滤波效果最优。

    1.5 纹理坐标

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

    • GL_OBJECT_LINEAR :
      • 设置三维空间中的一个平面;
      • 计算当前顶点与该平面的距离;
      • 以此距离作为一维纹理中的纹理位置,如果是二维纹理,则可以为s和t分别设置一个平面;
        在这里插入图片描述

    三维空间中的一个平面由(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 :
      在这里插入图片描述

    1.5.1 操作步骤为:

    指定坐标生成模式
    在这里插入图片描述
    在OpenGL中,(x,y,z,w)表示的是顶点,(s,t,r,q)表示的是纹理坐标,(u,v,w)可以表示纹理坐标。

    指定参参考平面的参数:
    在这里插入图片描述
    打开纹理自动生成的开关:
    在这里插入图片描述

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

    • GL_SPHERE_MAP
    • GL_REFLECTION_MAP
    • GL_NORMAL_MAP

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

  • 相关阅读:
    【前端求助帖】关于使用element-plus select 模板嵌套popover中使用select选择后,上一个select自动关闭的问题
    quick3-hydra
    GB/T 29734.3-2020 塑钢复合门窗检测
    软件测试书单/书籍推荐(整理更新中)
    杰理之CMD_SET_BLE_VISIBILITY【篇】
    Cloudflare进阶技巧:缓存利用最大化
    Python爬虫抓取微博数据及热度预测
    [爬虫]2.2.1 使用Selenium库模拟浏览器操作
    字符串旋转
    C++算法 —— 动态规划(9)完全背包问题
  • 原文地址:https://blog.csdn.net/TxyITxs/article/details/127813200