- 精华
- 0
- 帖子
- 42
- 威望
- 0 点
- 积分
- 49 点
- 种子
- 5 点
- 注册时间
- 2009-5-14
- 最后登录
- 2020-1-19
|
发表于 2011-10-19 10:36 · 北京
|
显示全部楼层
weixiao86 发表于 2011-10-18 10:32
帮人转个回应
“我躺着中枪了。。。07的一篇clipmap介绍被说成误人子弟。这个上纲上线很严重。。。
续完
“预处理(补充)
预处理还有一步,忘了说。把所有物体的贴图拼接在一起变为一整张virtual texture(也就是megatexture,本篇继续使用virtual texture的叫法)后,世界中所有的物体都只使用virtual texture这么一张贴图。所以世界中物体的坐标都应该换算一下。
假设virtual texture是一张2097152x 2097152大小的贴图。 virtual texture左下角贴图坐标为0,0. 右上角贴图坐标为1,1. 根据一个物体贴图在virtual texture中所在的相对位置,用很简单的换算即可得到这个物体新的贴图坐标。
比如一个物体有一张512x256的长方形贴图。位于virtual texture中从横向第 1048576个像素,纵向第524288个像素开始。这样物体一个顶点的贴图坐标u,v (0<u<1 ,0<v<1)换算到virtual texture中,就是
u' = (u*512 + 1048576 )/ 2097152 ,
v'= (v*256+524288)/2097152
当贴图坐标 u,v<0 或者 u,v>1时,说明使用了纹理 tilling。贴图重复排列。这时的处理,需要在virtual texture中重复复制物体所用到的贴图。 然后把贴图坐标重新换算到0-1之间。再进行virtual texture贴图坐标转换。
步骤详解
下面详细解释渲染的3个步骤
1,判断要使用哪些page
page中不仅仅记录了物体原始贴图的某个部分,同时这个原始贴图的mipmap也都切成块当作page储存在virtual texture中。所以这一步骤不仅要找到位于物体用的贴图在virtual texture中的哪个部分,还要判断使用哪个mipmap,这样才能精确定位出物体渲染需要的所有pages。
大致的做法是这样。我们准备一张virtual texture的浓缩版本。这个浓缩版我们叫它 indirect texture。有的paper叫page table texture 。 我们用中文,叫"页表贴图" 。页表贴图的每个图素,对应着virtual texture中相应位置的page 。图素内容就是对应page在virtual texture中的坐标信息。
第一遍绘制场景时,所有的几何体都用这么一张固定的页表贴图(page table texture)来绘制。
详细解释一下:假如我们的显卡显存超大。可以一次性把virtual texture装载下来。那么场景中所有几何体只用绘制一次。用这张virtual texture就可以完成所有绘制任务。因为场景中所有几何体贴图坐标都是转换过的。对应的就是virtual texture的坐标。现在使用一张缩小的页表贴图 (page table texture)。绘制所有景物。想象一下,物体上面的贴图内容,其实就是这个物体所用贴图pages在virtual texture中的位置信息。
接下来就容易了,得到屏幕上的所有像素。逐一分析。每个像素的信息就是对应物体所用到贴图page的位置信息。 绘制时,我们还可以得到每个像素应该用到贴图mipmap的级数。这个级数也用来定位page的位置。
分析完毕,我们就有了当前屏幕上所有景物要用到的pages 。我们把本帧需要用到的page,叫“活跃page”
1680x1080 的屏幕上,像素个数是 1814400 个。 每个像素都检查一遍,CPU基本就废掉,不用做其他事情了。 优化的办法是对屏幕buffer做down sample 。也就是缩小屏幕pbuffer尺寸。只检查有限的像素。或者干脆直接在一个分辨率很小的pbuffer上绘制整个场景。诸如此类。
2,读入贴图page
知道要用到哪些page,很简单,就读入进来。其中用到的各种streaming优化,贴图压缩解压缩,就不提了。
显卡中维护一张真正最后渲染要用到的贴图。我们叫它“显存贴图” (physical page texture)。这张贴图边长是page尺寸的整倍数。读入的page贴图方块,就一个个在显存贴图中拼接起来。拼接的时候每个page周围还需要留条边。 大家都知道显卡最后纹理映射时,有个双线性插值的问题。而且随着物体离镜头越远,用的mipmap不同,对不同mipmap page周围留的边,还有粗细不同的问题。 总之这些零零碎碎的问题充斥着megatexture实现的所有步骤。
显存贴图(physical page texture)用page填充好之后,就可以最后渲染了
3,渲染
到这个阶段,我们已经实现了megatexture的大部分目标,挑选一帧中能够看到的物体用到的贴图,拼起来。这样我们就实时创建了一张贴图,这张贴图上面只有本帧需要绘制在屏幕上的贴图图素(当然肯定有一些冗余)。
那么如何绘制? 因为我们用pages拼凑而成的这张显存贴图(physical page texture),即便是相同物体用到的贴图,也都是一个个被切成小方块的page拼凑而成。page与page之间根本不挨着。不同mipmap的page也都并列排在显存贴图里。根本不连续。用这唯一一张贴图去绘制场景所有物体。需要额外步骤。
纹理映射的原理是根据一个像素的贴图坐标(注意这里是已经被光栅化后的像素级贴图坐标了),去贴图中采样图素(texel)。这个图素的颜色值,经过光照处理,就可以直接显示在屏幕像素上。
用page拼凑而成的显存贴图(physical page texture)正确显示场景中所有物体,需要对像素的贴图坐标进行一下转换。使得显示在屏幕上物体的每个像素,精确的对应到显存贴图(physical page texture)上它应该对应的位置。
我们需要一次像素级别的贴图坐标转换。这个任务可以由indirect texture sampler也就是间接贴图采样,即,对一张记录贴图坐标的贴图进行采样,获取最终贴图坐标,来完成这个任务。
这个记录贴图坐标的贴图,其实就是页表贴图(page table texture)。只不过这次我们使用的页表贴图,内容有些不同。
我们先定义一下“活跃page”。 活跃page的意思,是说凡是被拷贝到显存贴图(physical page texture)中的page,都要被标记为活跃page。
在第一步中,我们使用的页表贴图(page table texture)每个像素记录着每个page在virtual texture中的相对位置信息。作用是检测需要哪些page。而在第三步,这个页表贴图(page table texture)需要每帧更新,每个活跃page对应在页表贴图位置的图素内容,要记录这个活跃page在显存贴图(physical page texture)中的位置信息。
其实,这些内容如果没有图,不太可能光用语言描述清晰。这会在pdf中给出。
以下是过程简述:
用更新后的页表贴图(page table texture)与显存贴图(physical page texture)共同绘制场景所有物体,在pixel shader中进行一次贴图坐标间接寻址。从页表贴图(page table texture)中得到最终需要采样显存贴图(physical page texture)的贴图坐标。最后场景中的物体就都按照实际需求绘制出来了。
4,镜头快速转动与移动时
经过3个步骤,如果硬盘无限快速,而且显存贴图(physical page texture)的大小能够满足绘制本帧所有物体最大精度贴图。那么我们会看到一个无限大的世界,有着最高贴图精度。流畅地在眼前飘过。
事实上,没有这么理想的情况。 磁盘速度不可能那么快。显存贴图(physical page texture)有时候并不满足绘制当前镜头中所有物体最大精度贴图的容量。
这就是我们在实际《RAGE》游戏运行过程中看到的景象。一旦摇动一下镜头,所有物体的贴图都重新回到最模糊,然后慢慢变得精细。这个现象在PS3上尤其严重。PS3的IO是严重瓶颈。理论上就无法保证足够量的精细贴图在一定时间内读入显存。在一个 光驱,硬盘,内存,显存的4级cache系统中,任何一个地方的瓶颈足以毁灭megatexture美好的初衷。这是为什么。
回顾virtual texture技术的3个步骤。如果磁盘是瓶颈,很多激活page无法从磁盘调入显存。那么显存贴图(physical page texture)就无法在足够时间内拼凑出绘制当前场景所需要的全部贴图page。 怎么办。 这个时候有很多办法可想。 一个最简单的办法是,没有贴图的景物,就绘制个马赛克贴图好了。。。
当然,商业产品不能这么做。 如果调入高精度贴图来不及,那么就先把最低精度的贴图调入进来。
如果最低精度都进不来,那么卡帧,让用户休息一下。。。
从这里看出,megatexture受硬件制约依旧较大。只不过从明确的显存上限,降低到对IO速度的一定要求。
IO速度对于PC,可能越来越快。对于XBOX360,卡马克爱不释手自然会量身定做。至于PS3,那就算那些买正版的家伙们倒霉了。
另外一种情况,当前帧的场景中物体太多了,所用到的贴图总量,超过了显存贴图(physical page texture)容量。
很多物体都没有贴图来绘制。自然只能空在那里。解决方案无非就是尽量合理的把场景中物体用到的贴图量控制一下。这里面要解决的工程问题无限多。要自研此技术做产品的人,只能自求多福了。
还有一个问题。在第一步用页表贴图(page table texture)绘制时,页表贴图是一张完整调入显卡显存的贴图。它是virtual texture的浓缩版。根据page的大小来缩小。一个page相当于这个贴图的一个像素。但是当virtual texture中page数量太多,以至于页表贴图(page table texture)的大小都超标了,这就是个很麻烦的事了。
我们假设一个page 512x512像素(page大小的制定也有讲究,不细表)。如果想要在页表贴图(page table texture)保持在 4096x4096 大小,那么我们的一张virtual texture最大边长只能是 4096x512 像素。 也就是这张virtual texture最大也就2097152 x 2097152 像素大小。一个像素算4字节。那么最大的一张图容量是 4096 G 。 难道我们与时俱进的玩家就按么容易满足4T的贴图容量么?随着祖国日新月异国富民强,人民群众的审美娱乐需求一日提高,早晚有一天。。。。。。”
|
|