Notifications
Article
分离动静态物体的自定义渲染管线思路
Updated 9 days ago
10
0
BK
通过分离场景中动态和静态物体 达到减少执行片源(像素)着色器代码的shadercore的计算负载 减少场景dc的目的
好久没在connect上发文章了,一个是因为本人做引擎中台(偶尔会做ta的事情,反正什么都要做哈哈)相关工作会挺忙,另外就是因为之前写的大家没有点赞,所以今天就先起个头,稍微透露后续要编辑的文章内容,一个是想知道相关内容的关注度,不然写了也白写,另外一个也是希望通过简短的文章能找到可以帮我一起完善后续内容(把现在的技术点使用demo等完善,考虑到保密协议毕竟不能直接那之前项目来做演示)的伙伴。
事实上在以前优化ui是也会考虑动静分离来做优化,分离动静态元素同样在其他场合也适用。
在之前的3d模拟|写实|大世界游戏项目中,由于屏幕中会包含很多建筑和大量npc,所有建筑都是pbr材质(反正就是计算量和纹理采样比较多),所以通过对动态和静态物体就可以在玩家没有滑动屏幕时只渲染动态物体npc特效等(摄像机没有移动时),不需要渲染静态物体。
其实有三个方案可以实现,一个是在上一帧渲染完成所有静态物体后,把当前framebuffer的数据拷贝到renderTexture上,继续渲染其余动态物体。
在下一帧,clear framebuffer之后,blit拷贝renderTexture上的颜色到framebuffer,并且渲染合并之后的所有静态物体的深度到framebuffer,继续渲染剩余动态物体的颜色,这里动态物体一般指:会动的npc和特效以及半透明的物体,ui等。
第一个方案最终实现没有任何问题,玩家如果只是操作ui的画,静态物体基本不需要重新绘制,每一帧起初的拷贝到framebuffer的消耗相比静态物体的消耗要小得多,而且可控。
这个方案是在unity2017通过commandbuffer实现的,最近开始用2019,发现在2019里面实现这个方案应该会方便很多,也不知道unity官方是不是已经在urp里面实现了,还没具体看,熟悉的同学可以交流一下。
另外一个方案
另外一个还没验证的方案,就是直接通过从framebuffer上拷贝depthAttachment到内存,每一帧把上一帧的静态物体的颜色和深度拷贝的framebuffer,但是这个在gles3.0中不确定是否可行,还可以试试ios metal里面或者vulkan里面需要花时间验证。
最后一个方案,考虑到动态物体(除去ui之外的)在屏幕中的像素占比并不大,这样的话,其实我只要在存下上一帧静态物体的深度和颜色,后面的动态物体只需要在frag中比较深度,深度不满足的非透明物体clip,由于动态物体在透明物体也不少,直接alpha set 0就可以了,这样也省去了再次填充深度导致的一点负载了。
不知算不算干货,最近在研究场景shadowmap优化方案,以后有机会再分享。
需要有几名看懂了的小伙伴合作根据这篇文章编辑相应的扩展详细教程和demo之类的,可以考虑给予小小报酬,同时也为了以后技术交流和一起做相关的技术延伸拓展和合作啦。
觉得一下就能看懂的朋友,并且觉得有用,想支持我的朋友可以扫下面二维码,以后有什么需要帮助的可以加好友交流呀。哈哈哈。
Tags:
BK
B.B King
Programmer
2
Comments