[优化]Unity中的阴影优化方案

游戏中人物的阴影等级分类

1.无阴影

对于一些重要性很低或者很难被注意到的,当然大多数情况下是硬件设备配置达不到要求而采用低配画质设置的,这种情况下直接不产生任何阴影,虽然这看起来会让玩家觉得不那么真实,但是为了能让低端机上能够保持一定的帧率运行,这样是不可避免的

2.脚底假阴影

fake_shadow,脚底的阴影贴图,为所有需要添加假阴影的人物,脚底添加假阴影预制体,实时跟随人物移动,开销只是一张贴图的开销,但不太适用于移动的NPC或者怪物,毕竟游戏中地形高低起伏,一张贴图可能会产生穿帮,所以为静止的NPC使用这种较为合适

3.Unity系统的实时阴影

在有光源并勾选了Cast Shadow的情况下,物体会投射阴影,勾选了Receive Shadow的物体表面会接收到投射的阴影,由于阴影是实时的,一般移动的物体使用这个效果会比较好,但同时这个开销也是不可避免的。unity自带的shadowmap阴影基于深度,需要浮点纹理的支持,但是有的移动平台不支持,而且开销很大。

shadowMap的阴影实现原理:将相机放在和光源重合的位置上,那么场景中相机看不到的地方就是光源的阴影区域,然后通过相机将这个阴影映射纹理存储,可以每次采样得到某个方向距离光源最近的点(比这个点远则说明在阴影中)

4.软阴影

何为软阴影,游戏引擎中的阴影为实时的数学计算,投射出的阴影都是有棱有角,在阴影和非阴影的边界也是区分明显,而真实世界中则不是这样,真实世界中的阴影收到间接光照等的影响,在阴影边缘形状往往不那么锋利,而且往往过渡平滑。那么如何在引擎中实现这一技术,近几年大火的实时光照追踪技术,即将一束光的第一次,第二次甚至更多反射的影响都计算上去,得到更为真实的渲染效果,不过这一过程计算复杂,开销往往也比较大。

5.特殊的阴影实现方式——投影器(Projector)


1.用来实现实时阴影

先来看看Unity自带的ShadowMap的实时阴影有什么弊端

(1)ShadowMap采集场景中所有物件的信息,进行深度排序,在用到的时候进行采样,需要浮点数的支持,相当于存了一张很大的图,开销可想而知,而且有的平台甚至可能不支持

(2)在一位前辈的知乎专栏看到shadowMap会影响到静态合批的数量和效率,具体原因分析想来也合理,shadowMap存储了场景中物件的深度信息,这在一些宏的设置时打乱了合批的顺序,使得很多物件无法被合批,batch数量增加

那么投影器怎么实现的呢

原理就是:将要投射阴影的cube设置为shadow层然后相机渲染出RT,然后用这个RT再去渲染接受阴影的物体

Projector projector = GetComponent<Projector>();

        // 设置相机参数

        Camera camera = gameObject.AddComponent<Camera>();

        camera.cullingMask = shadowCasterLayer;

        camera.orthographic = true;

        camera.orthographicSize = projector.orthographicSize;

        camera.clearFlags = CameraClearFlags.SolidColor;

        camera.backgroundColor = new Color(1.0f, 1.0f, 1.0f, 0.0f);

        _renderTex = new RenderTexture(1024, 1024, 0, RenderTextureFormat.ARGB32);

        camera.targetTexture = _renderTex;

        camera.SetReplacementShader(Shader.Find("Unlit/ReplaceShadowRender"), null);

        // 将相机渲染的图像传递给要投影的shader

        projector.material.SetTexture("_ShadowTex", _renderTex);

效果如图:Cube为shadow层,Plane为非shadow层,每帧阴影都会得到更新


添加一个接受阴影的小Cube,层级为非 Shadow,可以正确投影到小Cube上,分别为小的Cube投射和不投射阴影的情况

2.用来实现软阴影

软阴影的实现如果使用实时光线追踪的方式开销很大,而一种取巧的方式就是通过投影器,投影的纹理图片我们可以自定义,选用一个合适的边缘模糊的纹理,就可以让我们的影子看起来像是软阴影,最右边为硬阴影,有棱有角,中间为软阴影,左边固定在下面的fake阴影,上面已经介绍了fake阴影和硬阴影的实现,软阴影的实现原理类似,选用合适的渐变的黑白纹理,使得投影出的阴影有个渐变过程


6.FrameDebug


和深度相关的渲染

1.投影器的效率

Camera.Render一共有19个事件,

(1)在UpdateDepthTexture中有四个,可以看出,第一个是用来清空颜色缓冲,z缓冲,模板缓冲,然后3个事件来渲染三个场景中物体的深度信息,即DepthJob

(2)中间13个,9个用于渲染不透明物体,1个天空盒在渲染完其他物体后渲染,3个渲染透明队列的物体为什么渲染透明物体3个Pass呢,通过改变Cube的Layer可以发现,这一步的操作实际上是我们投影器Projector再次渲染场景中的物体,现在场景中有一个Plane,一个Cube,一个Cube1,如果三个都是接受投影即layer为非shadow则透明队列会有三个消耗,如果只把cube的layer改成shadow,那么会有两个消耗,因为cube需要分别向Plane和Cube1投影,同理,如果两个cube都为shadow,那么接受投射的物体就只剩下plane,那么这里就这只有一个开销。

分析可知,使用投影器的时候,如果一个投影器投射的影子需要有很多物体接受,那么会增加很多这个开销,还是要注意权衡

(3)投影器使用一张RT来存储产生阴影的物体,然后用这个RT重新绘制接受阴影的物体,RT的尺寸关系到了我们阴影的质量,demo中使用的是1024*1024的RT,但是还是稍微有些锯齿感


依次渲染不透明队列,天空盒,透明队列


7.Dynamic Shadow Projector代码分析


投影器的脚本

核心脚本有两个,ShadowTextureRenderer和DrawTargetObject两个,看到面板中的一些设置,投影的颜色,纹理的尺寸,mipMap的level,模糊的程度等等,核心思想就是控制RT的一些参数来控制投影的阴影的外观尺寸等参数,而DrawTargetObject脚本中则重点实现了阴影投射的递归遍历等操作,将一个物体及其所有子物体的材质和shader参数正确设置

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,045评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,114评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,120评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,902评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,828评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,132评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,590评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,258评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,408评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,335评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,385评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,068评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,660评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,747评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,967评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,406评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,970评论 2 341

推荐阅读更多精彩内容