找回密码
 立即注册
查看: 289|回复: 8

unity大世界阴影方案

[复制链接]
发表于 2023-1-24 13:18 | 显示全部楼层 |阅读模式
技术简介

一个项目的阴影实现需要用到好几套技术方案,但其中接触阴影单独写过文章 接触阴影详细说明,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配合,显存与工作流都得到优化。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
 楼主| 发表于 2023-1-24 13:20 | 显示全部楼层
[赞同]
发表于 2023-1-24 13:23 | 显示全部楼层
虽然,但是。。[魔性笑]
发表于 2023-1-24 13:28 | 显示全部楼层
虽然这个方案可以实用 但是我记得你有更好的软阴影方案[大笑]
发表于 2023-1-24 13:36 | 显示全部楼层
[酷]
发表于 2023-1-24 13:46 | 显示全部楼层
我想说的有很多个虽然但是[大笑]
发表于 2023-1-24 13:48 | 显示全部楼层
有一个延伸的问题,某个项目的怪体型巨大(几百米那种的),用csm画的阴影精度很低,这种情况有什么特殊解决方案吗?谢谢!
发表于 2023-1-24 13:56 | 显示全部楼层
这种确实非常不适合csm 逐对象分配lod 前提是都假定是小对象 本来用cluster mesh 可以实现超大对象不同部位的不同阴影精度 但如果有骨骼动画比较复杂没写过 可以看我clustermesh 那篇
发表于 2023-1-24 14:04 | 显示全部楼层
谢谢!新年快乐!
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-6-23 10:20 , Processed in 0.106764 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表