|
技术简介
一个项目的阴影实现需要用到好几套技术方案,但其中接触阴影单独写过文章 接触阴影详细说明,csm又是unity内置,所以这里主要讲最大开发量的部分: 在各种场景如何更好的使用静态阴影。这里主要分2部分,
- 在大世界补充csm ,高性能实现远处阴影绘制
- 在小世界代替csm,减少drawcall并大幅度提升帧数
<hr/>大世界阴影基础思路(1公里-4公里类型)
大世界阴影按距离分配
痛点:主要解决cms有限距离外 又不烘焙的 大场景,实现远处静态物件的接收与投递阴影与动态物件(角色.载具)接受阴影.[目标:较高性能实现全图阴影]
- 0-5米:屏幕空间接触阴影
- 0-50米: unity自带 csm
- 50-256米 离线烘焙的shadowmap,pcf (每128米一张1024 单通道深度图)
- 256米到4000米(全场景大小):离线烘焙的shadowmap,vsm(每128米一张256 双通道深度图) (升级后这里有改动看最后)
<hr/>pcf 的shadowmap
50米处还是比较近 需要比较稳定的软阴影,选pcf是比较稳定的,且硬件pcf加持
因为精度较高 数据大 需要实现大幅度压缩与内存的流入流出
- 流入流出:采用一层clipmap 只加载相机附近的5x5张图分帧加载,每帧最多一张 基于clipmap的静态shadowmap - 知乎 (zhihu.com)
- 容量压缩:采用bc4格式极大压缩了容量. 因为主要存在硬盘所以只要把不需要的数据统一成一个固定颜色.自带的文件压缩算法就可以自动压缩.所以是分析出地表的深度,地表的深度一般不再遮挡人物所以可以把这个深度值清除.但是有些地表是斜坡会投影到地面.所以采用深度剥离方式.,判断地表的遮挡范围内是否还有地表.shadowmap的压缩技巧 - 知乎 (zhihu.com)
- 精度提升:因为bc4压缩率高 但会丢失精度.为了最好的效果需要做精度保护.1 采样倾斜投影来缩小深度值的范围提高精度.2对深度图每32x32像素统计下最大最小深度.然后可以把存储的值填充满0到1.比如如果这些深度范围是0.40,到0.49 那么0.4部分是不需要反复记录的.长阴影shadowmap精度优化 - 知乎 (zhihu.com)
内存占用:50M(2M r16 x25),采用bc4 +软件pcf 可以 控制在12M
vsm的shadowmap
远处的软阴影准确性要求不高,但对性能要求更高所以一次采样的vsm比较适合
与pcf一样 采用倾斜投影和normalize depth,一次性常驻内存
内存占用:67M,(根据不同距离再做一次分离 可以大幅度减少内存)
效果图
主要展示远处vsm 静态阴影效果
主要展示近处csm与中处pfc静态阴影效果
主要展示中处pcf 与远处vsm 静态阴影效果
<hr/>小世界阴影基础思路(1公里以内)
因为项目同时存在小场景的传统竞技地图,所以这个技术方案 稍微调整下 用在小场景 能换来显著的性能提升.
痛点:主要解决静态物件每帧绘制shadowmap的性能浪费,尽量满足所有距离的静态物件都不在运行时绘制shadowmap.[目标:画质相差不大条件下极大提高阴影性能]
- 0-5米:屏幕空间接触阴影
- 0-64米 动态对象: unity自带 csm
- 0-64米 静态对象: 离线烘焙的shadowmap,pcf (每16米一张1024 单通道深度图,以相机位置为中心 加载附近9x9张 ),
- 64米以外:unity烘焙的shadowmask与occlusion probe(升级后这里有改动看最后)
性能收益与效果展示
精度非常接近实时的csm.省掉所有静态场景物件的drawcall ,cpu提升非常显著. shadowcasters引擎统计没有剔除我这部分所以统计不准.渲染批次只有原来的50% 顶点数只有原来33%
上:csm ,下:本方案阴影
<hr/>后期SVT升级
以上这套方案一直在线上运行了1年多,没什么实际大问题。但是在大世界只分2层mipmap 显存利用率不是最高,在小世界还依赖结合shadowmask,工作流比较麻烦而且有些图需要64米以上显存会快速增加。所以后面我又升级到svt来做阴影贴图的流入流出方式,svt大致方案是一套pcf 预计算几套不同lod的shadowmap图,比如lod0的图 一张覆盖n米,一张lod1的图一张覆盖2n米,一张lod2的图一张覆盖4n米。。准备4套lod够用,通过4叉树管理,简单根据距离计算每个node 需要的lod,然后加载不同lod图,在大世界不再需要vsm,在小世界不再需要烘焙shadowmask配合,显存与工作流都得到优化。 |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
×
|