Id tech5虚拟纹理

来源:互联网 发布:微信数据储存到sd卡里 编辑:程序博客网 时间:2024/05/22 15:36

原文名称 software virtual Texture   ,乃是id的高级程序员写的关于虚拟纹理如何实现的文章。

我保存在了网盘中,   地址  下载    原文有图像能够表示原理,由于Pdf文档格式,图像不好复制,所以我只是翻译了文字部分

强烈建议看原文

软件虚拟纹理
J.M.P.范·波伦
2012年2月25日
2012,Id Software LLC,Zenimax Media公司。

现代图像模拟越来越需要显示非常大,唯一的、互动率的纹理世界。在大型户外环境中也是如此
高详细的室内环境,如电脑游戏中显示的那样、RAGE,独特的纹理细节需要显着的存储和带宽。
虚拟纹理通过提供稀疏来减少唯一纹理数据的成本不需要所有数据存在的表示
渲染,同时留下大部分的纹理数据二级存储上的压缩形式。虚拟纹理不仅提供了减少内存需求,还可以提高渲染效果

    通过降低图形驱动和硬件状态的性能改变是因为许多曲面可以使用单个虚拟纹理而不使用
需要每个表面纹理选择。几个实例是讨论了强调实现虚拟纹理的挑战软件没有特殊的图形硬件支持

和可行的解决方案呈现。 这些包括地址转换,纹理过滤,超额订阅,LOD捕捉,压缩,缓存和流式传输。


2介绍
在计算机图形学中,纹理映射用于将表面细节添加到几何图元中。甚至
尽管纹理贴图能够有效地管理和渲染表面细节,但独一无二的纹理数据需要大量的存储和带宽。

因此,经常会出现一小组纹理重复使用,通常的做法是使用可以重复多次的平铺纹理单面。多个纹理也可以在

运行时混合在一起,以组合各种从一小束源纹理的细节。这些都可以被视为专门的形式纹理压缩对内容生成管道造成重大负担。通过
提供稀疏表示,虚拟纹理显着降低了独特纹理显示的成本

纹理数据。
纹理的稀疏表示描述了内存中不需要所有内容的布局
要呈现的数据。在mip映射纹理的上下文中,一个稀疏表示
可以允许图像的不同部分以不同的分辨率可用。这个很重要
因为在任何给定的渲染场景中,仅使用数据的稀疏采样,即使如此
所有数据都存在。通过虚拟纹理来挖掘这个稀疏度,涉及到一个池
物理纹理页面和页面表,将虚拟地址映射到物理页面,类似于
虚拟内存系统

 然而,虚拟纹理与其他形式的虚拟内存以两种关键方式不同。

第一,具有纹理,可以在不停止执行的情况下回退到略微模糊的数据。一个
标准虚拟内存系统必须停止执行进程,直到系统加载请求的数据。

第二,数据的有损压缩对于大多数用途是完全可以接受的。
这两个关键差异使虚拟纹理适合在质量上进行权衡牺牲性能并显着降低内存需求。

虚拟纹理不仅可以显着降低内存需求,还可以允许所有表面以单批几何绘制。不同的表面可以使用不同的
部分相同的虚拟纹理,并且不需要每个表面纹理选择。什么时候虚拟纹理被普遍应用,

几何通常只能分解成多个批量淘汰粒度。这可以显着提高渲染性能,因为改进的剔除和图形驱动和硬件状态的降低
变化。

虚拟纹理也可以使用per构建独特的纹理静态世界纹理预先计算的照明直接存储在纹理数据中,可以进一步减少
渲染次数和状态变化。

虚拟纹理提供了显着的优点,如减少内存要求提高渲染性能。然而,在软件中实现虚拟纹理,没有
特殊图形硬件支持,涉及各种挑战。

本文讨论了这些提出了挑战和可行的解决方案,即交易绩效,质量和内存要求。
3
2.以前的工作
对于地形渲染,有许多方法来管理非常大的纹理数据集
在选择或构造时自适应地选择细节纹理水平(LOD)
细节的几何层次。这些方法中的一些使用预先计算的几何LOD
在纹理LOD [1,2,3,4]中烘烤,而其他动态生成几何LOD和入
该过程分配不同的纹理LOD [5,6]。这些方法都不实现虚拟纹理通过每个片段纹理地址转换。

    代替,不同的纹理坐标由几何的不同的预先计算的版本提供,或几何生成新的纹理坐标。剪贴图[7,8,9,10,11,12]是第一个有效的方案之一虚拟纹理与perfragment纹理地址转换。 Tanner等人介绍的剪贴图在1998年[7],由一堆类似于mip地图层次的图像组成。然而,虽然mip-map级别覆盖了整个纹理与增加大小的图像,剪贴图使用固定的大小水平,覆盖放置在纹理的某处的单个焦点周围的减少区域。使用围绕单个焦点的感兴趣区域点显着简化了纹理数据到几何的映射,渲染过程中的纹理地址转换具有最小的复杂性。

   然而,剪辑映射的单个焦点将这个纹理管理化学限制在纹理数据和几何之间具有自然空间相关性的环境中,例如大多是平坦的连续地形。最近的虚拟纹理系统更加灵活,并且模仿虚拟内存管理的现代CPU [16,17,18,19,20,21,22,23,24]的操作系统。纹理划分为小页面,根据需要自动缓存并加载到视频内存中。这些系统通过pagetables和/或映射纹理使用实时的每个片段纹理地址转换。因为在几何和纹理页之间不一定有自然的相关性,这些虚拟纹理系统需要来自渲染管道的反馈来确定哪些页面需要驻留[13,14,15]。本文介绍了在没有特殊硬件支持的情况下在软件中实现这种类型的虚拟纹理系统的挑战。

   还有一些用于通用虚拟内存管理的图形硬件如GLIFT的软件系统[25]。这样的系统不会自动利用虚拟纹理的特定属性,使得它们可以在质量和性能之间进行权衡。然而,像GLIFT一样的系统可以用作构建虚拟纹理系统的基础。而不是使用像GLIFT这样的更广泛的子系统,这里的重点是虚拟纹理系统,直接映射到底层硬件。

    使用软件渲染Virtual Textures3.1地址转换将虚拟纹理分为小页面,并将其加载到渲染所需的驻留物理页面池中。这些小页面是方块的纹理,通常是128 x 128的顺序。具有物理页面的池是一个完全驻留的纹理,在逻辑上细分为这样的纹理像素块。虽然虚拟纹理可能非常大(例如一百万页),并且永远不会完全驻留在视频内存中,但是保存物理页面池的纹理本质上居然但更小(通常只有4096 x 4096纹素或1024页)。

    虚拟纹理映射到物理纹理页面,并且在渲染期间虚拟地址需要重新翻译为物理地址。图1:将虚拟纹理应用于全局测量的场景。图2:具有突出显示的虚拟纹理图像的场景相同。在其最简单的形式中,虚拟物理转换相当于通过使用虚拟纹理地址来走向表示当前驻留的纹理页面的层次结构的四叉树来找到所需的详细级别(LOD)。

    四叉树中的每个节点都提供了一个缩放和偏差,将虚拟页面中的虚拟地址转换为物理页面内的物理地址。尺度是虚拟mip级别的大小与物理纹理大小之间的比例。偏移是物理纹理中物理页面的偏移量,减去虚拟mip级别中虚拟页面的缩放偏移量。在四叉树行走时,在给定的虚拟地址上找到所需的LOD,找到所需LOD的比例和偏差,或者四叉树提前终止,最后一个节点的比例和偏差用于叠加。在后一种情况下,地址转换从较粗略的mip级别返回到页面,因为所需更精细的mip级别的纹理页面在物理池池中尚不可用。图3显示了虚拟到物理地址转换和比例和偏差的计算的概述.

    5图3:虚拟到物理地址转换。可以在附录A中找到规模和偏差的全面计算(考虑页面边界)。仅使用四叉树数据结构与当前驻留的纹理页面允许最小的内存页表,但是它具有最差的访问延迟,因为它需要对每个更细微的访问级别进行独立的读取。而不是走四叉树,地址翻译可以通过交易性能和记忆的各种方式来实现。一种简单的方法来实现virtu

物理翻译是在一个mip映射的纹理中查找尺度和偏差,每个虚拟页面有一个纹理像素。实际上,这个mip映射文件存储完整的四叉树数据结构,每个虚拟纹理页面都有一个节点,不管它是否驻留。对此页面表纹理的常规查找允许纹理硬件用于计算在给定虚拟地址处为期望的LOD的虚拟纹理页面对应的最接近的mip级别的最近纹理。

      纹理查找以页面宽度的基本对数为对象,以考虑虚拟纹理和页面表面纹理之间的大小差异。从该页面表格中检索的比例和偏差可以直接用于将虚拟地址映射到物理地址。如果在物理页面池中所需的较细的mip不可用,则该纹理的纹理将会从较粗略的mip存储纹理页面的缩放和偏差。

    如果虚拟和物理纹理都是正方形,则只需要单个双轴的刻度值。然而,为了将虚拟页面映射到任意物理页面,需要有两个偏置值(S偏置和T偏置)。

   需要以至少16位的精度存储比例和偏差,以便能够支持合理大的虚拟纹理(> = 1024 x 1024页边框)。因为FP16尾数没有足够的位,所以规模和偏差可以存储为32位浮点(FP32),而不是16位浮点(FP16)。通过将三个值(ST刻度,S偏置,T偏置)存储在四组件FP32(FP32x4)纹理中,实现最简单的结果。

       使用这样的FP32x4页表纹理的虚拟物理翻译的片段程序中的实现是微不足道的,并且由附录A.1所示的不超过纹理查找和乘法加法组成。不幸的是,对于一个相当大的虚拟纹理,FP32x4页表格纹理消耗大量的内存。

     例如,对于具有1024 x 1024虚拟页面的虚拟纹理,页表纹理占用了21.33 MB的内存。为了减少内存需求,页表可以分为两个纹理。第一个纹理在每个虚拟页面上使用一个纹理映射。再次对thistexture进行常规查找可以使纹理硬件用于计算对应于给定虚拟地址的所需LOD的虚拟纹理页面的最近miple的最近纹理。不存储比例和偏差,每2该纹理的字节纹素包含要用于虚拟页面的物理页面的(x,y)坐标。

    如果所需更精细的mip尚不可用,此纹理的纹理将指向较粗糙的mip的物理页面。第二个纹理是非物理映射的FP32x4纹理,每个物理页面有一个纹理像素。来自该纹理的纹理包含将虚拟纹理坐标映射到该页面的非物理纹理坐标所需的缩放和偏差(ST-刻度,S偏置,T偏置)。在附录A.2中显示了使用页表和单独的映射纹理来存储缩放和偏差的虚拟到物理翻译的片段程序中的实现。

     这种方法通过将浮点尺度和偏置存储在每个物理页面具有一个纹理像素(通常为32 x 32)的纹理中,同时允许以完全驻留的成本(通常为1024 x1024)的速度访问该纹理来节省存储空间,每个虚拟页面只有两个字节的纹理。这种内存优化花费了依赖纹理读取的延迟,但与将虚拟页面的浮点数和偏移量存储在每个虚拟页面一个纹理像素的纹理中相比,它节省了8倍的内存。每个虚拟页面只有2个字节,每个物理页面为16个字节,页面表纹理消耗大约2.66 MB的虚拟纹理的内存,具有1024 x 1024页面。

 图4:将虚拟纹理应用于所有几何图形的场景。

   图5:页面表与虚拟纹理的每个虚拟页面的2个字节应用于场景中的静态几何。在某些图形硬件中,从纹理获取超过32位/纹理的纹理是昂贵的和/或限制可并行处理的片段数。而不是使用singleFP32x4映射纹理,比例尺和偏差可以存储在三个单独的单组分7FP32纹理中:一个用于ST刻度,一个用于S偏置,一个用于T偏置。在使用三个FP32x1纹理的片段程序中实现,用于存储附录A.3中出现的比例和偏差。在某些平台中,性能受到使用纹理数量的限制。'

    因此,使用单独的单分量FP32纹理可能不会导致最佳性能。缩小绑定纹理的数量,缩放和偏差可以存储在两个16位元件定点纹理中:一个单组分纹理存储ST刻度和一个双组分纹理来存储S偏置和T偏置。有必要谨慎使用所有可用的位以便同步从非常大的虚拟纹理到虚拟物理转换。使用两个16位定点映射纹理的实现如附录A.4所示。虚拟到物理转换不再仅仅是纹理查找和乘法加法应用规模和偏见。需要进行两次附加乘法和减法,以便将16位定点值移动到适当的范围内。不需要在纹理中存储比例和偏差,虚拟到物理映射也可以在片段程序中根据坐标和物理页面的mip级别。


    物理页面的坐标和mip级别可以存储在单个mip映射纹理中,避免了依赖纹理读取的延迟以获取比例和偏差。在这里,这个纹理的一个常见的例子就是使用纹理硬件来计算一个对应于给定虚拟地址上所需LOD的虚拟纹理页面的最近mip级别的最近纹理。从该纹理检索的物理页面的坐标用于计算物理纹理中物理页面左上角的偏移量。要计算完整的物理地址,虚拟页面中的偏移量需要缩放并添加到物理页面的左上角。虚拟页面中的偏移量需要通过首先将虚拟纹理坐标与物理页面的mip级别(虚拟页面宽/ 2 ^ mip)的页面宽度相乘,然后获取分数来完成正确的mip级别。在添加到物理页面偏移量之前,将此分数缩放到正确的范围内。当使用8位每个组件RGBA页表格纹理时,物理页面坐标可以存储在前两个组件中。代替将mip级别存储在其他组件之一中,组合的最后两个组件的16位可用于存储物理页面的mip级别的宽度。 16位足以支持超过10个mip级别的1024 x 1024页的非常大的虚拟纹理。使用8位每个组件RGBA纹理的片段程序中的实现如附录A.5所示。 8位组件在片段程序中可用之前,会在硬件中转换为浮点范围[0,1]。不幸的是,这种转换可能是硬件具体的。

  在图形硬件上,8位组件通过除法255直接转换为FP32.在其他硬件上,8位组件首先转换为FP16,然后转换为FP32。

  片段程序中的虚拟到物理转换的计算必须在将物理页面的页面数量和物理页面的mip级别的页面宽度转换为整数值时,可以对纹理数据进行任何硬件特定转换。

  使用8位每个组件RGBA纹理,页表最终消耗5.33 MB的内存,用于1024 x 1024页的虚拟纹理。为了减少内存占用,页表可以存储为5:6:5 RGB纹理。物理页面坐标存储在5位组件中,物理页面的mip级别的页面宽度的两个对数存储在6位组件中。 exp2()函数用于计算片段程序中物理页面的mip级别的实际页面宽度。

   5:6:5的值在片段程序中可用时,会在硬件中转换为浮点范围[0,1]。不幸的是,就像8位浮点转换一样,这种转换也是硬件特定的。在某些硬件上,通过将高位位复制到低位位,首先将5:6:5值转换为8位。例如,对于5位值,所有位首先被复制到8位值的最高有效位,然后最高有效3位被复制到8位值的最低有效位3位。

  在某些硬件上,8位值在转换为FP32之前,通过转换为256位转换为FP16,而在其他硬件上,8位值被直接转换为FP32。在其他硬件上,5:6:5的值通过位复制直接转换为浮点数,而无需先转到8位值。用于虚拟到物理转换的片段程序需要考虑所有这些硬件差异。为了进一步复杂化,即使指数是精确的整数,exp2()函数也不过是对某些硬件的近似。例如,exp2(10)可能不是精确的1024.因此,一个微小的值被添加到指数,使得2 ^指数总是比2 ^ int(指数)大,但不能大于2 ^ int(exponent)+ 1。对于exp2()函数的结果,将使用floor()函数来获得两个完整的整数幂。使用5:6:5 RGB页表的片段程序中的实现可以在附录A.6中找到。这些差异的表现

虚拟到物理平台的实现。使用单个8位每个组件RGBA页表的实现是所有平台上最快的方法之一,因为它不涉及依赖的纹理读取,并且在存储器带宽和计算之间进行公平的交换。不幸的是,页表大小叠加,特别是如果有多个大的虚拟纹理同时有效。或者,5:6:5 RGB页表使用一半的存储器,并且需要较少的存储器带宽,代价是几个片段程序指令。在计算费用高昂的平台上,具有独立映射纹理的8:8页表可以提供最佳性能。使用mip映射页面纹理的虚拟到物理转换要比使用四叉树结构更快,对于访问的每个更细微的细节级别,依赖读取。然而,与仅存储四叉树相比,当使用mip映射的页表格纹理时,页表更新更昂贵。考虑何时映射虚拟纹理的第一页:整个页表格纹理必须使用单个纹素值填充。当nextfiner页面被映射时,必须更新四分之一的纹素,等等。幸运的是,更多的表更新很少发生。不用使用四叉树页表或页表纹理,哈希表可以在访问延迟,内存占用和计算之间建立中间位置。

     只有驻留的纹理页面存储在哈希表中。在哈希表中找到一个虚拟页面,其中包含从页面的mip级别和(x,y)坐标计算出的哈希值。一个很好的哈希键功能与一个小的哈希表相结合,例如,它只有9个物理页面的数量(比如2048个条目)的两倍),通常会导致非常少的冲突,从而允许使用单个内存访问来查找最近的页面。

   虚拟纹理四叉树中的页面的空间索引,可以用哈希表大小的模数作为哈希密钥。然而,如果虚拟页面的(x,y)坐标首先在mip级别重新映射,使得在四叉树中彼此靠近的页面不映射到相同的散列表条目,则实现更好的结果。散列表如果在物理页面池中还没有可用的更精细的mip,则不提供自动机制从acoarser mip返回到纹理页面。相反,当在哈希表中找不到所需的页面时,将不得不计算下一个较粗的页面的哈希键,以试图从哈希表中提取下一个较粗的页面。如果下一个粗糙页面也不驻留,则必须重复此过程,直到找到有效的页面。如果大部分期望的页面都是常驻值,则哈希表访问延迟比四叉树页表好得多。然而,在最坏的情况下,当驻留很少或没有页面时,必须计算多个冲突密钥,并且需要多个存储器访问。散列表的内存脚印很小,只是比四叉树页表小的一个因素。尽管散列表提供了四叉树表格和apage表格纹理之间的有趣的中间位置,但是在大多数硬件上,页表格纹理的直接访问是首选的,每个虚拟页面只有2个字节,页表格纹理的内存要求通常是可以接受的。

     3.2纹理过滤在没有特殊图形硬件支持的情况下,虚拟纹理的不幸复杂之处在于纹理单元不知道实际的纹理页面,不能跨页边界过滤。在虚拟纹理空间中相邻的纹理页面不一定映射彼此相邻的物理页面,更不用说在物理纹理中彼此靠近。不使用过滤器硬件,完全实现纹理过滤成本太高边缘程序。可以使用双线性滤波,同时以牺牲一些片段程序指令为代价迫使边缘纹理元素相等。然而,物理页面之间的地址不能被使用,这意味着这种“夹紧”页面的真实宽度与物理页面宽度相比,其实际宽度是一个无纹理的宽度,周边的半纹理无人地带。这些张开的页面也有一个根本的缺陷,在mip级别的转换中,纹理变换显示为令人反感的接缝。为了适当地支持硬件双线性滤波,每个物理纹理页面必须具有围绕它的纹素的边界。在没有特殊图形硬件支持的情况下,软件中虚拟纹理的实现也不能透明地支持三线性滤波。允许硬件加速三线性过滤的一个直截了当的方法是使用物理页面存储一个mip级别的纹理,但这将牺牲内存占用的25%的增加和增加的不足和带宽来填充这个mip级别。当使用块压缩的物理文件时,也不一定从较粗的虚拟mip到较粗的物理mip的平滑过渡。例如,如果纹理页面具有4纹理边界,那么第一个mip将显示物理纹理,其中页面是具有2纹理边界和2纹理偏移量的一半大小的页面,这会导致与虚拟mip.10另一种实现三线性过滤的方法是在渲染过程中访问两个虚拟页面,确定它们之间的LOD分数并计算加权平均值。即使使用amip映射的页面表格纹理实现,单个虚拟到物理转换的成本也会导致显着的开销。

    然而,有趣的是,第一笔翻译的成本背后隐藏着一些开销。然而,使用两个虚拟到物理平移的三线性滤波通常仍然相当昂贵。为了提高视觉保真度,各向异性滤波倾向于比三线滤波更重要。如果页面边框宽度超过1,则可以支持硬件加速各向异性过滤。因此,通常在每个物理页面周围使用4纹理边界。换句话说,如果一个页面是128 x 128的纹素,那么有效载荷就是120 x 120的纹理,由一个4纹理包围,纹理来自相邻的虚拟页面。 4纹理边界可以很好地映射到硬件支持的压缩格式(DXT,S3TC,ETC等)的4×4块大小,并允许合理的质量各向异性过滤,最大各向异性高达8.Ideally,虚拟纹理坐标用于计算各向异性足迹,并使用明确指定导数的纹理提取对物理页进行采样。这需要对衍生物进行缩放,以便在纹理坐标来自不同的mip级别时具有不同的尺度。比例因子是虚拟mip级别的大小与物理纹理的大小之间的比率。当使用一个或多个映射纹理进行虚拟物理转换时,必须使用附加纹理组件单独存储此比例因子。在FP32x4映射纹理的情况下,比例因子可以被赋予未使用的组件。当使用三个FP32x1或两个16位定点映射纹理时,必须添加一个额外的纹理或纹理组件来存储比例因子。


     当在片段程序中使用8:8:8:8或5:6:5页表纹理计算虚拟到物理映射时,需要存储额外的数据。在这些情况下,销售因子可以在片段程序中计算,如附录A.5和A.6所示。计算和缩放导数会增加片段程序的复杂性,并且在各种硬件上,使用显式导数的纹理提取更昂贵,这可能使得该解从性能的角度来看,没有吸引力。相反,可以使用具有隐式计算的导数的物理纹理坐标上的硬件加速各向异性。由于物理纹理空间在页面边界处不连续,因此会导致跨虚拟页面边界的四分片的不同的各向异性足迹。相邻虚拟纹理空间的纹理页面不一定映射到彼此相邻的物理页面,彼此靠近。然而,即使对于虚拟页面交叉,衍生物可能会随着任意方向变得太大,当最大各向异性小于等于边界宽度的两倍时,各向异性足迹仍然限于单个物理纹理页面。

      在大多数硬件上,页面边界上的错误的脚印是合理的性能与质量跟踪。虽然人造物以最大各向异性增加,即使具有更高的各向异性设置,质量实际上是令人惊讶的好,并且错误的脚印仅在显着放大倍率下显着。不幸的是,当在ATI / AMD硬件上的物理纹理坐标上使用硬件加速各向异性时,在由硬件选择的虚拟页面交叉点在页面边界之外,并产生令人反感的伪像,尽管最大11个各向异性设置小于等于页面边框宽度的两倍。在这个硬件上,使用非mip映射的物理纹理的各向异性过滤假定为理想的mip级别,而不是实际的mip级别,并且因此对于虚拟页面交叉,这些步骤可能太大了。幸运的是,大多数ATI / AMD硬件明确地计算衍生物,缩放它们并使用具有显式衍生物的纹理提取具有良好的性能,这是优选的方法。正常情况下,当从mip映射纹理获取纹理数据时,使用多个mip级别的纹素。

即使一个额外的map提供了用于物理纹理的p电平以允许三线性滤波,使用常规纹理查找对页表纹理进行点采样,不知道随后的各向异性纹理提取。页面表格必须进行点采样,以检索单个页面映射,而不会影响相邻但独立的页面映射之间的数据混合。使用纹理硬件topoint-sample页面表格纹理不一定会导致与物理纹理页面的映射,并具有以下各向异性纹理提取的相应纹理细节。没有任何调整,页表查找返回到物理纹理页面的映射,该页面特征太粗糙,并且提供的细节太少。为了提供各向异性纹理提取的附加纹理细节,页表查找可以用最大各向异性的负基数 - 双对数进行偏移。这允许各向异性纹理提取与表面上的附加纹理细节以与采样的脚印最大化(各向异性)的观看者倾斜的角度一起工作。然而,这可能导致与采样覆盖区最小(各向同性)的视图方向正交的明显的闪烁或凹陷表面。为了提高质量,可以根据各向异性在片段程序中计算页表纹理查找的纹理LOD。然后,计算出的LOD可以被隐式地传递给页表格纹理查找。

纹理LOD的计算如下所示.const float maxAniso = 4; const float maxAnisoLog2 = log2(maxAniso); const float virtPagesWide = 1024; const float pageWidth = 128; const float pageBorder = 4; const float virtTexelsWide = virtPagesWide *(pageWidth - 2 * pageBorder); float2 texcoords = virtCoords.xy * virtTexelsWide; float2 dx = ddx(texcoords); float2 dy = ddy(texcoords); float px = dot(dx,dx); float py = dot(dy,dy) ; float maxLod = 0.5 * log2(max(px,py)); // log2(sqrt())= 0.5 * log2()float minLod = 0.5 * log2(min(px,py)); float anisoLOD = maxLod - min(maxLod - minLod,maxAnisoLog2);

显然计算纹理LOD增加了片段程序的计算复杂度。然而,有趣的是,与使用常数LODbias相比,由于更好的纹理缓存使用,某些性能得到回升。对于与视图方向最垂直的表面,计算的LOD导致选择mip级别12,其中纹理样本彼此更接近。然而,由于额外的片段程序复杂性,从性能的角度来看,基于各向异性足迹选择mip级别可能是不吸引人的。相反,使用4的最大各向异性和以恒定的负2偏置的可折叠纹理查找通常导致质量和性能之间的合理交易,其中与观看者倾斜角度的表面显着更尖锐,同时出现在与表面正交的表面上的闪烁或混叠3.3.3从多个虚拟地址的渲染通常需要为同一模型提供不同的纹理数据来进行定制或指定损坏,团队等。在传统的API使用中,可以使用单独的集合纹理纹理或包含所有可能的皮肤的纹理数组。

    使用虚拟纹理,皮肤在单个大型虚拟纹理中分配自己独特的空间,并提供每个皮肤的基础纹理(s,t)地址,用于抵消顶点程序中的虚拟纹理坐标.Damage皮肤需要多个虚拟每个片段的物理翻译,以便从多个纹理源混合。事实证明,比起第二个翻译的成本很好地落后于第一个翻译,成本便宜得多。适当地使用每个片段的两个虚拟物理翻译可以非常有效地显示本地化的损害,同时保持性能。3.4反馈渲染虽然稀疏的表示使得可以使用部分驻留的纹理进行渲染,但需要反馈来确定纹理的哪些部分需要居民。纹理反馈渲染到单独的缓冲区,对于当前场景中使用的虚拟纹理页面,存储虚拟页面坐标(x,y),所需的mip级别和虚拟纹理ID(以允许多个虚拟纹理)。然后,该信息用于使那些需要呈现场景的纹理页面居住。

     在现有的渲染过程中,反馈可以在单独的渲染过程中渲染,也可以渲染到另外的渲染目标。渲染反馈的一个优点是反馈已被适当深度测试,因此虚拟纹理流水线不受最终不可见的纹理页面请求的影响。当使用单独的渲染通道时,以很低的分辨率(例如10xsmaller)渲染反馈是很好的。可用于的片段程序渲染到反馈缓冲区如附录B.13所示。图6:具有应用于全局测量的虚拟纹理的场景。图7:相同场景的反馈缓冲区。只有纹理坐标而不是实际纹理数据在反馈渲染通道中使用,这意味着alpha测试和透明表面被认为是完全不透明的。事实上,通常不可能使用alpha测试或透明的虚拟纹理来生成反馈,因为这种纹理数据可能不是驻留的,并且在这样的纹理数据变得驻留之前,必须首先生成适当的反馈。

    为了正确地拉入通过alpha测试或透明表面可见的纹理数据,不完全不透明的可以随机地呈现给反馈缓冲区。类似地,当表面使用多个虚拟纹理源时,这些源可以在每个渲染帧中交替,使得随着时间的推移所有必需的纹理数据被拉入。不幸的是,这具有使虚拟纹理流水线不稳定的趋势,因为即使场景没有改变,也要求每个帧都有不同的纹理页面集合。请求一帧的页面可能会最终替换与前一帧相同的表面请求的页面。

   因此,系统可能永远不会稳定,页面可能会连续更换,而无需拉扯渲染场景所需的最高细节纹理数据。当表面使用多个虚拟纹理源时,一个解决方案是在屏幕空间中交替使用不同的纹理来源,其中反馈缓冲器的每个其他像素从不同的源提取纹理数据。当从两个不同的来源渲染时,这将产生一个简单的检查板模式,但是当从多个资源进行渲染时,可以使用更复杂的模式。

     这种方法可能会增加当表面非常小并且覆盖相对较小的反馈缓冲区的非常少的像素时反馈不正确的可能性,但是实际上这不是一个明显的问题。类似的方法可以用于alpha测试或透明表面,其中由这样的表面覆盖的反馈缓冲器的每个其他像素被认为是完全透明的或完全不透明的。当使用简单的棋盘图案在完全透明和不透明之间进行交替时,并不是所有的纹理数据都可以被拉入到具有堆叠在彼此之上的多层alphatested或透明表面的场景中。

   使用更复杂的图案和每个alpha测试或透明表面的不同图案可以减轻这个问题。这与渲染具有屏幕透明度或字母到覆盖范围相似,如果反馈缓冲区的“alpha通道”不用于存储反馈数据,则某些硬件可能会用于此目的。在支持原子操作的较新图形硬件中可以实现每个pixellinked列表。这样的链表也称为结构化附加和消耗缓冲区。创建链表可以允许每个像素跟踪任意数量的数据元素。每个表面的每层透明度或每个不同虚拟纹理源的虚拟纹理反馈数据可以简单地附加到每像素存储的数据链中。以一定的复杂性为代价,当方法测试或透明表面非常小并且覆盖相对较小的反馈缓冲区的非常少的像素时,该方法减少了反馈的欠采样的可能性。

   反馈渲染遍历的结果在单独的过程中被分析。这个过程可以安装并等待反馈渲染,但是使用帧旧的数据并引起延迟的时候通常很好。反馈分析步行屏幕缓冲区,并将页面信息压缩到具有唯一页面的列表中。有效地,反馈分析创建四维代表代表mip-map层次结构,所有页面需要驻留以适当地适应当前场景。分析过程对页面进行优先排序。

    首先,优先考虑的是,所需的mip级别距离实际驻留mip级别越远,优先级越高。第二,优先级随着特定页面的样本数量的增加而增加,反馈缓冲区中增加。虚拟纹理系统使用排序的页面来维护已经驻留的可见页面的保留,并且首先在非驻留页面中流式传输,这将极大地提高当前呈现的场景的视觉质量.3.5超订阅在具有虚拟存储的任何系统中,物理存储不足以保持工作集,并发生抖动。这是虚拟纹理系统在不损失性能的情况下进行的。跟踪上一帧反馈中看到的驻留页面的数量。如果该数字大于高水位,系统将被超额认购并且在产生反馈时使用的LOD偏置增加。如果数字小于低水位标记,则系统被认为是低估,并且在产生反馈时使用的LODbias递减。动态反馈LOD偏差总是被夹持,以避免它变得负面。对于不能提供足够的细节的视图,这种机制可以避免细节的细节,但是后来将细节添加到系统没有紧张的地方。图8:具有32 x 32页的物理纹理。已订阅的系统已经完全分辨图9:具有8 x 8页的物理纹理。具有一切模糊的超订单系统。当从mip映射纹理渲染时,在理论上应该不需要更多的texelsthan约4倍的屏幕分辨率。然而,即使有足够的物理页面可以占用屏幕分辨率的四倍以上(考虑到页面边界),系统也可能会超额认购。其原因是纹理页面大小和几何被展开到虚拟纹理上的方式的组合。纹理空间相对较小的物体,并且具有面向不同方向的多个面可能会在所有面都展开到同一纹理页面上时产生显着的变化。同时,只有几个方面是可见的,而这些对象需要将整个纹理页面拉入页面中的最多纹素可能不可见。使用较小的纹理页面可能会减少插入但不需要的纹素的数量。然而,较小的页面浪费了边框的相对空间,而对于较大的页表需要更多的内存。使用128 x 128texels的页面通常是一个合理的交易.3.6 LOD捕捉/纹理弹出有时会发生,尽管所有努力,在需要纹理页面的时间和数据的时间之间会产生显着的延迟可用。

   当页面的期望的LOD关闭多于一个级别时,这可能导致不愉快的“pop”,并且LOD突然变得可用。如果采用三个虚拟到物理翻译的三线性过滤,那么直接的方法是在所期望的水平不足够接近当前显示水平的时候,将过渡从更粗糙到更精细的水平的过渡包括一些延迟。延迟可以被编码到页面表或映射纹理中。当使用具有单个mip级别的双线性或各向异性滤波时,需要不同的方法。

     而不是在渲染过程中使用三线性过滤,物理页面可以通过更粗糙和更精细的mip之间的某种混合来连续更新。直到更好的mip级别可用并且通过从较粗略的mip级别的采样版本开始进行分阶段似乎是一个合理的解决方案。但是,由于样本位置在上采样图像映射时突然变化,因此不会完全删除纹理弹出。不可能创建两倍于其他纹理的分辨率的纹理,当两者在纹素中心之间以双线性放大显示时,都会产生完全相同的双线性滤波器图案。双线性放大可有效地在纹理中心之间产生无法复制的纹理波形图案,该纹理纹理不能用分辨率的纹理复制,也可以用双线性放大进行渲染。分辨率两倍的纹理表现出三角形波顶和底部截止或某些其他近似的图案。结果是从双线性放大的较粗糙的mip到通过上采样较粗略的mip创建的finer mip的可见“pop”。

     图10:分辨率N和2x之间的纹素中心之间的双线性滤波。更好的解决方案是创建一个在较粗大的mip放大之前,从较粗略的mip通过采样获得更精细的mip的物理页面。从较粗糙的mipthrough上采样创建的更精细的mip将随着观点接近纹理表面逐渐进入。没有明显的弹出,从较粗糙的mip通过采样创建的更精细的mip可以在实际更精细的mip可用时被混合。

      这不会有突然的过渡,因为只有纹素颜色发生变化,而不是样本的位置。可以使用各种有趣的算法来通过上采样coarsermip来创建更精细的mip级别。例如,可以使用简单的双立方体滤波器。然而,也可以使用更复杂的边缘化过滤器。如果没有原始纹理内容可用,通过上采样创建更好的芯片,一旦它们被渲染,也可以用于创建有趣的细节[35] .174。

     Storage&Streaming4.1存储和压缩为了适应普遍应用的虚拟纹理,使用3个物理页面纹理,它们存储相同的物理页面但不同的数据。这3个纹理共存储10个通道。有一个纹理使用在片段程序中呈现时转换回RGB的YCoCg颜色空间存储漫反射图。还存在一个纹理,其存储在渲染期间在片段程序中导出正交的Z分量的切线空间法线图的X和Y分量。电源图存储在相同纹理的一个通道中。最后,有一个纹理存储镜面图,无论是单色还是RGB颜色。该纹理还存储1位Alpha通道(遮罩)。视频存储器中的物理纹理可以被存储为未压缩或DXT压缩[30,31]。

     希望进行DXT压缩,以减少渲染时的视频内存使用和带宽需求。三个DXT压缩纹理用于存储物理页面纹理:一个DXT1用于具有alpha [32]的镜面映射,一个DXT5用于YCoCg漫射映射[33],一个DXT5用于切线空间法线贴图[34]地图。未压缩,每个物理页面消耗192 kB,而压缩到DXT格式物理页面占用40kB。图11:虚拟纹理通道布局。磁盘上的页面可以存储未压缩,DXT压缩或可变比特率压缩格式,如JPEG-像基于DCT的格式[27]或HD-Photo [28] / JPEG-XR [29]。高压缩比是必要的,以便能够在像DVD这样的光盘上可用的有限存储空间上存储非常大的独特纹理世界。还需要高压缩18比特以减少从低于存储设备的纹理数据流传输的带宽要求。因此,可变比特率压缩格式用于存储磁盘上的纹理图像,将大多数纹理页面减少到1到6 kB之间。使用纹理过滤的4纹理插入边框和128 x 128纹理像素的物理页面大小每页只有120 x 120的有效载荷。因此,适当的纹理过滤所需的边界在附加纹素中花费大约12%。边框纹理不需要存储在磁盘上,但实际上,使页面完全独立,实际上将额外的12%纹理存储在磁盘上是不那么复杂.4.2改进压缩比率在将纹理数据压缩到磁盘之前,它可以以几种方式处理以提高压缩比。

     例如,漫反射映射可以基于所使用的压缩算法被子采样到4:2:0的YCoCg。类似地,如果没有显着的颜色信息,镜面图可以转换为单色,或者YCoCg颜色空间可以与4:2:0的次采样一起使用。当使用预先计算的照明解决方案时,可以实现额外的节省 - 镜面反射。例如,基于离散辐射度的全局照明算法可用于计算环境中的静态照明,其中仅使用一些近似法实时计算镜面反射。对于这样的近似来看,镜面映射被(离线计算)阴影减小,以减少阴影区域中的镜面反射。这减少了阴影区域中镜面映射的动态范围,并提高了压缩率。有时镜像地图纹理值可以完全省略。如果环境中独特的纹理素材的入射光从所有方向(相同颜色和强度)几乎相同,则可以将恒定的镜面反射移动到预先点亮的“漫射”图,并且不需要存储纹素的镜面值。

     当使用预先计算的照明时,正常的X和Y分量也可以用镜面强度进行缩放,通过减小动态范围来提高压缩比。毕竟,当使用预先计算的照明时,表面凹凸大部分已经被烘烤到漫反射图中,否则只有在存在动态镜面反射时可见。减少X和Y分量的大小导致运行时间衍生的Z分量增加到大小,这意味着正切空间正常将会收敛到表面的指向,使得所观察到的颠簸度随着镜面反射减小而减小。基于镜面照明降低感知到的颠簸在质量上略有损失,但损失质量通常很小,而存储节省则显着.4.3基于可见度的优化大型虚拟纹理降低了独特纹理数据的成本,但是在一个非常大的虚拟世界中,通常会有许多对于观众无法访问的区域,或者可以被看到只有一点距离。特别是在电脑游戏中,会有很多表面永远不会被关闭。

    因此,执行离线强力分析可以非常有用,可以查看19个可视性,捕获全方位的虚拟纹理反馈数据,并为所有可能的观察者位置标记可以显示的数据。在一个电脑游戏中,这个暴力的可见度确定可以,例如,基于播放器导航空间(配置空间)的地板表面的采样。首先,捕获每个纹理可见性是有用的。为了减少存储要求,可以在虚拟纹理中跟踪4x4纹理像素的可见性。然后可以使用此可见性信息来消除永远无法看到的整个页面。换句话说,虚拟纹理不仅稀疏地驻留在视频存储器中,虚拟纹理也可以用源数据稀疏地填充。此外,可见性信息还可用于模糊页面的不可见部分,以改善其压缩。

     其次,可以采集数据来优化纹理空间中几何相邻的几何的纹理区域分配,在“图集”中通常称为“图表” “在文学中。记录图表ID,样本数量,导数的最小导数,最小比例和最大比率,而不是捕获纹理可见性。然后,该信息用于缩放纹理空间中的对象,使得所有对象在虚拟纹理上占据合理的空间,而不仅仅是基于每个世界单元的纹素数,而且基于可见性。这不仅使苏打水罐的纹理密度高于它所坐的计数器的20倍,而且还允许将虚拟纹理上的图表缩小,这些图形永远不会被关闭。当首次构建非常大的纹理图集时,没有可用性信息可用于确定纹理空间图应该占用多少,并且对于每个图表使用基于世界空间区域的一些估计。

     最好的LOD数据是按照图表收集的,基于附加信息重新优化了图集.4.4布局和位置虚拟纹理上纹理数据的布局对实时应用至关重要,因为寻找光盘的倍数大约是100+ ms,而通过互联网流式传输纹理数据时,会考虑类似的延迟。在具有本地硬盘的系统上,长时间不需要数据的危险可以大大降低。不幸的是,并不是所有系统都有硬盘,或者有限的硬盘空间可用于缓存纹理数据。有在优化虚拟纹理的布局时,重要的几个指标。具有一致的纹素密度是非常重要的,使得虚拟纹理空间不会浪费永远不可见的LODtexel。如上一节所述,可以基于暴力收集的可见性信息来优化几何图形“图表”的纹理分配。然后将图表放置在虚拟纹理上,以便浪费最少的空间。图表可能有奇数在某些相对位置上只能很好地结合在一起的形状。图表的方向也可以改变到更适合的地方。

    然而,当仅使用缩放和偏置来执行虚拟地址处理时,这需要更改几何体中的纹理坐标以解决方位改变。旋转图也使优化过程显着更复杂.20尽量减少浪费空间的重要性,同样重要的是优化虚拟纹理上“图表”的位置,使得任何渲染的场景都使用最少的纹理页面。这是一个困难的优化问题,有时与虚拟纹理上浪费的空间最小化相冲突。对于局部性和最少量的浪费空间进行优化是网格参数化和NP-hard的bin-packing问题的组合。

    首先通过3D二进制空间分区对图表进行空间分类,然后走树,可以找到合理的解决方案首先呼吸,同时分配2D纹理空间与2D局部性的空间填充曲线。一旦所有图表最佳地放置在虚拟纹理上,重要的是优化光盘上的纹理页面的位置,使得任何渲染的场景需要最少的搜索量在所需的纹理数据中。以前的工作[26]建议以四叉树顺序布置页面,可能会交织多个mip级别。这适用于一个大部分平坦的连续地形。然而,对于适用于任意3D环境的虚拟纹理,情况会更加复杂.4.5流和CachingCachesCache可以用于在流经常使用的纹理页面时显着降低延迟。当用于存储最近看到的纹理页面时,系统内存中的高速缓存在减少使用以前查看的区域的纹理数据更新物理页面的延迟方面非常有效,例如当视图突然回到观看者所在的地方时。当纹理页面从光盘流式传输到系统内存,可以将其写回到硬盘缓存,以便将来的访问速度更快,并且不会受到更多的追求时间的影响。

     对于高穿孔通常情况下,多个软件线程用于从相对较慢的存储设备(如硬盘或光盘)中恢复纹理页面,其中为每个存储设备实现单独的线程。压缩比在10:1到20:1范围内可变位速率压缩和DXT固定块压缩,重要的是尽可能长时间保持数据完全压缩,以最佳地利用可用内存。纹理数据存储在视频存储器中的4个不同位置:光盘,硬盘,系统内存和物理页面纹理。数据在所有高速缓存级别中使用可变比特率压缩格式进行压缩,以接收物理页面的纹理。所有虚拟内存系统中,虚拟纹理系统可以具有被“固定”的存储区域,即总是驻留且不能被替换的纹理页面。例如,代表虚拟纹理的最粗略的mip级别的纹理页面通常被锁定在物理页面纹理中,以确保总是有一些纹理数据回落到当视点突然改变为具有所有新纹理数据的场景时。

   215。物理页面更新

5.1流水线概述

图12显示了物理页面更新流程的概述。将ascene的纹理反馈渲染到一个小屏幕缓冲区。该屏幕缓冲区的颜色值用于对当前渲染场景的像素的虚拟纹理页面进行跟踪。从这个缓冲区,反馈分析创建一个排序列表,其中包含需要驻留的纹理页面。来自反馈分析的排序页面用于首先更新非常驻地页面,这些页面将最大限度地提高当前渲染场景的视觉质量。对于已经存在于物理纹理中的可见页面,维护居住权。图12:物理页面更新流水线。对于每个排序页面,系统尝试从缓存中获取压缩的纹理数据。在高速缓存命中的情况下,压缩的纹理数据将被隐藏,并且高速缓存计划错过在后台加载。对于已压缩纹理数据的纹理页面,系统会分配一个新的物理页面。在使用新的物理页面之前,它是未映射的,以确保GPU停止使用该页面并且下降到较粗的父页面。然后将经压缩的纹理页面进行转码,以使其可以用于在GPU上呈现。只有在对完整的纹理页面进行转码之后,才会映射GPU,从而开始渲染.

5.2替换策略

当需要分配新的物理页面以存储所请求的虚拟页面时,所有的物理页面都将根据优先级进行排序,最重要的是使用重新布置。

   优先级首先是基于页面的LOD级别,使得更好的mips将首先被替换。这意味着表示具有驻留页面的mip层次结构的四叉树通过删除和添加叶节点逐渐地改变结构。接下来,重新放置的页面优先级随着上次使用页面的渲染帧数而增加。换句话说,最好的mip级别页面被替换为最近最少使用的(LRU)替换策略.253.3代码变量比特率压缩非常高压缩比用于在由光盘提供的有限存储器上存储非常大的简单纹理的世界,并且在从光盘流式传输纹理数据时也减少带宽要求。固定比特率DXT压缩纹理用于GPU上的内存带宽和占用空间。当新的纹理页面从磁盘流式传输或从高速缓存中提取时,必须从JPEG格式或HD-Photo / JPEG-XR转换为DXT格式。

     Thistranscode过程是一个重要的计算负载,并且通过并行作业处理系统并行执行,该系统将作业卸载到任何可用的和适用于任务的处理器。为了改善负载平衡,每个页面添加两个作业,每个页面需要重新转码,其中每个作业对页面数据的一部分进行转码。在正常操作期间,大约8到16页被转码为每个渲染帧,从而导致16到32个作业。当以60Hz的帧速率每帧16帧,每页128×128个纹素,这导致大约15MegaTexels /秒(MT / s)的吞吐量。在直接访问纹理内存的系统上,转码器可以将DXT压缩的纹理块直接写入视频内存.

5.4异步更新

 在具有直接访问纹理内存的系统中,寻呼系统与GPU异步运行。每一帧,系统确定是否需要使可用的纹理页面更多,并且将重新使用的页面立即被取消映射。这使得GPU开始使用较粗的父页面。页面的纹素不会被覆盖,直到页面被取消映射,并且新页面没有被映射,直到其所有的纹素都存在。这加工确保即使页表和物理页面连续不断地更新,维护虚拟纹理的一致性。存在纹理缓存的风险与纹理内存不一致,但实际上,冲洗orin验证纹理缓存的操作通常足够,从而不会发生错误的行为。结果6.1地址转换使用附录C中所示的片段程序,在几个平台上测量了虚拟到物理的翻译性能。对于此性能测试,单屏幕对齐四分之一渲染具有100个驻留纹理页面,以1280的分辨率覆盖整个屏幕x720.表1:虚拟到物理翻译的表现。页表/ mappingtexture格式页面大小为1024x1024页



    在较旧的ATI / AMD硬件中,使用虚拟纹理坐标来计算各向异性脚印,并使用带有显式导数的纹理提取。这是必要的,以避免在使用隐式计算的导数的物理纹理坐标上的硬件加速各向异性时出现的有害伪像。使用隐式计算的导数的ATI / AMD硬件的性能显示在表1中的括号之间进行比较。6.2页表更新页表更新由部分页表纹理更新和可能使用的任何映射纹理中的单个纹理更新组成。更新映射纹理不仅仅是高效的单一纹素写,这不是很贵。

     但是,基于正在映射的虚拟页面,页表更新可能会更昂贵。当虚拟页面被映射时,来自与虚拟页面对应的mip级别的页面表texel和其mip级别被更新。接下来,两个正方形区域的纹素的权力在页面纹理的任何更精细的mip级别更新,对应于存储映射的虚拟页面的更精细图像细节的虚拟页面。

     例如,当第一个最粗糙的虚拟纹理页面被映射时,页表的完整mip-map层次结构中的所有纹素设置为相同的值。如果下一个更精细的页面被映射,则四分之一的纹素必须被更新,等等。这些更新的性能与写入到squarepage表纹理区域的纹素数量成正比,这返回与mip级别相关映射的虚拟页面。在具有直接存储器访问的系统上,性能仅受限于可写入存储器的速度。

    然而,在通过像OpenGL或DirectX这样的API直接访问视频内存的系统上,页面表更新面临着重要的API开销。目前的API不支持子映像“memset”操作,只有子映像数据副本。为了有效地“记忆”页表mip级别的正方体纹理区域,相同的纹素值24首先多次写入主存储器块,然后通过API传输该数据,以更新视频存储器中的平方纹理区域。反馈分析反馈分析的性能与反馈缓冲区的大小成正比。 Asmaller反馈缓冲区提高了反馈分析的性能,但它导致对纹理数据进行粗体抽样,其中虚拟页面可能不会立即被视为可见。实际上,使用比场景渲染的分辨率要小10倍的反馈缓冲区没有明显的视觉异常。反馈分析可以在GPU上实现。然而,通常有足够的CPU时间可用,特别是例如IBM Cell SPE。在这个平台和多核PC上,反馈分析的消耗量为80x60像素的反馈缓冲器的CPU时间为0.5毫秒。这种性能是通过使用散列表来查找在四叉树中构建的页面的父类,以从反馈缓冲区中提取唯一的页面列表来实现的.6.4存储系统中使用的纹理页面是128 x 128纹素,带有4纹理插入边框和120个x120纹素有效载荷。


    为了最佳地使用可用的视频存储器,具有边缘的纹理页面是两个的功率,而有效载荷是两个的幂。在一些硬件上,物理纹理的最大尺寸是两个(如4096 x 4096)的强度,并且具有128页128的两页大小的功能,确切的页数可以适应物理纹理,而不浪费任何空间。物理纹理尺寸通常为4096×4096纹素,等于32×32纹理页面。当存储在视频存储器中的DXT压缩时,three 4096 x 4096物理纹理(存储10个通道)在一起消耗40 MB。较新的硬件可支持更大的物理纹理(16k x 16ktexels),而较旧的硬件可能不支持大于4096 x 4096纹素的纹理。要增加旧硬件上的物理页面数量,可以使用3D纹理。这将使虚拟到物理翻译仅稍微复杂一点,但是很多硬件不支持3D纹理上的各向异性过滤,这使得该解决方案不具吸引力。

    相反,可以使用立方体贴图纹理,但是会使地址转换显得更复杂。增加物理页面数量的最简单方法是以多组物理纹理的形式创建多个单独的物理页面池。然而,这需要不同的几何从不同的方式分配页面,而不是每个渲染的场景都可以以均匀的几何形式结束,使得所有图形池都能够同样填充。使用字节存储物理页面坐标的虚拟到物理的翻译允许最大256 x 256物理页面,当纹理页面大小为128 x 128纹素时,相当于32k x 32ktexels的物理纹理。

   使用a5:6:5页表的虚拟到物理转换只能支持多达32 x 32个物理页面,当纹理页面大小为128 x 128纹素时,它们会累积到物理图案大小4096 x 4096。

   另一方面,虚拟纹理可以高达240k x 240k的纹素(其中240k = 2048 *有效载荷大小),在这种情况下,2字节或5:6:5页表格纹理消耗10.66 MB的内存。不管最大大小,120k x 120k虚拟纹理通常用于减少可折叠的纹理记忆。对于120k x 120k的虚拟纹理,页表纹理消耗2.66MB的内存。

   在计算机游戏RAGE中,大多数环境中使用单个120k x 120k虚拟纹理,用于所有静态几何,另外还有120k x 120k虚拟纹理,用于环境中的动态对象。一些非常大的户外环境使用多个虚拟纹理进行静态几何。每个虚拟纹理都有自己的页面表,但是多个虚拟纹理可以映射到物理页面的对象池,但是它们也可以映射到单独的物理页面池。

   一个未压缩的完全填充的120k x 120k虚拟纹理,每个纹理带有12个通道(其中2个未使用)需要225 GB的无边框存储空间和256 GB的边框。压缩到DXT格式,这样的虚拟纹理仍然占用53 GB。对于计算机游戏RAGE中的大多数静态环境,120k x 120k虚拟纹理未完全填充。许多最好的mip纹理页面永远不可见,不需要存储。此外,在完整分辨率下永远不可见的页面的任何部分都可以模糊,从而显着提高可变比特率压缩率。表2显示了计算机gameRAGE的几个环境中用于静态几何的虚拟纹理的大小。表2:虚拟纹理大小(每个纹理元素为10个组件)。环境#页未压缩DXT JPEG像HD-PhotoWellspring 112102 21023 MB(96 b / t,192 kB / p)4379 MB(20 b / t,40 kB / p)334 MB(1.5 b / t,3.1 kB / p )170 MB(0.8 b / t,1.6 kB / p)Bash TV 115879 21731 MB(96 b / t,192 kB / p)4526 MB(20 b / t,40 kB / p)358 MB(1.6 b / t ,3.2kB / p)205MB(0.9b / t,1.8kB / p)RC-Bomb Base 244357 45826MB(96b / t,192kB / p)9545MB(20b / t,40kB / p) 777 MB(1.6 b / t,3.2 kB / p)416 MB(0.9 b / t,1.8 kB / p)在表2中,平均位/ texel(b / t)和平均页大小(kB / p )显示在括号之间.6.5 TranscodeTranscoding

 纹理页面是一个重要的计算负载,并且通过并行作业处理系统并行执行,该系统将作业卸载到任何可用于和适合于任务的处理器区域。

 

    在较新的图形硬件上,纹理页面转码可以实现在GPU上运行。在具有少量CPU内核的系统上,这可以将不利的计算负载卸载到GPU,允许将CPU内核用于其他目的。然而,旧的图形硬件可能没有实现转码的必要功能,或者GPU已经完全占用了渲染和没有时间可用于额外的计算负载。在这样的系统上,代码转换被实现为在可用的CPU内核上运行,如Cell PPE和Cell SPE的硬件线程。表3显示了以每秒兆兆赫(MT / s)表示的几种不同处理器的DXT压缩性能。表3:DXT压缩性能。 3.2 GHz 45nm Intel Core 2采用单核心3.2 GHz IBM Cell使用单个PPE硬件线程3.2 GHz IBM单芯片SPEDXT1 - RGB镜面+二进制Alpha 252 MT / s 160 MT / s 334 MT / sDXT5 - YCoCg漫射128 MT / s 75 MT / s 150 MT / sDXT5 - XY-正常+功率203 MT / s 115 MT / s 240 MT / s下图显示了以MegaT表示的几种不同处理器的可变比特率解压缩性能

比例缩放性能.RGB 4:2:0 JPEG像RGB 4:4:4 HD-PhotoYCoCg 4:2:0 JPEG-like YCoCg 4: 4:4 HD-PhotoXY-Normal JPEG-like XY-Normal HD-Photo27

     很明显的是,HD-Photo解压缩比解压缩JPEG格式更昂贵。然而,HD-Photo通常允许将纹理数据压缩到几乎等于JPEG样数据的大小,同时保持相同的保真度并且通常减少或消除无效的压缩伪像。因此,在比较HD-Photo和JPEG样格式之间的性能时,需要考虑不同的压缩比。

    例如,将20:1 JPEG样压缩数据与40:1 HD-Photo压缩数据进行比较是合理的。还要注意,4:2:0子采样用于RGB和YCoCg的JPEG样压缩数据。因此,只有一半的数据被推送到通过HD-Photo解码器推送的4:4:4采样数据的JPEG样解码器中。下图显示了几个不同处理器的完整转码性能。

  转码性能( 10个组件每个纹理).JPEG样 - > DXT HD-Photo - > DXT286.6 Visuals使用描述的解决方案的虚拟纹理系统已经在电脑游戏RAGE中成功实施和使用。这个游戏以高帧率(60 FPS)运行在各种平台上,如Microsoft Windows PC,Apple Macintosh PC,Xbox 360和PlayStation 3上的各种图形硬件。


    以下是电脑游戏RAGE的一些室外环境照片RAGE.297环境镜头。结论虚拟纹理与其他形式的虚拟内存不同,因为首先,可以在不停止执行的情况下将其复制到略微模糊的数据;其次,数据的有损压缩对于大多数应用是完全可以接受的。软件虚拟纹理的实现利用虚拟纹理和其他形式的虚拟内存之间的这些关键差异来保持性能并以牺牲质量降低内存需求。实现没有特殊硬件支持的虚拟纹理具有挑战性,涉及许多细微??之处,不可避免地会降低性能,内存需求和质量之间的正确交易。这里介绍的解决方案允许以高性能实现非常大的虚拟纹理,同时要求最少的内存占用,而且质量损失很小。使用所描述的解决方案的虚拟纹理系统已经被成功地实现并运用在运行在诸如Microsoft Windows PC,Apple Macintosh PC,Xbox 360和PlayStation 3.8等不同平台上的各种图形硬件上的计算机可读RAGE中。未来方向一种用于纹理反馈的反应系统工作良好,因为虚拟纹理系统具有内在容忍性。

    然而,单独的反馈渲染通过成本高,并且希望将其与正常的渲染过程相结合。当将反馈传递与正常渲染通过组合时,重要的是反馈被适当深度测试,以避免对最终不可见的纹理页面的请求强调虚拟纹理流水线。如果在管道上执行一个单独的显式深度通过,那么值得考虑用这个深度通过写出反馈。在许多平台上,仅深度通过双倍速度深度写入的优点,并且这样的渲染通常通常结束isgeometry(顶点)限制。通过使用深度通过写出反馈,深度将不再以双倍速度写入,并且添加额外的片段成本来计算反馈,因此渲染遍可能变得片段受限。基于投射的几何量和具体的GPU性能特征,这可以是一个积极的交易,因为不再是单独的反馈通过,几乎总是几何(顶点)由于反馈缓冲器的小尺寸而受到限制。

  当使用多个渲染目标时,也可以在单次传递中投影深度,颜色和反馈。这具有能够对反馈和页表查找使用各向异性LOD计算的附加益处。纹理过滤是即使在当前和未来的可编程图形硬件上也在固定功能硬件中实现的,因为在软件中完全执行纹理过滤(即片段程序)成本很高。没有特殊图形硬件支持的虚拟纹理的不幸复杂之处在于,不知道实际纹理页面的纹理单元不能跨页边界过滤。然而,如果虚拟到物理转换在硬件中实现,则通过对纹理过滤器所需的每个纹素进行地址转换,可以在硬件中实现适当的纹理过滤。这意味着硬件实现
     使用8个虚拟到物理翻译进行三线性过滤的纹理提取,如果纹理位置位于最近的较粗略的mip级别的页面角上,则可能会触发多达8个不同的纹理页面。各向异性纹理提取可能需要更多的虚拟到物理平移.30当硬件中已经实现了常规虚拟内存系统时,希望采用这种系统来实现硬件中的虚拟纹理系统。

     虚拟内存页面可用于存储纹理页面,虚拟内存页面表可用于纹理数据的虚拟到物理转换。然而,一个复杂的问题之一是,虚拟内存系统不了解mip层次结构中的纹理页面之间的关系,如果finermip尚不可用,则不能自动从较粗略的mip返回页面。当更精细的mip的页面不可用时,虚拟内存系统可以简单地返回页面错误,并且可以使用更高的最小LODclamp重试纹理提取。然而,下一次尝试也可能失败,并且在性能成本下可能需要进行几次重试。

    另一种解决方案可能是将附加信息存储在虚拟存储器系统的页表中,以允许虚拟物理转换自动地从较粗略的mip返回到一个页面,如果更精细的mip不可用。这种方法的不足之处在于,这种膨胀的页面表也可能用于除了该信息没有意义的纹理之外的数据,并且简单地是浪费的。除了在页表中存储附加信息之外,还可以选择维护“minLOD”纹理存储虚拟纹理的每个页面驻留在物理内存中的最小LOD。显然,这样的纹理必须与虚拟存储器系统的页表完全同步以避免页面错误。可以使用这种“最小LOD”纹理的纹理查找来检索要钳位的实际虚拟纹理查找所需的LOD,以避免页面错误。不幸的是,三维线性,特别是虚拟纹理上的各向异性纹理查找可能会跨越几个小时的几个页面边界。因此,必须使用“最大过滤器”对“最小LOD”纹理进行采样,并具有对应于所关注的虚拟纹理查找的占用空间的适当覆盖区。这需要在硬件中实现“最大纹理过滤器”,并以快速的方式根据虚拟纹理查找的覆盖度将样本覆盖度确定为“最小LOD”纹理。这样一个“最小LOD”纹理也可以用于混合在更精细的芯片中,为了避免LOD咔哒咔哒的“弹出”纹理细节,尽管所有努力,在需要页面的时间与其数据可用时间之间存在显着的延迟。当使用“minLOD”纹理时,当新页面映射到新页面时,可以逐渐调整该纹理的纹理。

References1。

用于地形可视化的综合多分辨率几何和纹理模型Konstantin Baumann,JürgenD?llner,Klaus HinrichsJoint Eurographics-IEEE TCVG可视化研讨会,2000年5月可在线获取:http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.26 。

 50012。地形可视化的纹理技术JürgenD?llner,Konstantin Baumann,Klaus HinrichsIEEE Visualization,pp。227-234,2000可在线获取:http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.26.49923 。

使用分块级别的细节控制渲染大量地形.Thatcher UlrichSIGGRAPH课程注释,2002可在线获取:http://tulrich.com/geekstuff/sig-notes.pdf4 。

视图依赖的渲染多解决方案纹理图集Henrik Buchholz,JürgenD?llnerIEEE可视化,p。 28,2005可在线获取:http://www.hpi.unipotsdam.de/doellner/publications/year/2005/919/BD05.html5 。

 Terrain Rendering in High Levels DetailJonathan BlowBolt Action Software,May,2000可在线获取:http://number-none.com/blow/papers/terrain_rendering.pdf6 。

自适应4-8纹理层次结构Lok M.Hwa,Mark A.Duchaineau,Kenneth I. JoyIEEE Visualization,pp。219-226,October 2004可在线获取:http://www.llnl.gov/tid/lof/documents/pdf/310387 .pdf7。

 Clipmap:虚拟MipmapChristopher C. Tanner,Christopher J. Migdal,Michael T. Jones SIGGRAPH 98的成果,第151-158页,1998年7月可在线获取:http://www.cs.virginia.edu/~gfx/Courses/2002 /BigData/papers/Texturing/Clipmap.pdf8。

GPURoger Crawfis的剪贴画,Eric Noble,Michael Ford,Frederic Kuck,Eric Wagner俄亥俄州立大学,OSU-CISRC-4/07-TR24,2007年4月可在线获取:ftp://ftp.cse.ohio-state.edu /pub/tech-report/2007/TR24.pdf9。硬件独立剪贴簿安东尼奥Seoane,Javier Taibo,LuisHernández第十五届中欧计算机图形,可视化与计算机视觉国际会议(WSCG 2007)可用Online:http://wscg.zcu.cz/WSCG2007/Papers_2007/full/A89-full.pdf3210 。

基于剪贴图的地形数据综合Matalte Clasen,Hans-Christian HegeSimVis 2007在线可用:http://www.zib.de/clasen/download/ClipmapSynthesis.pdf11 。

 Terrain Rendering using Spherical ClipmapsMalte Clasen,Hans-Christian HegeEuroVis 2006 Proc。

 Eurographics / IEEE VGTC Symposium on Visualization,pp。91 -98,2006.可在线获取:

http://www.zib.de/clasen/download/SphericalClipmaps_Electronic.pdf12。虚拟纹理:GPUAnton Ephanov的大面积光栅资源,Chris ColemanInserservice /行业培训,模拟和教育会议(I / ITSEC)2006在线提供:http://lists.modsim.org/devrim_extras/2006IITSEC_VTPaper_2.pdf13。纹理平铺可视性确定动态纹理LoadingMichael E. Goss,Kei YuasaEUROGRAPHICS / SIGGRAPH 1998 Workshop on Graphics Hardware,pp。55-60,LisbonPortugal,Aug./Sept。 1998可在线获取:http://www.hpl.hp.com/research/mmsl/publications/3d/texturetilevisibility.pdf14。 Interactive Display of Very Large TexturesDavid Cline,Parris K.EgbertProceedings of the conference on Visualization,pp。343-350,October 1998可在线获取:http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.72 。

 457115。一种基于感知的纹理缓存算法,用于基于硬件的渲染Reynald Dumont,Fabio Pellacini,James A. Ferwerda第12届欧洲图像研讨会的渲染技术研讨会,第249-256,2001页,网址:http://www.cs.dartmouth.edu /~fabio/papers/textures01.pdf16。

 Adaptive Texture MapsMartin Kraus,Thomas ErtGraphics Hardware,pp。1?10,2002可在线获取:http://www.vis.uni-stuttgart.de/eng/research/pub/pub2002/hwws02-kraus.pdf17。用于任意网格的统一纹理管理Lefebvre,JéromeDarbon,Fabrice Neyret Institut国家信息自动化(INRIA),2004年5月可在线获取:

http://www-evasion.imag.fr/Publications/2004/LDN04/RR-5210 .pdf18。 TileTreesSylvain Lefebvre,Carsten Dachsbacher ACM SIGGRAPH交互式3D图形和游戏研讨会的成果-2007可在线获取:http://www-sop.inria.fr/reves/Basilic/2007/LD07/LD07.pdf3319。高级虚拟纹理主题在3D图形和游戏课程中进行实时渲染的进步。SIGGRAPH 2008在线可用:

http://portal.acm.org/citation.cfm?id=1404435.140443820。稀疏的虚拟纹理Sie BarretGame开发者大会2008在线可用:http://silverspaceship.com/src/svt/21。 Virtual TexturingAndreas NeuRWTH亚琛大学,2010年4月可在线获取:http://www.graphics.rwthaachen.de/uploads/media/neu_virtual_texturing_high_03.pdf22。实施虚拟纹理学安德森技术大学,2010年5月可在线获取:http://epubl.ltu.se/1404-5494/2010/009/LTU-HIP-EX-10009-SE.pdf23。虚拟纹理映射101Matthaus G.Chajdas,Christian Eisenacher,Marc Stamminger,Sylvain LefebvreGPU Pro,第3.4节,2010年7月1日在线提供:http://www.akpeters.com/product.asp?ProdCode=472824。加速虚拟纹理使用CUDACharles-Frederik Hollemeersch,Bart Pieters,Peter Lambert,Rik van de WalleGPU Pro,第10.2节,2010年7月1日在线提供:http://www.akpeters.com/product.asp?ProdCode=472825。 Glift:图形硬件的通用数据结构Aaron E. LefohnPh.D。论文,计算机科学系,加利福尼亚大学戴维斯分校,2006年9月可在线获取:http://graphics.idav.ucdavis.edu/~lefohn/work/dissertation/26。慢速存储设备的地理空间纹理流。 van WaverenIntel软件网络,2008年6月可在线获取:http://softwarecommunity.intel.com/articles/eng/3865.htm27。实时纹理流和解压缩J.M.P。 van WaverenIntel软件网络,2007年3月可在线获取:http://softwarecommunity.intel.com/articles/eng/1221.htm28。高清照片:数字摄影的新型图像编码技术Sridhar Srinivasan,Chengjie Tu,Shankar L. Regunathan,Gary J. SullivanProc。 SPIE,Vol。 6696,September 2007可在线:http://spie.org/x648.html?product_id=7678403429 。

 JPEG XR图像编码系统 - 图像编码规范ISO / IEC FDIS 29199-2 | ITU-T建议书草案T.832PEG文件WG 1 N 4918,2009年2月可在线获取:http://www.iso.org/iso/catalogue_detail.htm?csnumber=5160930 。

压缩纹理资源(Direct3D 9)Microsoft Developer NetworkMSDN,2007年11月可在线:

http://msdn2.microsoft.com/en-us/library/bb204843.aspx31 。

块压缩(Direct3D 10)Microsoft Developer NetworkMSDN,

2007年11月可在线:http://msdn2.microsoft.com/en-us/library/bb694531.aspx32 。

实时DXT压缩van WaverenIntel软件网络,2006年10月可在线获取:http://www.intel.com/cd/ids/developer/asmo-na/eng/324337.htm33。实时YCoCg-DXT压缩van Waveren,IgnacioCasta?oNVIDIA,October 2007可在线:http://developer.nvidia.com/object/real-time-ycocg-dxt-compression.html34 。实时法线贴图DXT

   CompressionJ.M.P。 van Waveren,IgnacioCasta?oNVIDIA开发人员网站,2008年3月可在线获取:http://developer.nvidia.com/object/real-time-normal-map-dxtcompression.html35。图像通过纹理进行抽样HallucinationYoav HaCohen,Raanan Fattal,Dani Lischinski国际计算问题解决会议(ICCP),2010在线可用:http://www.cs.huji.ac.il/~yoavhacohen/upsampling/35 附录A - 虚拟物理翻译

附录A - 虚拟到物理翻译
/ *
版权所有(c)2012,Id Software LLC,ZeniMax Media Company。
作者:J.M.P.范·波伦
特此授予任何人的免费许可
获取此软件和相关文档的副本
文件(“软件”),无需处理软件
限制,包括但不限于使用权,
复制,修改,合并,发布,分发,再许可和/或销售
该软件的副本,并允许谁的人
提供软件以做到这一点,但须遵守以下规定
条件:
上述版权声明和本许可声明应为
包含在本软件的所有副本或大部分内容中。
该软件“按原样”提供,不提供任何形式的保证,
明示或暗示,包括但不限于担保
适销性,适用于特定目的和
不侵权。在任何情况下,作者或版权
持有人对任何索赔,损害或其他责任负责,
无论是合同行为,侵权行为还是其他方式
从或与本软件或使用相关或不存在
软件中的其他交易。
* /
//常量
const int PageWidth = 128; // 128 x 128 texels per page
const int pageBorder = 4; // 4-texel inset border
const int physPagesWide = 32;                                      //每个物理纹理为4096 x 4096个纹素
const int virtPagesWide = 1024;                                       //每个虚拟纹理120K×120K的纹素

//派生常数,用于将虚拟页面中的偏移量缩放到物理页面中的偏移量

const float pageFracScale =(pageWidth - 2.0f * pageBorder)/(pageWidth * physPagesWide);
unsigned int physX,physY;         //物理页面的坐标(整页)
unsighed int physMipLevel;        //物理页面中存储的虚拟页面的mip级别
unsigned int virtX,virtY;           //虚拟页面的坐标(整页)
float physTexelsWide = physPagesWide * pageWidth;
float virtLevelPagesWide = virtPagesWide >> physMipLevel;

//可用于将虚拟地址转换为物理地址的比例和偏差。< BR >

 float scaleST = virtLevelPagesWide *(pageWidth - 2.0f * pageBorder)/ physTexelsWide;
float biasS =(physX * pageWidth + pageBorder)/
physTexelsWide - scaleST * virtX / virtLevelPagesWide;
float biasT =(physY * pageWidth + pageBorder)/
physTexelsWide - scaleST * virtY / virtLevelPagesWide;< BR >

//应用于虚拟纹理坐标导数的缩放因子
//用于各向异性纹理查找。< BR >

float derivativeScale = pageFracScale * virtLevelPagesWide;
//物理页面坐标转换为可以直接在片段中使用的8位值
//程序从每个物理页面的一个纹理像素查找映射纹理的比例和偏差。
unsigned char texelPhysX =(无符号字符)((physX /(physPagesWide - 1.0f))* 255.0f + 0.01f);
unsigned char texelPhysY =(unsigned char)((physY /(physPagesWide - 1.0f))* 255.0f + 0.01f);

A.1 - FP32x4页表
//页表是一个四分量32位浮点纹理存储
//第一个分量的比例和最后两个分量的S,T偏差。
//
// float pageTable.texel [4] = {scaleST,derivativeScale,biasS,biasT};
//
//对于1024 x 1024页的虚拟纹理,页表= 21.33 MB。
static float2 VirtualToPhysicalTranslation(sampler2D pageTable,float2 virtCoords){
 float4 scaleBias = tex2D(pageTable,virtCoords);
 return virtCoords * scaleBias.x + scaleBias.zw;
 // float derivativeScale = scaleBias.y;
}
 A.2 - 8:8页表+ FP32x4映射纹理
//页表是一个8位每个组件无符号整数亮度 - alpha纹理
//存储要用于虚拟页面的物理页面的X,Y坐标。
//还使用一个单一的4组件32位浮点映射纹理与缩放
//存储在第一个组件中,S,T bias存储在最后两个组件中。
//
// unsigned char pageTable.texel [2] = {texelPhysX,texelPhysY};
// float physPageScaleBias.texel [4] = {scaleST,derivativeScale,biasS,biasT};
//
//对于1024 x 1024页的虚拟纹理和32 x 32页的物理纹理
//页表= 2.66 MB,映射纹理为16 kB。
static float2 VirtualToPhysicalTranslation(sampler2D pageTable,
 sampler2D physPageScaleBias,float2 virtCoords){
 half2 physicalPage = tex2D(pageTable,virtCoords).xw;
 float4 scaleBias = tex2D(physPageScaleBias,physicalPage);
 return virtCoords * scaleBias.x + scaleBias.zw;
 // float derivativeScale = scaleBias.y;
}
 A.3 - 8:8页表+ 3/4 x FP32x1映射纹理
//页表是一个8位每个组件无符号整数亮度 - alpha纹理
//存储要用于虚拟页面的物理页面的X,Y坐标。
//还使用三个单一组件32位浮点映射纹理。
//一个存储刻度,两个用于S,T偏置。
//
// unsigned char pageTable.texel [2] = {texelPhysX,texelPhysY};
// float physPageScale.texel [1] = {scaleST};
// float physPageBiasS.texel [1] = {biasS};
// float physPageBiasT.texel [1] = {biasT};
// float virtCoordScale.texel [1] = {derivativeScale};
//
//对于1024 x 1024页的虚拟纹理和32 x 32页的物理纹理
//页表= 2.66 MB,映射纹理为12 kB。
static float2 VirtualToPhysicalTranslation(sampler2D pageTable,
 sampler2D physPageScale,
 sampler2D physPageBiasS,
 sampler2D physPageBiasT,float2,virtCoords){
 half2 physicalPage = tex2D(pageTable,virtCoords).xw;
 float scaleST = tex2D(physPageScale,physicalPage).x;
 float biasS = tex2D(physPageBasS,physicalPage).x;
 float biasT = tex2D(physPageBiasT,physicalPage).x;
 返回virtCoords * scaleST + float2(biasS,biasT);
 // float derivativeScale = tex2D(virtCoordScale,physicalPage)。 X;

A.4 - 8:8页表+ UINT16x1 / 2 + UINT16x2映射纹理
//页表是一个8位每个组件无符号整数亮度 - alpha纹理
//存储要用于虚拟页面的物理页面的X,Y坐标。
//同时使用两个无符号定点16位每个组件映射纹理。
//一个亮度纹理用单个组件存储刻度
//和一个亮度-a纹理与两个组件来存储S,T偏置。
//
// unsigned char pageTable.texel [2] = {texelPhysX,texelPhysY};
// unsigned short physPageScale.texel [1/2] = {
//(unsigned short)(scaleST *(65535.0f / 32.0f)+ 0.5f),
// derivativeScale
//};
// unsigned short physPageBias.texel [2] = {
//(unsigned short)((biasS + 30.0f)*(65535.0f / 32.0f)+ 0.5f),
//(unsigned short)((biasT + 30.0f)*(65535.0f / 32.0f)+ 0.5f)
//};
//
//对于1024 x 1024页的虚拟纹理和32 x 32页的物理纹理
//页表= 2.66 MB,映射纹理为6 kB。
static float2 VirtualToPhysicalTranslation(sampler2D pageTable,
 sampler2D physPageScale,
 sampler2D physPageBias,float2 virtCoords){
 half2 physicalPage = tex2D(pageTable,virtCoords).xw;
 float4 scaleST = tex2D(physPageScale,physicalPage)* 32.0;
 float4 biasST = tex2D(physPageBias,physicalPage)* 32.0;
 返回virtCoords * scaleST.x + biasST.xw - 30.0;
 // float derivativeScale = scaleST.y;
}
 A.5 - 8:8:8:8页表
//页面表格为8位每个组件RGBA格式,具有物理页面坐标
//存储在前两个组件和存储在最后两个组件中的比例。
//
// unsigned short scale =(virtPagesWide * 16)>> physMipLevel;
// unsigned char pageTable.texel [4] = {physX,physY,scale&0xFF,scale >> 8};
//
//对于1024 x 1024页的虚拟纹理,页表= 5.33 MB。
static float2 VirtualToPhysicalTranslation(sampler2D pageTable,float2 virtCoords){
 //常量
 const float pageWidth = 128; // 128 x 128 texels per page
 const float pageBorder = 4; // 4-texel inset border
 const float physPagesWide = 32;                                 //每个物理纹理为4096 x 4096个纹素
 //乘数来撤消硬件特定的转换
 //无符号字节[0,255]到范围[0,1]中的浮点值。

#if defined(GEFORCE_7800)||定义(RADEON_X1900)
 const float floatToByte = 255. 0 + 1.0 / 256.0;
#其他
 const float floatToByte = 255.0;
#万一
 //派生的常量
 const float pageFracScale =(pageWidth - 2 * pageBorder)/ pageWidth / physPagesWide;
 const float borderOffset = pageBorder / pageWidth / physPagesWide;
 const float4 texScale = {
 floatToByte / physPagesWide,
 floatToByte / physPagesWide,
 floatToByte * 1.0 / 16.0,
 floatToByte * 256.0 / 16.0
 };
 const float 4 texBias = {borderOffset,borderOffset,0,0};
 //虚拟到物理翻译
 float4 physPage = tex2D(pageTable,virtCoords)* texScale + texBias;
 float2 pageFrac = frac(virtCoords *(physPage.z + physPage.w));
 return pageFrac * pageFracScale + physPage.xy;
 // float derivativeScale = pageFracScale *(physPage.z + physPage.w);

A.6 - 5:6:5页表
//页表是RGB 565格式,存储物理页坐标
//在5位元件中的log2和物理宽度的页面
//页面的mip级存储在6位组件中。
//
// unsigned short pageTable.texel [1] = {
//((physX * 32 / physPagesWide)<< 11)|
//((log2(virtPagesWide) - physMipLevel)<< 5)|
//((physY * 32 / physPagesWide)<< 0)
//};
//
//对于1024 x 1024页的虚拟纹理,页表= 2.66 MB。
//
//在准确执行exp2()的平台上,1.0 / 4096.0
//添加可以删除,并且floor()不需要包含'y'
//组件,它删除依赖关系并提高性能。
static float2 VirtualToPhysicalTranslation(sampler2D pageTable,float2 virtCoords){
 //常量
 const float pageWidth = 128; // 128 x 128 texels per page
 const float pageBorder = 4; // 4-texel inset border
 const float physPagesWide = 32; //每个物理纹理为4096 x 4096个纹素
 //乘数来撤消硬件特定的转换
 // 5位或6位值到范围[0,1]中的浮点值。
#if defined(GEFORCE_7800)
 const float floatToPagesWide =(255.0 + 1.0 / 256.0)/ 256.0 * physPagesWide;
 const float floatToMip =(255.0 + 1.0 / 256.0)/ 256.0 * 64.0;
#elif defined(RADEON_X1900)
 const float floatToPagesWide =(31.0 + 1.0 / 33.0)/ 32.0 * physPagesWide;
 const float floatToMip =(63.0 + 1. 0 / 65.0);
#其他
 const float floatToPagesWide = 255.0 / 256.0 * physPagesWide;
 const float floatToMip = 255.0 / 256.0 * 64.0;
#万一
 //派生的常量
 const float pageFracScale =(pageWidth - 2 * pageBorder)/ pageWidth / physPagesWide;
 const float borderOffset = pageBorder / pageWidth / physPagesWide;
 const float4 texScale = {
 floatToPagesWide,
 floatToMip,
 floatToPagesWide,
 0
 };
 //将小的值添加到指数中,以便我们可以对不准确的exp2()结果进行处理
 const float4 texBias = {0,1.0 / 4096.0,0,0};
 //翻译
 half4 physPage = tex2D(pageTable,virtCoords)* texScale + texBias;
 physPage.y = exp2(physPage.y);
 physPage = floor(physPage); //记录不准确的exp2()和条带复制位
 float2 pageFrac = frac(virtCoords * physPage.y);
 return pageFrac * pageFracScale + physPage.xz / physPagesWide + borderOffset;
 // float derivativeScale = pageFracScale * physPage.y< /P > < P >  }

附录B - 反馈片段程序
uniform float virtualTextureID;
均匀浮动反馈// log2(feedbackWidth / windowWidth)+ dynamicLODbias
struct PS_IN {
 float4 texcoord0:TEXCOORD0;
};
struct PS_OUT {
 float4反馈:COLOR;
};
void main(PS_IN fragment,out PS_OUT result){
 const float maxAniso = 4;
 const float maxAnisoLog2 = log2(maxAniso);
 const float virtPagesWide = 1024;
 const float pageWidth = 128;
 const float pageBorder = 4;
 const float virtTexelsWide = virtPagesWide *(pageWidth - 2 * pageBorder);
 float2 texcoords = fragment.texcoord0.xy * virtTexelsWide;
 float2 dx = ddx(texcoords);
 float2 dy = ddy(texcoords);
 float px = dot(dx,dx);
 float py = dot(dy,dy);
 float maxLod = 0.5 * log2(max(px,py)); // log2(sqrt())= 0.5 * log2()
 float minLod = 0.5 * log2(min(px,py));
 float anisoLOD = maxLod - min(maxLod - minLod,maxAnisoLog2);
 float desiredLod = max(anisoLOD + feedbackBias,0.0);
 result.feedback.xy = fragment.texcoord0.xy * virtPagesWide; < BR >  result.feedback.z = desiredLod; < BR>  result.feedback.w= virtualTextureID; < /P> < P> } < BR >

附录C - 虚拟纹理片段程序(双线性分析)
uniform sampler2D physicalTextureDiffuse;
均匀采样器2D physicalTextureSpecular;
均匀采样器2D physicalTextureNormal;
uniform sampler2D pageTable;
struct PS_IN {
 float4 texcoord0:TEXCOORD0;
};
struct PS_OUT {
 float4颜色:COLOR;
};
void main(PS_IN fragment,out PS_OUT result){
 float3 physCoords = VirtualToPhysicalTranslation(pageTable,fragment.texcoord0.xy);
#if定义(RADEON_X1900)
 float2 dx = ddx(fragment.texcoord0.xy)* physCoords.z;
 float2 dy = ddy(fragment.texcoord0.xy)* physCoords.z;
 half4 diffuseYCoCg = tex2D(physicalTextureDiffuse,physCoords.xy,dx,dy);
 half4 specularRGB = tex2D(physicalTextureSpecular,physCoords.xy,dx,dy);
 half4 normalXY = tex2D(physicalTextureNormal,physCoords.xy,dx,dy);
#其他
 half4 diffuseYCoCg = tex2D(physicalTextureDiffuse,physCoords.xy);
 half4 specularRGB = tex2D(physicalTextureSpecular,physCoords.xy);
 half4 normalXY = tex2D(physicalTextureNormal,physCoords.xy);
#万一
 半分散;
 diffuseYCoCg.z = 1.0 /((diffuseYCoCg.z * 255.0 / 8.0)+ 1.0);
 diffuseYCoCg.xy * = diffuseYCoCg.z;
 diffuse.r = dot4(diffuseYCoCg,half4(1.0,-1.0,0.0,1.0));
 diffuse.g = dot4(diffuseYCoCg,half4(0.0,1.0,-0.5 * 256.0 / 255.0,1.0));
 diffuse.b = dot4(diffuseYCoCg,half4(-1.0,-1.0,1.0 * 256.0 / 255.0,1.0)); < BR>  half3 normal = normalXY.wyz * 2.0 - 1.0;
 normal.z = 1.0 - sqrt(dot(normal.xy,normal.xy)); < BR > result.color.rgb = diffuse.rgb + normal.xyz * half3(0.707,0.707,0)* specularRGB.rgb;< /P > < P > }

附录D - 虚拟纹理片段程序
(三线性各向异性+反馈)
uniform sampler2D physicalTextureDiffuse;
均匀采样器2D physicalTextureSpecular;
均匀采样器2D physicalTextureNormal;
uniform sampler2D pageTable; //假定是FP32x4
uniform float virtualTextureID;
均匀浮动反馈// log2(feedbackWidth / windowWidth)+ dynamicLODbias
struct PS_IN {
float4 texcoord0:TEXCOORD0;
};
struct PS_OUT {
float4 color:COLOR0;
float4 :COLOR1;
};
void main(PS_IN fragment,out PS_OUT result){
const float maxAniso = 4;
const float maxAnisoLog2 = log2(maxAniso);
const float virtPagesWide = 1024;
const float pageWidth = 128;
const float pageBorder = 4;
const float virtTexelsWide = virtPagesWide *(pageWidth - 2 * pageBorder);
float2 texcoords = fragment.texcoord0.xy * virtTexelsWide;
float2 dx = ddx(texcoords);
float2 dy = ddy(texcoords);
float px = dot(dx,dx);
float py = dot(dy,dy);
float maxLod = 0.5 * log2(max(px,py)); // log2(sqrt())= 0.5 * log2()
float minLod = 0.5 * log2(min(px,py));
float anisoLOD = maxLod - min(maxLod - minLod,maxAnisoLog2);
float4 virtCoordsLod1 = float4(fragment.texcoord0.x,fragment.texcoord0.y,0.0,anisoLOD - 0.5);
float4 virtCoordsLod2 = float4(fragment.texcoord0.x,fragment.texcoord0.y,0.0,anisoLOD + 0.5);
float4 scaleBias1 = tex2Dlod(pageTable,virtCoordsLod1);
float4 scaleBias2 = tex2Dlod(pageTable,virtCoordsLod2);
float2 physCoords1 = fragment.texcoord0.xy * scaleBias1.x + scaleBias1.zw;
float2 physCoords2 = fragment.texcoord0.xy * scaleBias2.x + scaleBias2.zw;
#if定义(RADEON_X1900)
float2 dx = ddx(fragment.texcoord0.xy);
float2 dy = ddy(fragment.texcoord0.xy);
float2 dx1 = dx * scaleBias1.y;
float2 dy1 = dy * scaleBias1.y;
float2 dx2 = dx * scaleBias2.y;
float2 dy2 = dy * scaleBias2.y;
half4 diffuseYCoCg1 = tex2D(physicalTextureDiffuse,physCoords1.xy,dx1,dy1);
half4 specularRGB1 = tex2D(physicalTextureSpecular,physCoords1.xy,dx1,dy1);
half4 normalXY1 = tex2D(physicalTextureNormal,physCoords1.xy,dx1,dy1);
half4 diffuseYCoCg2 = tex2D(physicalTextureDiffuse,physCoords1.xy,dx2,dy2);
half4 specularRGB2 = tex2D(physicalTextureSpecular,physCoords1.xy,dx2,dy2);
half4 normalXY2 = tex2D(physicalTextureNormal,physCoords1.xy,dx2,dy2);
#其他
half4 diffuseYCoCg1 = tex2D(physicalTextureDiffuse,physCoords1.xy);
half4 specularRGB1 = tex2D(physicalTextureSpecular,physCoords1.xy);< BR >half4 normalXY1 = tex2D(physicalTextureNormal,physCoords1.xy);< BR > half4 diffuseYCoCg2 = tex2D(physicalTextureDiffuse,physCoords2.xy);< BR >half4 specularRGB2 = tex2D(physicalTextureSpecular,physCoords2.xy);< BR > half4 normalXY2 = tex2D(physicalTextureNormal,physCoords2.xy);< /P > < P >  

float trilinearFraction = fract( anisoLOD );
half4 diffuseYCoCg = lerp( diffuseYCoCg1, diffuseYCoCg2, trilinearFraction );
half4 specularRGB = lerp( specularRGB1, specularRGB2, trilinearFraction );
half4 normalXY = lerp( normalXY1, normalXY2, trilinearFraction );
half3 diffuse;
diffuseYCoCg.z = 1.0 / ( ( diffuseYCoCg.z * 255.0 / 8.0 ) + 1.0 );
diffuseYCoCg.xy *= diffuseYCoCg.z;
diffuse.r = dot4( diffuseYCoCg, half4( 1.0, -1.0, 0.0, 1.0 ) );
diffuse.g = dot4( diffuseYCoCg, half4( 0.0, 1.0, -0.5 * 256.0 / 255.0, 1.0 ) );
diffuse.b = dot4( diffuseYCoCg, half4( -1.0, -1.0, 1.0 * 256.0 / 255.0, 1.0 ) );
half3 normal = normalXY.wyz * 2.0 - 1.0;
normal.z = 1.0 - sqrt( dot( normal.xy, normal.xy ) );
result.color.rgb = diffuse.rgb + normal.xyz * half3( 0.707, 0.707, 0 ) * specularRGB.rgb; < BR> result.feedback.xy = fragment.texcoord0.xy * virtPagesWide; < BR > result.feedback.z = max( anisoLOD + feedbackBias, 0.0 ); < BR > result.feedback.w= virtualTextureID; < BR > }< /P > < P >  

0 0