[TOC]
摘要
前面我们已经介绍了顶点shader的详细内容,以及之后的顶点变换和图元装配的细节,渲染管线的下一阶段就是片段shader了。本章介绍片段shader中的核心方面:对纹理的应用。主要包括以下方面:
- 纹理基础
- 加载纹理和mipmap
- 纹理过滤和wrapping
- 纹理LOD(Level of detail)、混合和深度对比
- 纹理格式
- 在片段shader中使用纹理
- 纹理子图像说明
- 从framebuffer中复制纹理数据
- 压缩纹理
- 采样器对象
- 不可变纹理
- Pixel unpack buffer objects
1. Texturing Basics
在3D图形渲染中,最基本的操作之一就是将纹理应用到一个表面上。在OpenGL ES 3.0中,纹理主要包括这几种格式:2D纹理,2D纹理数组,3D纹理,立方图纹理。
通过使用纹理坐标将纹理应用到表面上,可以把纹理坐标当做纹理数据数组的索引。下面将介绍OpenGL ES中几个不同的纹理类型,并且说明它们是怎样进行加载和访问的。
2D Textures
2D纹理是OpenGL ES中最基础、最常见的纹理格式。一个2D纹理就是图像数据的一个二维数组,纹理图像数据可以表现为多种不同的基础格式,如下表:
Base Format | Texel Data Description |
---|---|
GL_RED | (Red) |
GL_RG | (Red, Green) |
GL_RGB | (Red, Green, Blue) |
GL_LUMINANCE | (Luminance) |
GL_LUMINANCE_ALPHA | (Luminance, Alpha) |
GL_ALPHA | (Alpha) |
GL_DEPTH_COMPONENT | (Depth) |
GL_DEPTH_STENCIL | (Depth, Stencil) |
GL_RED_INTEGER | (iRed) |
GL_RG_INTEGER | (iRed, iGreen) |
GL_RGB_INTEGER | (iRed, iGreen, iBlue) |
GL_RGBA_INTEGER | (iRed, iGreen, iBlue, iAlpha) |
一般情况下,在3D内容制作过程中,会生成一个网格,其中每一个顶点都有一个纹理坐标。2D纹理的纹理坐标用(s,t)表示,也叫 (u,v)坐标,这个坐标用来在纹理图像中查找图像数据。
纹理图像的左下角坐标是(0.0,0.0),右上角坐标是(1.0,1.0),在区间[0.0, 1.0]之外的坐标也是被允许的,这些区间之外坐标的纹理由纹理的wrapping mode决定。
Cubemap Textures
立方图纹理是由6个单独的2D纹理面组成的纹理,在3D渲染中有很多高级的使用方式,最常用的是环境贴图特效。通常,将一个摄像机放在场景中央,通过从6个轴的方向(+X, -X, +Y, -Y, +Z, -Z)捕捉场景图像,并将它们保存在每一个面上来生成一个立方图。
立方图纹理的像素通过一个3D向量(s,t,r)作为纹理坐标来进行查找,(s,t,r)代表着3D向量的(x,y,z)分量。首先根据这个3D向量,选择一个面,然后计算向量在这个面的投影或获得一个二维(s, t)坐标,具体的数学计算过程不在本章讨论范围,只需知道根据一个3D向量来查找立方图就可以了。
立方图的每个面的声明方法和2D纹理相同。每个面必须是正方形,并且每个面的宽高必须相同。用作纹理坐标的3D向量并不是逐顶点的储存在网格上,而是通过法线向量进行计算来获得。
3D Textures
3D纹理可以看做2D纹理切片的数组,用(s,t,r)坐标表示,其中r坐标用来选择要采样的切片,(s, t)坐标用来读取每一个切片的2D贴图。3D纹理的每一个mipmap等级包含着上一个等级纹理的一半数量的切片。
2D Texture Arrays
2D纹理数组和3D纹理很像,但用途不同。2D纹理数组经常用来储存2D图像动画,数组的每个切片代表动画的一帧。
2D纹理数组和3D纹理的差别虽然细微,却很重要。对于3D纹理,在切片之间会发生过滤;但在2D纹理数组中,只是从一个单独的切片中进行采样。并且,2D纹理数组的每一个mipmap等级都包含着和上一个等级的纹理相同数量的切片。
2D纹理数组的纹理坐标也用(s, t, r)表示,其中r坐标用来选择切片,(s,t)坐标用来在选择的切片上进行采用。
网友评论