1.3 不可变的纹理

OpenGL ES 2.0核心规范认可的唯一纹理对象类型是可变纹理对象。 这意味着在执行过程中的任何时候都允许OpenGL ES应用程序完全重新定义纹理mipmap配置。 它不仅可以即时添加或删除mipmap,还可以更改内部格式或属性,例如任何纹理对象的任何mipmap的宽度或高度。 这种自由极大地减少了驱动程序实现的优化可能性,这些实现被迫跟踪应用程序使用的所有纹理的完整性。 纹理完整性验证是相当大的开销,特别是如果必须为应用程序进行的每个绘制调用执行纹理完整性验证时。

OpenGL ES的解决方案是在不可变的纹理对象中。 最初在GL_EXT_texture_storage扩展中引入,它们成为OpenGL ES 3.0的核心功能。 不可变纹理的工作方式就像可变纹理一样,除了不再有可能将以下任何API函数应用于已变为不可变的纹理对象之外:

  • glCompressedTexImage*
  • glCopyTexImage*
  • glTexImage*
  • glTexStorage* – 可用于初始化不可变的纹理对象

新的glTexStorage *入口点使纹理不可变。 它们为用户指定的纹理目标初始化一个mipmap链,但不会在mipmap中填充任何内容。 应用程序负责通过使用glTexSubImage *入口点将不可变的纹理对象填充为实际内容。

不可变的纹理没有特定的用例。 相反,应该将它们视为减轻驱动程序负载的一种方法,这通常可以转化为更好的渲染性能。

注意:
在Adreno平台上,使用不可变纹理具有主要的性能优势。 始终使用不变的纹理,并避免使用所有易变的纹理。

1.4 每个纹理对象的LoD夹具

OpenGL ES 3.0 API规范包括一种用于组织多种分辨率的纹理的技术,该技术能够显示低分辨率的纹理,并在场景中的相机(查看器的位置)接近纹理对象时,在多个帧上缓慢引入更详细的纹理 。 这种技术通常用于地图或导航应用程序。 放大地图时,必须加载分辨率较高的纹理,但流式传输该纹理需要花费时间。 同时显示较低分辨率的纹理。 这提供了更好,更直接的观看体验,还有助于在不影响性能的情况下更有效地管理内存带宽。

例如,考虑一个大小为1024x1024像素的纹理,每个像素32位。 如图所示,此纹理在LoD = 0时的Mip为4MB,Mip 4-10的大小约为5KB。 作为LoD效果的起点,通过将基本级别设置为4,将最小LoD设置为4,下载4-10级的Mips。应用程序启动后,下载Mip 3,2,1,0。 然后,通过在多个帧上将基本级别缓慢设置为0,将min LoD更改为0。因此,纹理逐渐移相到最高分辨率。
OpenGL ES 写字api opengl es3.0metal_贴图
在glTexParameter()函数中使用以下参数来控制不同的LoD。

  • GL_TEXTURE_BASE_LEVEL –指定最低定义的mipmap级别的索引;这是一个非负整数值,其中初始值为0
  • GL_TEXTURE_MAX_LEVEL –设置最高定义的mipmap级别的索引; 这是一个非负整数值,其中初始值为1000
  • GL_TEXTURE_MAX_LOD –设置最大细节级别参数; 此浮点值限制了最低分辨率的Mipmap(最高的Mipmap级别)的选择,初始值为1000
  • GL_TEXTURE_MIN_LOD –设置最小细节级别参数; 此浮点值限制了对初始分辨率为-1000的最高分辨率mipmap(最低mipmap级别)的选择。

1.5 PCF用于深度纹理

阴影贴图会在电影和电视的高端渲染中创建阴影。 然而,由于诸如锯齿状放大形式的混叠问题,在诸如视频游戏之类的实时应用中使用阴影映射一直是有问题的。 阴影贴图涉及将阴影贴图投影到几何体上,并将阴影贴图的值与每个像素处的光视图深度进行比较。 如果投影放大了阴影贴图,则阴影边界处将出现大而难看的锯齿状的锯齿。 通常可以通过使用更高分辨率的阴影贴图并使用诸如透视阴影贴图的技术来增加阴影贴图的分辨率来减少混淆。

当光线几乎平行于阴影表面行进时,使用透视阴影映射技术和增加阴影贴图分辨率将不起作用,因为放大倍数接近无穷大。 高端渲染软件通过使用一种称为“百分比-封闭器”过滤的技术解决了混叠问题。

与普通纹理不同,阴影贴图纹理无法进行预过滤以消除锯齿。 取而代之的是,对每个像素进行多次阴影贴图比较,并将其平均在一起。

这项技术称为“percentage-closer filtering”(PCF),因为它计算的是更靠近光(因此不在阴影中)的表面的百分比。 考虑如Reeves等人所述的示例PCF算法。 1987年,它要求将要着色的区域映射到阴影贴图空间,并对该区域进行随机采样; 即是随机的。 该算法首先使用REYES渲染引擎实现,因此要着色的区域表示四面微多边形。

下图为实现的示例:
OpenGL ES 写字api opengl es3.0metal_opengl_02Adreno 4xx对百分比封闭过滤的OpenGL ES 3.0功能提供了硬件支持,其中将硬件双线性样本提取到阴影贴图纹理中,从而减轻了阴影贴图的混叠问题,如下图所示。
OpenGL ES 写字api opengl es3.0metal_贴图_03要了解如何使用此功能,请参阅Adreno SDK中的OpenGL ES 3.0 PCF示例。

1.6 新的内部纹理格式

OpenGL ES 3.0引入了可用于定义纹理数据内容的大小内部格式。 现在可以使用浮点,有符号和无符号整数内部格式以及许多不同的尺寸优化格式来表达纹理内容。 可以使用两种新的内部格式来存储以sRGB颜色空间表示的颜色信息。
OpenGL ES 写字api opengl es3.0metal_贴图_04
OpenGL ES 写字api opengl es3.0metal_应用程序_05OpenGL ES 写字api opengl es3.0metal_opengl_06对于大小合适的内部格式,可以保证内部纹理数据存储的实际分辨率与该格式定义的大小相匹配。

为了向后兼容,将继续支持不定尺寸的内部格式。 但是,使用它们可能会导致不同的OpenGL ES扩展与其他极端情况之间发生不良交互。 建议改用新尺寸的内部格式。