摘要:似乎是初次来到 indienova?好吧,其实不是,我不太清楚怎么看自己的注册时间,但我确定我很早以前就逛 indienova。应该是 18 年,那个时候,我还在用 Gamemaker Studio 2,还在上初三,看的都是 indienova 的教程。转眼高
似乎是初次来到 indienova?好吧,其实不是,我不太清楚怎么看自己的注册时间,但我确定我很早以前就逛 indienova。应该是 18 年,那个时候,我还在用 Gamemaker Studio 2,还在上初三,看的都是 indienova 的教程。转眼高中三年,大学四年,虽然不能说这几年全都在做游戏,也不能说这几年真的在 indienova 活跃过几天,但眼下早就换到了 Unity,并且开发出了《多元窗口》(MultiWindows)这样一部独特作品的早期试玩版,也该来这个我独立精神的启蒙之地分享点东西了。
虽然《多元窗口》现在有一个试玩版,但那只是为了验证游戏是否能在大多数人电脑上运行的技术测试版本,眼下我还在做更多有意思的游戏内容。前段时间,我看到 B 站有位 UP 主做了很独特的桌宠技术演示视频,其实我本来就研究过透明窗口的相关技术,也有很多人早就讨论过这方面的内容,前不久还看到有位大佬在 indienova 分享了他的桌面挂机游戏技术。但是我得说,这个演示视频里的 URP 透明可比一般的技术厉害多了。
Universal Render Pipeline 算是新版本 Unity 主推的渲染管线,不仅在 3D 光照方面效果出众,甚至还有十分方便的 2D 灯光。光照系统可以很方便地补足美术上的不足,让游戏的整体氛围感更加浓厚,下图是本人之前制作的《ReRevue》,运用了 URP 的 2D 光照,还算很好地结合到了 2.5D 的视觉方案之中,利用光照和舞台概念掩盖了美术资源不足的问题。
不过,如果只是单纯地在一个普通的透明窗口游戏中导入 URP 并且能运行,那我也不会写这篇文章。实际上,只有使用 Unity 自带的 Built-in 渲染管线,才可以通过将相机背景设置为透明来实现透明窗口效果。在 URP 中,是不能直接这样去做的,还需要一些额外设置。
如果是 URP 老版本(即低于 14),可以直接看上面那位视频 UP 大佬的 Github 项目,已经相当完善了:在后处理前对颜色进行判断,如果检测到相机背景颜色,则输出 Alpha 为 0 的颜色。不过,由于老版本的 URP 太过拉跨,还要涉及到本地化 UPR Package 并修改 Uber Post 的操作。
在较新版本的 URP 中,原项目使用的 Blit 已经无法使用了,也不需要修改 Uber Post ,但还需要做其他的修改。首先是关闭项目设置中的 DXGI 交换链,接着关闭相机与 URP 设置中的 HDR 选项(HDR 无法最终输出透明)。然后,利用新版本的 Full Screen Render Feature,去制作一个全屏效果处理。
在这里,我使用了两个 Shader 来完成最终的效果。首先是 TransparentWindow,我其实不太会 Shader 方面的内容,以前也没怎么用过,只会照葫芦画瓢——所以这里就是我用 Shader Graph 连连看搞出来的东西,功能也不过是比较颜色,如果检测到指定颜色(相机背景颜色),则输出黑色透明像素(黑色是为了在编辑器中预览的时候方便排查,实际不需要,这里的 colorMask 确实重复了)。
而 LimitedMaxAlpha 则是针对一个很独特的情况进行的保险措施。经过测试,在渲染时,如果后处理中包含了更亮的颜色,例如十分强劲的泛光效果,新版 URP 会将最亮颜色的 Alpha 值视为 1(即不透明),而会按比例下调非最亮颜色的 Alpha 值。这会导致一个结果,如果泛光之类的后处理太亮,会导致整个游戏不该透明的地方都透明,而不是没有遮挡的地方透明,有遮挡的地方完全不透明。因此,在后处理后,利用这个 Shader 调整整体的 Alpha 值,可以使得无论后处理多么强劲,都维持 Alpha 值在合理的范围内(其实我也不太清楚这个方案是否可以完全解决问题,只能说目前这个“It just works”,但也有可能在其他情况下出现问题)。
而代码方面,基本上就是简单地调用 WindowAPI 修改窗口样式,然后启用 URP 的透明输出。
经过多次尝试,这里必然会导致窗口的标题栏消失,而加上标题栏,就会导致透明效果失效。暂时无法确定是什么原因所致,但似乎只能这样去处理。如果需要在保留标题栏的同时去实现 URP 透明效果,就不能有光影,那么可以使用 GetLayeredWindowAttributes 实现颜色剔除来解决问题。
最终效果演示:5 个不同颜色的方块,以及较大的 URP 泛光。
* 本文为用户投稿,不代表 indienova 观点。
来源:indienova