http://blog.sina.com.cn/s/blog_1377810120102w2h3.html
最近都在玩UE4。上手一个新东西,总是会有各种各样的问题。有时候很难解决,一个问题卡上几天都是很正常的事情。最近开始慢慢研究出来一点东西了,开一个帖子记录一下平时研究出来的疑难杂症,方便大家也方便自己。会一直更新的。
1)UE4使用真实反射screen space reflection技术。这个反射的精度是在post processing volume中进行调节的。默认quality是50,然而你发现基本调到七十几以上以后效果并不会有变化。是因为后台真正控制精度的是代码,精度有4个档次,默认可以提升到的最大精度只到3,最高精度4并没有解锁。解锁的方法是,点击键盘上的“~”键,打开控制台输入。输入指令:r.ssr.quality 4.这样就可以将ssr的最大精度又3上升到4.这个时候,再把post processing volume中ssr的quality提高上去,就可以看到反射精度显著提高了。
然而,如果你对画面要求非常高的话,quality4可能都还无法满足要求。这个时候仍然有办法继续提高,方法是找到文件夹(安装UE4的盘符):\Program Files\Epic Games\(正在使用的版本号)\Engine\Shaders。找到ScreenSpaceReflections.usf文件,使用记事本打开查看代码。翻到文本一半的地方, 会有这样的代码:
#if SSR_QUALITY == 1
const int NumSteps = 8;
const int NumRays = 1;
#elif SSR_QUALITY == 2
const int NumSteps = 16;
const int NumRays = 1;
#elif SSR_QUALITY == 3
const int NumSteps =8 ;
const int NumRays = 4;
#else // SSR_QUALITY == 4
const int NumSteps = 12;
const int NumRays = 12;
#endif
聪明的朋友应该看懂了,这里就是真正控制ssr反射精度的地方。这段代码将精度分为4个档次,使用post processing volume里的ssr quality属性来划分这4个档次,调节ssr quality(0-100)的数值可以使精度档次在这4档中来回切换;同时控制台输入密码,r.ssr.quality (1-4)来选择可以解锁的最大精度档次。如果这里的r.ssr.quality 给到2,就算你把post processing volume里的ssr quality调到100,依然只有2级的效果,而不是4级。
而真正影响反射精度的参数本质上是代码里的这两个:NumSteps和NumRays。目前没法知道具体的意义到底是什么,但是前面的参数似乎可让反射的具体形状变得更准确,后面的参数可以降低噪点。
当你把质量调到4级感觉反射依然不满意的时候,就可以手动修改这里的参数。默认是(12,12),我自己调成了(24,16),还尝试过(32,32),但是精度到一定程度以后,提升比较不明显,对性能消耗也非常高,帧率掉得很厉害。根据具体项目来具体制定吧。改了数值,保存文档以后,要重启引擎,并且重新在控制台输入r.ssr.quality 给到对应的精度等级,才会生效。
另:1,2,3,4级的具体参数都可以修改。我自己尝试了增加一个SSR_QUALITY == 5的精度设置,但是系统并不识别,似乎只支持他们自己预先设置好的4个精度级别。总的来说,简直黑科技有木有。一般做三维转过来的美工谁会想到这种玩意儿啊。
2)在UE4中,就算你新建一个完全空的场景,依然会有post processing效果。你当然可以自己建立一个post processing volume来覆盖。但总觉得这个默认的效果不知道在什么地方,似乎对这个引擎的掌控力不够,心里虚虚的。这个默认的全局控制,在大纲里是找不到的。开关的方法只能用控制台。密码是:ShowFlag.PostProcessing(0或者1,代表关闭或者开启)。使用ShowFlag.PostProcessing 0,马上场景中的所有post processing效果都消失啦,干净爽朗。想要完美掌控场景每个角落设置的处女座,终于不用自杀啦。
3)在研究材质节点的时候,学到一个ConstantBiasScale节点。这个节点有两个参数,作用非常简单,假设你的两个参数分别为a和b,输入这个节点的参数是x,那么输出的参数就是(x+a)*b。我当时就非常纳闷,既然仅仅只是简单的加法和乘法,为什么不可以让用户自己手动用加法节点和乘法节点连?而是要做一个新的节点出来,然后我仔细找了好多资料看了下,也没发现这个节点到底有什么特殊作用,于是草率地得出结论:这个节点并没有什么卵用。
结果呢,今天在做sin函数控制亮度的时候,发现sin函数输出的结果范围是-1到1。而亮度不会有负数啊,最暗也就是0了,-1到0那一段信息就没用了啊,于是我就要把输出的结果重新分布一下,让-1到1的区间变为0到1,于是我连了一个节点,把输出结果都加上1,再连一个节点,把输出的结果除以2(乘以0.5)。忽然我就想到了一件事,先加后乘,这不是ConstantBiasScale节点干的事吗?于是我创建了一个ConstantBiasScale节点,连到我的sin输出节点上。这时候我又发现一件事,原来ConstantBiasScale的默认参数就是1和0.5,即是说,默认状态下,ConstantBiasScale就是把输出结果+1再除以2.原本我需要连两个节点调两个数值完成的事情,现在只要连一个节点就够了。
关键是,我恍然大悟,官方设置这个节点的本意,并不是真的让你去加去乘,而是专门针对你想要吧-1到1的区间重新分布到0到1的区间时的快捷操作。并且这种需求在UE4里面应该还是相当不少的。我仿佛看到那些开发引擎的程序员们,天天连一个加1的节点,再连一个除2的节点,烦得不行。最后终于有个人忍不住了,做了一个看起来没什么卵用,但其实能让天天重复这个劳动的人得到一定程度解放的节点——ConstantBiasScale。
哈哈,简直讲了一个小故事。在和开发人员心意相通的一瞬间,我忽然感觉到这个引擎的美好与可爱,感受到隐藏在冷冰冰的软件界面背后滚热的内心,CG行业里的这些东西真的有意思。
4)今天找到了非常好的关于UE4烘焙lightmap相关的文章和视频教程,都贴在这里了。
http://www.worldofleveldesign.com/categories/udk/udk-lightmaps-01-basics-and-important-principles-for-creating-using-lightmaps.php
http://v.youku.com/v_show/id_XMTMwNzk2MDI4MA==.html
http://v.youku.com/v_show/id_XMTMwNzk2MDI1Ng==.html
http://v.youku.com/v_show/id_XMTMwNzk2MDI2OA==.html
最后这一个是maya ue4工作流程,而且讲得最清晰易懂。
5)研究了一下UE4里的tone mapping。这个功能可以更好地模拟人眼的视觉效果或者胶片机的特性,在接近高光的地方,将画面的亮度压缩,不至于画面完全过曝看不到细节。是实现画面真实感的非常重要的功能。
查到官网用的公式:
GammaColor=LinearColor/(LinearColor+0.187)*1.035;
这公式表示的意思大概如下图所示,总之是更符合人眼视觉的图像表现形式,不展开了。
UE4对于tone mapping的处理,也是其画面真实性的一个重要来源。你会发现,高亮区域基本不会过曝。
然后我尝试把他们的做法在ps或者AE里复刻,发现很容易实现,控制很方便,并且效果也很不错,比我之前用的色阶加曲线的方式更简单出效果。个人感觉可以把这个步骤融入到一般的静帧或者动画后期流程中去,给一些高动态场景带来的提升会非常显著。
6)有的时候会发现场景中的透明物体无法选中,只要给这透明的物体换另外一个不透明的材质,马上可以选中了。原因是settings里面的一个选项——allow translucent selection。是否允许你选择透明物体。关键是还有个快捷键T,很容易按到,所以是初学者容易犯的毛病之一,堪比maya中的B键问题了。。。而UE4设置一个这样的快捷键其实是我很不能理解的,难道这个功能使用率很高吗?居然要占掉一个很容易按的快捷键。可能是我还没理解这个选项的作用?
7)在UE4的视图中,左键按住不放划框的操作,并不是一般三维软件中画框选中多个物体的操作,而是控制摄像机移动的。出了shift键一个个加选以外,怎么样快速选择一片问题呢?使用ctrl+alt+左键画框就可以了。
而在udk的版本里,material editor也有类似的操作。那个时候,左键和右键都是平移视图,只有ctrl+alt+左键一起按才是画框。现在是右键平移视图,左键选择,左键加右键一起缩放了。而中键除了滚轮缩放以外并没有什么用。其实很希望UE4的material editor可以变成maya式的操作方式,右键按住缩放,中键按住平移,左键选择,这样鼠标就可以得到充分高效的利用。怕的就是之前那些人都已经用惯了,并不想改。
8)开启实时GI的方法:找到你安装UE安装文件夹\你所使用的版本号\Engine\Config。在这里,找到ConsoleVariables.ini文件,打开,翻到最后一页,加上 r.LightPropagationVolume=1 这一段代码,储存,重启编辑器。对于想要开启实时GI的灯光,勾选Dynamic indirect lighting,然后你都了鉴证奇迹的时刻了。实时GI的效果还是有限,并且默认状态有点太强了,可以适当调低一些强度。
因为现在UE4里的灯光,若使用raytracing soft shadow就必须让灯光的移动类型变成movable,而烘焙灯光贴图的时候,movable类型的灯光,是不会烘焙任何信息的,当然也不会计算该灯光的间接照明。就相当于,你想要raytracing soft shadow就要用moveable light,就不能烘贴图,想要间接照明,就得开启实时的。
技术层面是这么说的,具体的效果本人暂时测试量还不够,而且实时GI官方也说还在持续开发中,期待后续版本。
9)大略说一下这几天研究的UE4中的灯光与阴影,虽然还有不少问题,但成果也相当多。果然次时代游戏引擎是一种很复杂的东西。
UE4的灯光的移动性有三种:static;stationary ;movable。分别是完全游戏运行后不能移动也不能调参数的;游戏运行后不能移动但是能调节亮度和颜色的;什么东西都是可以实时修改的。
而这三种类型对于UE4中烘焙lightmap影响非常之巨大。UE4的烘焙主要是把场景中的GI效果以及灯光的阴影,计算出来,然后存到一张lightmap的图片上,再和原来的贴图叠在一起,相当于把GI和阴影效果直接绘制在颜色贴图上一样,只不过是通过计算出来的,非常准确。这样的话,就可以几乎没有性能消耗地获得实时的GI和阴影效果。但劣势也非常大,就是你的灯光一动或者某些物体一动,就会露馅,因为GI和阴影是之前计算好,位置固定的。
static 和stationary类型的灯光,点击烘焙之后,都可以把GI信息储存在lightmap中。虽然说stationary灯光可以烘焙完之后,甚至在游戏运行过程中,改变亮度和颜色。但是lightmap是预先就烘焙好的,储存的是烘焙的时候的灯光亮度和颜色产生的GI效果。这个时候,你改变stationary的灯光颜色,虽然是允许的,但是GI效果是不会跟着改变的,你甚至会调出绿色的灯光和红色的GI效果。。
这么说起来static和stationary感觉上似乎没啥区别啊。实际上我个人感觉最大的区别并不在GI而在阴影的处理。static类型的灯光烘焙的时候,会把阴影也烘到lightmap中去,而一般lightmap的尺寸非常小,如果你所需要的阴影非常硬,边缘很清晰的话,那么烘焙出来的效果,就会有很多锯齿,毕竟尺寸小啊,非常难以接受,而加大lightmap尺寸代价也非常大,很高的内存和储存空间需求以及夸张的烘焙时间。
而stationary类型的灯光,烘焙的时候,虽然也会烘焙阴影,但是阴影用的是cascaded阴影,会清晰很多很多。强烈建议主要光源使用。
还有新的阴影类型distance field shadow。就是一般意义上的软阴影。可以选择光源的大小,光源大的时候,阴影就会产生软边。并且是实时效果,不需要烘焙,只要进行一些设置就行了。
10)今天开始学习UE4和maya的动画工作流程。本来想使用一直很信赖的advanced skeleton插件进行绑定,然而却发现UE4有一套自己的绑定动画工具,这让我想到maya自己开发的那一套,心里想,官方的工具总是没有个人工具那么黑科技吧,稍微看了下介绍,发现是我错了,UE4的这套工具蛮给力的,原来是他们员工内部使用的工具,在最近的版本开放给大家使用了。给自己人用的东西总不会坑撒。我仔细学习了他们的一套教程,虽然还有很多地方并不很了解,但已经感受到这插件的强大气息了,很多功能甚至超越advanced skeleton,尤其针对游戏领域,简直是绑定动画的不二选择!这感觉,仿佛在万千人群中终于找到了那个ta。记住他的名字animation rig toolkit后面简称art。
以上是一些背景介绍,这个帖子里总是要记录一些技术点的。说一下使用过程中让我感到很诧异,必须十分注意的一个点吧。首先在art使用的过程中,无法使用除了mb以外的格式进行保存!如果使用了ma文件,那么系统将会提示里有未知节点无法保存。尤其是在2015及以后的版本中,系统已经设置默认保存格式为ma了,不知道这一点很容易造成无法保存的局面。
这个还不是关键点。关键在于,你的绑定文件做好的最后一步,art会进行build操作,主要是帮你保存文件,而文件格式没法选择(就我目前来看没发现可以选择文件格式的地方),会自动帮你保存成你场景的文件类型。而根据上面一点说的,若保存成出了mb文件以外的格式,系统就会报错,没法保存,你直接就会卡在最后一步无法完成也无路可退,直接导致之前的工作都白费了!而当你直接打开一下从别的地方导过来的模型文件进行绑定的时候,这些文件经常会是obj 或者fbx格式的,那么art插件默认就会尝试帮你保存成obj或者fbx格式,然后他发现无法实现,于是你就无法保存,于是就卡在最后一步,你就跪了。
结论,对于obj或者fbx文件使用art插件进行绑定的时候,千万记得在绑定开始之前就将文件存成mb格式!
11)看了一篇官方的,做面光源的教程,思路还可以。链接分享出来:
https://www.unrealengine.com/zh-CN/blog/simulating-area-lights-in-ue4
其中,对于lightmass质量的设置引起了我的注意:
- Static Mesh Lightmap resolution(静态网格物体光照贴图分辨率) = 512
- Num Indirect Lighting Bounces(间接光照反弹次数) = 25
- Indirect Lighting Quality(间接光照质量) = 8.0
- Use Ambient Occlusion(使用环境遮挡) = True
- Compress Lightmaps(压缩光照贴图) = False
- 我这才知道,原来想要得到好的灯光烘焙效果,参数居然是要开到这么高的,真想再做个场景试试,当时我还是太年轻了。
12)今天装vs2013的时候发现c盘空间居然不够了,因为c盘是ssd一直很省着用的,结果还是不够了,于是开始手动清理,一个文件夹一个文件夹地查看删除。发现装了UE4以后,确实是越用c盘越小,对于ssd用户是很头疼的。后来发现,在你的
C:\Users\你使用的用户名\AppData\Local\UnrealEngine\Common
下DerivedDataCache这个文件夹非常大,有3个多G,看名字就是放一些文件缓存的。去网上搜了一下转移文件夹的方法。
找到安装引擎的根目录:\Program Files\Epic Games\4.8\Engine\Config下的BaseEngine.ini文件,打开,找到这一段:
[DerivedDataBackendGraph]
MinimumDaysToKeepFile=7
Root=(Type=KeyLength, Length=120, Inner=AsyncPut)
AsyncPut=(Type=AsyncPut, Inner=Hierarchy)
Hierarchy=(Type=Hierarchical, Inner=Boot, Inner=Pak, Inner=EnginePak, Inner=Local, Inner=Shared)
Boot=(Type=Boot, Filename="%GAMEDIR�rivedDataCache/Boot.ddc", MaxCacheSize=512)
Local=(Type=FileSystem, ReadOnly=false, Clean=false, Flush=false, PurgeTransient=true, DeleteUnused=true, UnusedFileAge=34, FoldersToClean=-1, Path=../../../Engine/DerivedDataCache, EnvPathOverride=UE-LocalDataCachePath)
Shared=(Type=FileSystem, ReadOnly=false, Clean=false, Flush=false, DeleteUnused=true, UnusedFileAge=23, FoldersToClean=10, MaxFileChecksPerSec=1, Path=?EpicDDC, EnvPathOverride=UE-SharedDataCachePath)
AltShared=(Type=FileSystem, ReadOnly=true, Clean=false, Flush=false, DeleteUnused=true, UnusedFileAge=23, FoldersToClean=10, MaxFileChecksPerSec=1, Path=?EpicDDC2, EnvPathOverride=UE-SharedDataCachePath2)
Pak=(Type=ReadPak, Filename="%GAMEDIR�rivedDataCache/DDC.ddp")
EnginePak=(Type=ReadPak, Filename=../../../Engine/DerivedDataCache/DDC.ddp)
这里就是定义缓存文件存放位置的。
找到对应段落,修改为:
Boot=(Type=Boot, Filename="D:/Program Files/Unreal Engine Projects/DerivedDataCache/Boot.ddc", MaxCacheSize=512)
Path="D:/Program Files/Unreal Engine Projects/DerivedDataCache"
Pak=(Type=ReadPak, Filename="D:/Program Files/Unreal Engine Projects/DerivedDataCache/DDC.ddp")
EnginePak=(Type=ReadPak, Filename="D:/Program Files/Unreal Engine Projects/DerivedDataCache/DDC.ddp")
类似的代码段落有好几段,每一段都要认真修改,改完储存,将之前的缓存文件都删除就可以了。