问答 多个相机分别实现各自屏幕后处理的问题

侑虎科技 · 2021年03月24日 · 34 次阅读

1)多个相机分别实现各自屏幕后处理的问题
​2)怎么查看子线程中的 GC Alloc
3)Mesh 组件的世界坐标
4)绘制的 Mesh 丢失了 Unity 自带的 Keywords
5)AssetDatabase V2 和 V1 的核心区别


这是第 235 篇 UWA 技术知识分享的推送。今天我们继续为大家精选了若干和开发、优化相关的问题,建议阅读时间 10 分钟,认真读完必有收获。

UWA 问答社区:answer.uwa4d.com
UWA QQ 群 2:793972859(原群已满员)

Rendering

Q:游戏中有多个相机,每个相机有自己的后处理效果。但是发现 Depth 越大的相机 OnRenderImage 传过来的图像越小于这个 Depth 所有相机的叠加图像,这样就没法实现各自的后处理效果,有什么方法可以解决吗?

A:经过测试,给 Camera 赋值 RenderTarget,那这个相机上的 OnRenderImage 就只会对这个 RT 起作用。

使用这种方式,对不同的 Camera 加不同的 OnRenderImage。最后需要一个额外的相机将这些 RT 合在一起,在这个额外的相机里面,可以渲染一个 Canvas,里面用多个 RawImage 来将之前的 RT 叠在一起。

下图中,球和天空盒是场景相机渲染的,相机渲染到 RT1,文本是 UI 相机渲染的,相机渲染到 RT2。

第一个相机 OnRenderImage 里面颜色反一下,第二个相机的 OnRenderImage 里面变成灰度图。从下图可以看到这两个效果是相互独立的。

最后用 CombineCamera 画一个 Canvas,里面有 2 个 RawImage,RawImage 里面的 Texture 分别使用那两个 RT 就可以了,如下图:

感谢 Xuan@UWA 问答社区提供了回答

Mono

Q:我把一些大计算量的东西放到了子线程中,现在想看下有没有 GC Alloc,但是没找到像 Profiler.BeginSample/Profiler.EndSample 这样的方法,看不到子线程中的 GC Alloc,只能看到时间开销。请问要怎么才能看到子线程中的 GC Alloc 呢?

A:目前新版本的 GOT2.3 版本已经支持了。
《多线程统计 | GOT Online 新功能上线》

感谢 Xuan@UWA 问答社区提供了回答

UGUI

Q:Mask 组件的世界坐标传给了 Shader,然后要把模型空间的 Vertex 转到世界空间进行对比。

把 Mask 的四个角的坐标通过 GetWorldCorners 这个接口获取到传给 Shader,

然后将特效的 Vertex 转换到世界空间中作比较。但是效果看起来这个转换的值好像不太对,我的渲染模式是 Overlay。

A:我把 Render Mode 改成 Camera 就行了,应该是在 Overlay 下 GetWorldCorners 获取到的值不正确。

感谢题主方星@UWA问答社区提供了回答

Rendering

Q:使用 CommandBuffer.DrawRenderer 绘制的 Mesh 会丢失 Unity 自带的 Keywords,导致 ShadeSH9 计算的结果不对。(版本:Unity 2019.2.0f1)

正常渲染:

CommandBuffer.DrawRenderer:

A1:光照处理阶段,CommandBuffer 的内容还未产生,所以也就不会有球谐和屏幕空间阴影的内容了。

感谢李星@UWA问答社区提供了回答

A2:测试后发现,可以使用 EnableKeyword 来强行开启 Keyword。但是会遇到环境光渲染不出来的问题。

正常的渲染如下:


环境光渲染不出来,如下:





虽然 Keywords 是完整的,但是环境光还是没渲染出来,原因是 SH 的系数出问题了,具体解决方案可以参考:
https://github.com/keijiro/LightProbeUtility

使用如下的代码可以让这个 Cube 和普通的渲染方式产生相同的渲染结果,但是需要使用 CommandBuffer.DrawMesh 的方式。

public class TestCommand : MonoBehaviour
{
   public MeshRenderer rend;
   public Mesh mesh;
   CommandBuffer cb;
   MaterialPropertyBlock block;
   Material mat;

   void Start()
   {
       block = new MaterialPropertyBlock();
       LightProbeUtility.SetSHCoefficients(rend.transform.position, block);//来自git中的脚本
       cb = new CommandBuffer();
       cb.name = "DrawCube";
       mat = new Material(rend.sharedMaterial);
       mat.EnableKeyword("SHADOWS_SCREEN");
       mat.EnableKeyword("LIGHTPROBE_SH");
       cb.DrawMesh(mesh, rend.localToWorldMatrix, mat, 0, 0, block);
       Camera.main.AddCommandBuffer(CameraEvent.AfterSkybox, cb);
   }   
} 

感谢 Xuan@UWA 问答社区提供了回答

Editor

Q:AssetDatabaseV2 和 V1 的核心区别是什么?切换到 V2 对项目有哪些好处?

A1:做个搬运工:

《资产导入新管线:加速资源导入的坚实基础》

《Asset Pipeline Version 2(Asset Database v2)内部细节》

《The new Asset Import Pipeline: Solid foundation for speeding up asset imports》

AssetDatabase.Refresh() refresher - Unite Copenhagen(需要梯子)

Speed up your asset imports for big projects - Unite Copenhagen(需要梯子)

【三思 Unity】深入浅出资源管理之:Asset Import Pipeline v2(上)

感谢黄程@UWA问答社区提供了回答

A2:就是在编辑器加速导入的功能,本身也不收费。加速幅度还比较大,对多个小文件导入提速比较明显,但是导入 ASTC 图片依然很慢,可能因为主要耗时是在图片转换这边。总的来说,切换到 V2 没遇到什么问题。

感谢邹彬@UWA问答社区提供了回答

封面图来自网络


今天的分享就到这里。当然,生有涯而知无涯。在漫漫的开发周期中,您看到的这些问题也许都只是冰山一角,我们早已在 UWA 问答网站上准备了更多的技术话题等你一起来探索和分享。欢迎热爱进步的你加入,也许你的方法恰能解别人的燃眉之急;而他山之 “石”,也能攻你之 “玉”。

官网:www.uwa4d.com
官方技术博客:blog.uwa4d.com
官方问答社区:answer.uwa4d.com
UWA 学堂:edu.uwa4d.com
官方技术 QQ 群:793972859(原群已满员)

暂无回复。
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册