基本结束了输入阶段的调试之后,开始搭建VR场景。VR的基本配置在前文当中已经提到过了,导入SteamVR和VRTK的文件包之后,将可用的场景素材放入Unity文件中。先将[Camera Rig]/[status]/[SteamVR]三个文件拖入场景中。其中[Camera rig]是比较重要的一个文件。它代表着VR中的头戴式设备和两个手柄。
基本配置完成之后,来进行VR场景模型的搭建。模型素材来自于网络,但是为了创造出符合我们需求的场景,利用这些素材进行了重新搭建。
我们的场景构想是,一位在现实中疲惫的文字工作者,可以在这个场景中获得一些轻松和愉悦,并在这种轻松的氛围中继续进行自己的文字工作。
为了增加场景中窗明几净的感觉,增加了反射探针的元素。所谓反射探针,就是Reflection Probe。当使用标准着色器时,每一个材质都会具有一定程度的镜面反射(specularity)和金属反射(metalness)属性,在没有强大的硬件来处理即时光迹追踪反射的情况下,我们得仰赖预先计算著色反射,我们使用了一个由六张描述天空的图片所组成的方体贴图(Cubemap)然后在和其他光和地表信息混合运算来仿真如同我们真实世界看到的反射效果。
从Unity 5.x开始,我们可以反射探头(Reflection Probe)产生贴图来模拟反射。
工作原理:在某个定点搜集环境信息,动态生成cubemap 反射贴图。
当一个物体横跨了多个Reflection Probe的时候, 他的Mesh Renderer中会自动加入所有他触及到的Reflection Probe. Weight是通过计算每个他触及的Reflection Probe和这个物体之间距离来得出的. 另外还可以单独调节Reflection Probe的”Importance”这个参数来手动干预这个计算结果.
Reflection Probe种类
Baked:在编辑器里存储一个生成的反射cubemap。可以点inspector窗口下面的bake按钮或者light窗口下边的bake按钮进行烘焙生成反射cubemap。跟烘焙lightmap差不多,如果light窗口Auto勾选上了,会自动更新cubemap。baked探头只能显示标记为Reflection Probe Static的物体。一旦烘焙完后,cube map就不会变化,所以不会受移动物体实时变化的影响。消耗比实时的小很多。可以更进一步,通过culling mask和clipping plane属性(像摄像机一样)将不想要的物体屏蔽出reflection probe。
Realtime:在运行时实时生成cubemap,也就是说反射不局限于静态物体,而且在场景中会实时更新。然而,需要花费大量的处理时间刷新光探头,unity允许你通过脚本触发刷新。同时,有选项控制刷新,这样就可以好几帧刷新一次。也可以通过culling mask和clipping plane控制哪些物体加入反射cubemap。
Custom:这种也可以在场景中烘焙,像Baked探头一样,但是你可以设置一个自定义的反射cubemap,自定义的也不会实时更新。但有动态物体选项,勾选上后,允许没有标记为Reflection Probe Static的物体加入反射cubemap中。
面板系数
Time Slicing---官方文档上说这个选项仅仅针对于当我选择了Every frame作为刷新模式的情况, 实则不然, 因为不管是On Awake还是Every frame还是Via scripting, 这个Time Slicing都是有效果的, 要了解这个选项. 首先要了解一下Reflection Probe的内部生成机制, 一个Realtime的Reflection的生成有三个步骤:第一个步骤要计算一个Cubemap的六个面, 第二步要考虑这个Cubemap的mipmap(文档上说为了支持Glossy Reflections, mipmap是必要的, 而Glossy Reflections对于调节不同程度的Smoothness时是有一定效果上的提升的), 第三步是将计算结果拷贝到Cubemap中.
那么TimeSlicing的三个选项分别有不同的三步计算所需帧数:
All faces at once---9帧, 性能消耗中等. (9帧之内再次通过Via Scripting调用刷新是无效的)
Individual faces---14帧(在9帧的基础上加了将六个面分为六帧的那多出来的五帧), 性能消耗最低.(14帧之内再次通过Via Scripting调用刷新是无效的)
No time slicing---1帧. 所有动作都在同一帧执行, 这种性能消耗最大. (1帧之内再次通过Via Scripting调用刷新是无效的)
Importance---影响了一个MeshRenderer中的多个ReflectionProbe的Weight的自动混合比例. 当一个物体处在多个Reflection Probe的”领地”内的时候, 首先会考虑每个Reflection Probe的Importance, 之后, 在此基础上才会考虑每个Reflection Probe与该物体之间的分别的交叉的体积的大小. 也就是说Importance的优先级高于交叉体积的计算.
关于交叉体积的计算: For ex., if the first volume is 1.0 and the second is 2.0, then first probe’s influence will be 1.0 / (1.0 + 2.0) = 0.33, the second probe’s influence will be 2.0 / (1.0 + 2.0) = 0.67. 还有一种特殊情况, 就是就是一个小的Probe套在一个大的Probe里面, 而一个物体又完全在这个小的Probe里面, 那么对这个物体来说, 小的Probe的Weight会是1, 大的会是0. 而当这个物体逐渐脱离这个小的Probe的时候, 那么小的Probe和大的Probe对于这个物体的Weight会进行一个混合.
Size---该Reflection Probe的影响范围. 进入这个范围的MeshRenderer会自动和这个Reflection Probe产生关联. 同时, 当Box Projection开启的时候, 这个Size也会影响Reflection Probe的UV映射.
Probe Origin---取样点相对于影响范围中心的偏移. 当勾选了Box Projection的时候, Probe Origin的位置会影响Reflection Probe的UV映射.
Box projection:一般情况下,反射cubemap是被假设在无限远出投射出来的图像,不同的角度都能看到反射的团,但是当你距离反射物体远近改变时,这个反射的图案不会发生改变,这个特性,一般情况下,在室外场景很适用,但是到了室内就不行了,开启Box projection 选项,(支持Shader Model3以上平台可用)允许我们创建一个投射有限距离内的物体,当我们与反射物体距离发生变化时,反射图案的尺寸也同样发生变化,Probe Size以及Probe Origin会影响Reflection Probe的映射图案的效果.
Shadow Distance---反射阴影距离, 特性和Quality Setting中的特性一样, 数值越小, 在反射画面中阴影显示越近, 但阴影越精细, 调成0会完全关闭阴影.
shadow distance为0
distance 为100
关闭反射探针和开启的对比,显然开启反射探针之后,效果更好:
除此之外,利用Unity中的PostProcessing插件,这是一种摄像机上的后处理插件,可以产生类似于运动模糊、偏光等效果。使用方法也很简单,导入相应的包之后,在camera中添加Postprocessing Behavior脚本,在脚本上附上设定好的各中小股就可以了。具体效果选择界面如下:
这样,一个与我们设计意图相符合的环境就搭建而成了。接下去要做的就是实现VR条件下的漫游。