美文网首页
Opengles 纹理映射

Opengles 纹理映射

作者: 范少 | 来源:发表于2016-02-02 22:23 被阅读1143次

    在纹理坐标系中有一个命名为 S 和 T 的 2D 轴(类似于 X 轴 和 Y 轴)。纹理的尺寸为从 S 轴上从 0.f 到 1.f ,从 T 轴上从 0.f 到 1.f 。
    纹理的映射就是让物体的每个片元(每个颜色像素)都找到对应的纹理纹素点,在这个映射过程中,因为纹理和物体的不匹配,势必会出现两种情况。
    第一种是拥有大量纹素的纹理被映射到只还有少量片元的物体中。
    第二种是拥有少量纹素的纹理被映射到含有大量片元的物体中。

    针对这两种情况,纹理有几种设置方式。

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    

    GL_TEXTURE_MIN_FILTER 是多个纹素对应一个片元的解决方案。可以设置两个值(不能完全确定),GL_NEAREST 和 GL_LINEAR ,这两个值分别对应了两种不同的解决方案。GL_LINEAR 会混合匹配的颜色来得到片元的颜色,产生的颜色可能是纹理中不存在的颜色。例如一个纹理是由交替的黑色和白色的纹素组成,那个线性取样会使最终的片元颜色为灰色。GL_NEAREST 会拾取与片元 U,V 坐标最相近的颜色。

    GL_TEXTURE_MAG_FILTER 是没有足够的纹素来映射片元的解决方案。可以设置的值同 GL_TEXTURE_MIN_FILTER 一样。GL_LINEAR 会告诉OpenGL ES 混合附近纹素的颜色来计算片元的颜色。GL_LINEAR 会有一个放大纹理的效果,当没有足够的纹素来映射片元时,会让纹理模糊的出现在要渲染的图形上。GL_NEAREST 仅仅会拾取片元的 U ,V 位置接近的纹素的颜色,并放大纹理,会使其像素化的出现在要渲染的图形上。

    如下是一张原始图片:


    test.png

    当使用 GL_LINEAR 方式时,呈现如下:


    Paste_Image.png

    可以看到不会失真,变为了模糊的放大效果。

    使用 GL_NEAREST 方式时,呈现如下:


    Paste_Image.png

    可以看到图片失真,却没有模糊。

    当纹理较小且不复杂时,可以使用GL_NEAREST 的方式,这样能较好的保证原图的质量。

    另外一种在映射时可能出现的情况是纹理并没有完全映射到物体上。即纹理的 S 轴的 1.f 处 或 T轴的 1.f 处并没有与物体的 X 轴 1.f 或者 Y 轴的 1.f 处重合(简单来说就是纹理只覆盖了物体的部分)。

    这种情况可以有三种设置解决方案。默认为GL_CLAMP_TO_EDGE 。
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);

    GL_REPEAT: 看名称就能猜出,在纹理没有覆盖的部分重复之前的纹理。
    GL_CLAMP_TO_EDGE:延续结束时的纹理
    GL_MIRRORED_REPEAT:将原来的纹理先颠倒再重复。
    PS:在写代码时发现,当使用GL_REPEAT 和 GL_MIRRORED_REPEAT时,如果图片尺寸不是2的次幂时可能会导致纹理无法显示。GL_CLAMP_TO_EDGE 能够正常显示非2的次幂规格的纹理。

    一个简单的小例子

    相关文章

      网友评论

          本文标题:Opengles 纹理映射

          本文链接:https://www.haomeiwen.com/subject/fyfekttx.html