[TOC]
Automatic Mipmap Generation
在上一节的例子中,先创建了一个图像作为mipmap链的第0级,然后通过盒试过滤生成mipmap链的其余图像。这是生成mipmap链的一个方法,但是在OpenGL ES中,还提供了另外一种机制来自动生成mipmap:
void glGenerateMipmap (GLenum target)
- target : 要生成mipmap的纹理目标,可取值为
GL_TEXTURE_2D
GL_TEXTURE_3D
GL_TEXTURE_2D_ARRAY
GL_TEXTURE_CUBE_MAP
当在一个绑定的纹理对象上调用glGenerateMipmap时,这个方法会根据0级图像内容来自动生成完整的mipmap链。
OpenGL ES 3.0并没有强制一个用于生成mipmap贴图的过滤算法(尽管规范中推荐使用盒试过滤,但各个实现可以自由选择使用哪一种算法)。如果你需要一个特殊的过滤算法,还是需要自己生成mipmap链。
当你开始使用帧缓冲对象来渲染纹理时,mipmap链自动生成就变得非常重要了。当渲染到一个纹理时,我们不想要将纹理内容读回到CPU中来生成mipmap贴图。这时,使用glGenerateMipmap和图形硬件,就可以在不需要将数据读回到CPU的情况下生成mipmap贴图。这一点在第十二章将会更详细地进行介绍。
Texture Coordinate Wrapping
纹理wrap模式用来声明当纹理坐标位于[0.0, 1.0]范围之外时所发生的行为,可以通过glTexParameter方法来设置。在OpenGL ES中,有三种wrap模式可供选择:
Texture Wrap Mode | Description |
---|---|
GL_REPEAT | 重复纹理 |
GL_CLAMP_TO_EDGE | 限定读取纹理的边缘 |
GL_MIRRORED_REPEAT | 重复纹理和镜像 |
注意,纹理wrap模式也会影响到过滤。例如,当一个纹理坐标位于一个纹理的边缘时,双线性过滤核心可能会跨越纹理边缘,在这种情况下,纹理wrap模式将会决定核心处于纹理之外的部分要读取哪些纹理像素。如果你不希望出现任何形式的重复,应该使用GL_CLAMP_TO_EDGE。
下图是三种wrap模式的一个示例,其中纹理坐标的范围是[-1.0, 2.0]:
Texture Swizzles
纹理swizzle控制输入的R,RG,RGB,或者RGBA纹理中的颜色分量在shader中读取时的映射。例如,一个程序可能希望一个GL_RED纹理映射为(0,0,0,R)或者(R, R, R, 1)而不是默认的(R,0,0,1)。通过glTexParameter方法可以单独设置每个分量的映射。从纹理R,G,B,A分量获取到的GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA可以作为shader中映射分量的纹理值,另外,也可以用GL_ZERO或GL_ONE将映射的纹理值设为0或1。
Texture Level of Detail
在一些应用中,在所有纹理mipmap级别可用之前就能开始显示场景是很有用的。例如,一个GPS应用可以从最低级别的mipmap开始显示,然后在更高级别的mipmap可用时再显示它们。在OpenGL ES 3.0中,可以通过glTexParameter来实现。GL_TEXTURE_BASE_LEVEL设置一个纹理使用的最大的mipmap级别,这个默认值是0,但是如果这个级别还不可用的话可以设置为一个更高的值。GL_TEXTURE_MAX_LEVEL设置使用的最小的mipmap级别,这个默认值是1000(超过了任何纹理可能具备的级别),它可以被设置为一个更小的值来控制一个纹理使用的最小mipmap级别。
为了选择使用哪个级别的mipmap来进行渲染,OpenGL ES自动计算一个细节级别值(LOD)。这个浮点值确定从哪一个级别的mipmap进行过滤(在三线性过滤中,控制每个mipmap的多少被使用)。应用程序可以通过设置GL_TEXTURE_MIN_LOD和GL_TEXTURE_MAX_LOD来控制LOD的最小值和最大值。通过控制LOD可以在新的mipmap级别可用时提供平滑过渡,如果只设置纹理的基础和最大mipmap级别可能会在新mipmap级别可用时造成伪像,而插入LOD能够使这一过渡看上去更平滑。
Depth Texture Compare (Percentage Closest Filtering)
接下来要讨论的是GL_TEXTURE_COMPARE_FUNC和GL_TEXTURE_COMPARE_MODE参数。引入这些参数是为了提供百分比渐进过滤(PCF)功能。在使用阴影贴图技术时,片段shader需要比较一个片段的深度值和深度纹理中的深度值,以此来决定这个片段是在阴影内还是阴影外。为了获得平滑的阴影边缘,对深度纹理进行双线性过滤是很有用的。但是,当对深度纹理进行过滤时,我们希望过滤发生在采样比较之后,如果过滤发生在比较之前,那么结果就不正确了。PCF提供了正确的过滤,它将采样的深度值和参考深度比较之后,将比较结果(0或1)进行平均。
GL_TEXTURE_COMPARE_MODE的默认值是GL_NONE,但是当它被设置为GL_COMPARE_REF_TO_TEXTURE时,纹理坐标(s, t, r)的r分量用来和深度纹理的值做比较,比较结果会成为阴影纹理读取的结果(可能为0或者1,如果开启了纹理过滤则是这些值的平均值)。比较函数用GL_TEXTURE_COMPARE_FUNC设置。
网友评论