纹理贴图资源(Texture)

    纹理贴图资源可由图像资源(ImageAsset)转换而来,图像资源包括一些通用的图像转换格式如 PNG、JPEG 等等。

    Texture2D 是纹理贴图资源的一种,通常用于 3D 模型的渲染,如模型材质中的反射贴图、环境光遮罩贴图等等。

    在将图像资源 导入 到 Creator 后,即可在 属性检查器 面板将其设置为 texture 类型,texture 类型便是 Texture2D 纹理资源。

    当导入图像资源时,编辑器默认将其设置为 texture 类型,并且在导入的图像资源下会自动创建一个或多个子资源,点击 资源管理器 中图像资源左侧的三角图标即可展开查看所有的子资源,如下图所示:

    sub-texture

    选中生成的 Texture2D 子资源后可以在 属性检查器 设置相关属性:

    接下来我们对部分属性进行简单的说明。

    当 Texture2D 的原始大小与屏幕映射的纹理图像尺寸不一致时,通过不同的纹理过滤方式进行纹理单元到像素的映射会产生不同的效果。

    Texture2D 中的 Min FilterMag Filter 属性,分别用于设置在缩小或者放大贴图时采用的纹理过滤方式:

    1. 邻近过滤()

      邻近过滤是 默认 使用的纹理过滤方式。使用中心位置距离采样点最近的纹理单元颜色值作为该采样点的颜色值,不考虑其他相邻像素的影响。
      需要注意的是使用临近过滤方式可能会出现边缘不平滑,锯齿较为明显的情况。

    2. 线性过滤使用距离采样点最近的 2 x 2 的纹理单元矩阵进行采样,取四个纹理单元颜色值的平均值作为采样点的颜色,像素之间的颜色值过渡会更加平滑。
      需要注意的是使用线性过滤方式可能会出现边缘黑边的情况,如果是像素类游戏,可能会出现模糊情况。

    为了加快 3D 场景渲染速度和减少图像锯齿,贴图被处理成由一系列被预先计算和优化过的图片组成的序列,这样的贴图被称为 mipmap。mipmap 中每一个层级的小图都是原图的一个特定比例的缩小细节的复制品,当贴图被缩小或者只需要从远距离观看时,mipmap 就会转换到适当的层级。

    当 Texture2D 的 Mip Filter 属性设置为 nearest 或者 linear 时,会在两个相近的层级之间插值,自动生成 mipmap(仅对非压缩格式生效)。因为渲染远距离物体时,mipmap 贴图比原图小,提高了显卡采样过程中的缓存命中率,所以渲染的速度得到了提升。同时因为 mipmap 的小图精度较低,从而减少了摩尔纹现象,可以减少画面上的锯齿。另外因为额外生成了一些小图,所以 mipmap 需要额外占用约三分之一的内存空间。

    Texture2D 可以在运行时动态选择 mipmap 的范围。设置完 mipmap 范围后,只有在范围之内的 mipmap 可以被使用。这允许我们通过跳过低层级来达到节约带宽的目的,同时也可以避免使用过高层级而降低效果。

    可以通过以下方法设置 Texture2D 的 mipmap 层级范围:

    其中 minLevel 指定了最小限制,maxLevel 指定了最大限制。

    一般来说,纹理坐标在水平轴(U)和垂直轴(V)的取值范围为 [0,1],当传递的顶点数据中的纹理坐标取值超出 [0,1] 范围时,就可以通过不同的寻址模式来控制超出范围的纹理坐标如何进行纹理映射。

    Texture2D 中的 Wrap Mode SWrap Mode T 属性便是分别用于设置纹理在 UV 方向上的寻址模式:

    1. 重复寻址模式(repeat

      重复寻址模式是默认使用的纹理寻址模式。对于超出 [0,1] 范围的纹理坐标,使用 内的纹理坐标内容不断重复,也就是在超出纹理坐标范围外的地方重复放置纹理贴图。

      当 Texture2D 的 Wrap Mode SWrap Mode T 属性都设置为 repeat 时,效果图如下:

      repeat

    2. 将纹理坐标约束在 0 到 1 之间,只复制一遍 [0,1] 的纹理坐标。对于 [0,1] 之外的部分,将使用边缘的纹理坐标内容进行延伸,产生类似边缘被拉伸的效果。

      当两个属性都设置为 时,效果图如下:

    Texture2D 是使用范围非常广泛的资源,在 Creator 中的使用方式主要包括在编辑器中使用和动态获取使用:

    • 在编辑器的 属性检查器 面板中,任何标记为 Texture2D 类型的属性,都可以将 Texture2D 资源拖拽到属性框中使用。例如设置材质资源的 Texture2D 类型资源:

      mirrored-repeat

    • 动态使用时,需要先获取图像资源(ImageAsset),然后根据获取到的 ImageAsset 实例化出 Texture2D 资源。

      1. resources.load("testAssets/image/texture", Texture2D, (err: any, texture: Texture2D) => {
      2. const spriteFrame = new SpriteFrame();
      3. spriteFrame.texture = texture;
      4. this.node.getComponent(Sprite).spriteFrame = spriteFrame;

      详情请参考 。

    LearnOpenGL — 纹理