虚拟贴图理论之Feedback Rendering

在游戏中我们经常会更换贴图来换装,或者使用细节贴图去增强模型的表现效果,在不使用虚拟贴图的情况下,这些效果实现都是很自然的事情,比如换装直接更换材质的贴图,细节贴图就是在PS中读取多张贴图。现在如果我们使用了虚拟贴图技术,那么就会有一个问题摆在我们面前。我们回想一下虚拟贴图的寻址过程,在PS中我们根据虚拟uv坐标去indirect texture中索引坐标转换的参数,然后通过参数转换到物理坐标。一个uv坐标只能对应indirect texture中的一个像素,也就是说一个uv坐标只能对应一张贴图。如果shader中一个uv坐标需要对应多张贴图,最简单的办法就是提供一个offset,然后根据这个offset去寻址不同的贴图。

由于物理缓存有限我们需要存储当前Frame需要的page,为了获取这个page列表,我们首先要渲染一遍场景,然后根据屏幕上每一个像素使用的虚拟uv坐标获取使用的page以及mipmap等级。我们需要将这些信息存储到buffer中然后回传给cpu。PageID和mipmap等级是必须的,根据不同的需求可能还会回传一些其他信息,比如使用多张虚拟贴图,需要回传贴图ID,使用自适应虚拟贴图还要回传sector的size。回传是不可避免的,我们都知道回传很浪费性能,浪费性能主要是因为回传的带宽以及破坏了cpu及gpu并行处理的流程。如果不想回传只能使用软光栅化,但是这不现实,通常我们只会在遮挡剔除的时候使用软光栅化,因为渲染的都是少量的包围盒,并且会因此剔除大量的三角面片,所以使用软光栅化不亏。但是虚拟贴图技术使用软光栅化是得不偿失的。如果不想回传就只能离线渲染feedback信息了。还有一个办法就是使用clipmap,因为clipmap可以预知下一帧使用的贴图,所以不需要Feedback。通常每个page会占用屏幕多个像素,所以feedback的贴图可以使用比较低的分辨率,使用低分辨率的贴图有可能会漏掉一些page,但是漏掉的page因为占了屏幕很少的像素,使用低级别的mipmap层是可以接受的。使用低分辨率的贴图可以降低回传的带宽,而且也减少了我们处理page的数量。Feedback如下图:

我们在渲染feedback的时候需要开启深度测试,这样可以避免加载被遮挡的贴图。 但是对于半透明物体或者是带有alpha test的物体,这里就会有一个问题,简单理解就是为了保证半透效果,屏幕上的像素点可能对应多张贴图(因需要贴图混合)。这个问题就和OIT半透明渲染一样,必须记录每一个像素背后对应了多少张贴图。dx11(ps shader model 5.0之后)可以使用 Per-Pixel Linked Lists 技术来解决,这个技术同样可以解决OIT问题。如下图:

ps shader model 5.0之后,ps可以读写结构化buffer,而且还提供了原子操作,因此我们可以构建一个像素列表,里面存储每一个使用的贴图。其中start offset buffer存储链表的头部,而link buffer存储所有的贴图信息以及维护链表的next指针。我们可以在feedback之后使用computer shader对数据进一步处理,然后再回传给cpu。这个方案有两个问题第一,原子操作是性能杀手。会破坏并行运算。但是仔细想想这个和算法有关,你需要一个一个的渲染物体,然后把信息存储到buffer中,如果是并行运算,可能会有数据被覆盖从而丢失数据。另一个问题是link buffer很大,通常需要是屏幕分辨率的数倍,而且具体是多少我们并不清楚。虽然问题很明显,但是这个算法可以完美解决一个像素对应多张贴图的问题。还有一些算法可以hack解决这个问题,比如一帧渲染透明物体,一帧渲染不透明物体,这样就可以获取全部使用的贴图。但是这样做解决不了多个半透物体叠加的问题。另外也可能会照成前一帧加载的贴图,下一帧被卸载。我们需要在加载和卸载的策略中去尽量回避这些问题。

物理缓存的大小如果是屏幕分辨率的4倍就足够了,但是即使是4倍也会出现缓存不足的情况,这个和page的大小以及模型uv分布有关。某些物体即使只占了几个像素,我们也会把整张贴图加载进来,缩小page的大小可以降低这种浪费,但是却会增加边框的浪费,通常page使用128*128比较合适。如果出现缓存不足的情况,我们可以调整贴图的lod来尽量保证最佳效果。因为延迟的加载,可能会出现mipmap等级跨级的情况,这样会造成显示效果的突变。比如当前mipmap为4,突然变成mipmap为1的情况。我们需要做的是保证mipmap按等级逐级变化。比如当前mipmap等级是4,需要mipmap等级为1,我们可以先加载3,然后再加载2,最后加载1,这个可以在加载page的逻辑上进行处理。

之前我们一直讨论使用低分辨率的方式加速feedback,另外为了让cpu和gpu并行处理,我们可以延迟feedback的使用,比如第三帧处理第一帧的feedback,如果第三帧的时候第一帧还没有完成feedback则阻塞等待。这是一种常见的优化方案,实现原理是基于时间和空间的一致性。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值