Cache The RenderList

本文探讨了在游戏渲染中,如何通过缓存RenderList来优化性能,尤其是在物体数量众多时减少构建时间。当相机未移动时,利用上一帧的RenderList;相机移动时,根据物体的可见性更新RenderList。通过添加帧戳来标记物体可见性,减少无效绘制和内存操作。该策略能显著降低RenderList构建时间,提高5倍性能并减少内存碎片。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        大部分游戏渲染的时候都会构建一个管理Render物体的List,所以简称RenderList,所有要绘制的物体的RT,Shader,Texture,Shader Constant都是保存在这个数据结构里的,构建好RenderList之后才会把这些需求发给GPU执行。

        在场景物件很多的时候这个RenderList的构件时间极其夸张,有时候会占到Render线程一半的时间,更让人觉得接受不了的是很多时候Camera基本没怎么动这个开销依然还是那么大。因此降低这个RenderList的构件时间非常重要,因为按照优化准则,总是优化最费的那部分,RenderList这时候觉得算得上NO1了。

        我们可以想象,如果Camera不动,对于静态物体来说前一帧和当前帧画的物体一个没多一个没少,那么干嘛不把上一帧的RenderList拿来用呢?嗯,的确可以。如果Camera动起来了就不行了,因为有的物体可能看不见了,不需要再画了,有些物体上一帧没出现,camera转动之后可能当前帧看到了,需要加入新的物体到RenderList。而这时候上一帧看到并且这一帧还看到的物体占了RenderList的一大部分(比例依赖于Camera的转动幅度)。这么分析下来,思路已经很清楚了,对于上一帧出现,当前帧出现的物体继续保留,对于上一帧可见,当前帧不可见的物体垃圾回收掉,对于上一帧不可见当前帧可见的物体新增到RenderList里。

        那么怎么来标记在哪一帧可见呢?其实很简单给每一个RenderPack加一个FrameStamp即可

        

struct RenderPack
{
        .......//RenderPack Content
        u32  mFrameStamp;
};
       

        每一帧构建RenderList的时候会为每个RenderPack打标记,如果mFrameStamp==LastFrameStamp的话说明上一帧可见,并且当前帧依然可见,只需要更新mFrameStamp即可(这样就把构建一个RenderPack的操作优化为mFrameStamp的更新了),对于mFrameStamp==LastFrameStamp,而这一帧不可见的RenderPack就可以这一帧绘制的时候跳过,或者垃圾回收掉,对于mFrameStamp<LastFrameStamp的RenderPack来说上一帧是不可见的,需要从Pool里拿一个出来。


        有了RenderList的Cache机制后,可以为RenderList预留一个Pool,所有的RenderPack都是从这个Pool里去拿的,而不是动态分配和销毁,这样也可以提高性能并且降低内存碎片。这个方法有些时候会带来5倍(节省80%)的RenderList构件时间的提升

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值