开源框架 RealityShaderExtension,帮你将 Unity 和 Unreal 的 Shader 转到 visionOS

visionOS 上的 Shader

visionOS 上使用 Shader 有两种方式:ShaderGraphLowLevelTexture(LowLevelMesh) + ComputeShader

  • Shader Graph:本质是 MaterialX 增加了特有的扩展,配合苹果自家的 RealityComposer Pro(以下简称 RCP),实现拖拽连线快速编写 Shader。
  • Compute Shader:需要手工编写 Metal Shader 代码,复杂但更加自由。

Unity 中也有自己的 Shader GraphUnreal蓝图 也可以对 Shader 拖拽连线,从这方面讲它们三个的操作具有很大的相似性,理论上可以很方便进行迁移。但 UnityUnreal 是高度成熟的游戏引擎,各种材质效果和配套工具非常丰富,要在苹果原生 RealityKit 达到同样效果,需要手工迁移很多 Shader。虽然 UnityPolySpatial 能自动将 Unity Shader Graph 转译为 visionOS 支持的 MaterialX 版 Shader Graph 材质以在模拟器和真机上运行,然而遗憾的是,当我们使用苹果原生开发时,PolySpatial 并不能帮上忙,所有效果还是要手工迁移。

在我的日常开发中,我经常要在 Unity 和 苹果原生之间切换,偶尔也会帮忙迁移一下 Unreal 到原生。在这个过程中经常面临的困难是:Unity 和 Unreal 中大量内置的 Shader 效果节点,在 RCP 中并没有内置,需要手工编写。于是我就经历了一系列痛苦的迁移过程,比如下图中这些复杂的连线都是手工迁移过来的:

RealityShaderExtension

相信我,经历过一次后,再也不想再重新经历第二遍编写与调试。所以我就把这些迁移好的节点整理了一下,形成开源项目 RealityShaderExtension,供其他开发者使用,可以方便地帮助大家完成从 Unity 和 Unreal 到苹果 visionOS 原生 Shader 的迁移。

RealityShaderExtension 复刻了来自 Unity28 个 Shader Graph 节点和来自 Unreal28 个 Blueprint 节点,此外还包含 20 多种颜色混合模式和 8 种颜色空间转换节点。

Shader Graph 调试

在手工迁移这些节点的过程,我遇到了非常多的 bug,总结下来有三类:

  • 不小心写错的
  • 误解(误用)了 RCP 中节点的参数
  • RCP 自身的 bug

顺便来讲讲这些 bug 的应对方法。

a. 不小心写错的

最简单的当然是,花大量时间逐一检查对比节点和连线。当然我们还可以借助"假彩色图像"对输出值或中间值进行检验。

"假彩色图像"是指将输出值映射到[0, 1]区间,然后做为 RGB 值进行输出。

当我们在 Xcode 中编写代码时, RealityKit 自带的调试组件 ModelDebugOptionsComponent 就可以将 UV 和法线,显示为不同颜色。

在 RCP 中,右上角也有自带的 Debug Views 功能,可以将法线,UV ,粗糙度等用颜色显示出来。

除了自带方法之外,还可以手动转换为颜色进行显示,在项目的示例中,就有大量输出值被手动转换为 RGB 颜色表示出来,这样更加灵活。

b. 误用 RCP 中节点的参数

最常见的是,部分 RCP 中节点与 Unity 和 Unreal 中参数含义不同。

比如 RCP 中没有 lerp 函数,可以使用 Mix 来代替,但它们参数顺序是反过来的。还有 Step 函数,参数顺序也是反过来的:

c++ 复制代码
//GLSL 
lerp(a, b, t) = b * t + a * (1-t)
step(edge, x)

//RCP 
mix(F, B, m) = F * m + B * (1-m)
step(in, edge)

比如 RCP 中的条件选择节点 MTLSelect ,当条件为 true 时,会选择参数 B;条件为 false 时,选择参数 A,这点与常规判断不同,需要特别注意。

还有一些函数名称与常见的不同,比如其他平台常见的求导函数:ddx, ddy, fwidth,在 RCP 中则是名称的全称:

  • ddx(dFdx):Screen-Space X Partial Derivative,屏幕空间 x 偏导数
  • ddy(dFdy):Screen-Space Y Partial Derivative,屏幕空间 y 偏导数
  • fwidth:Absolute Derivatives Sum,偏导数绝对值的和

c. RCP 的 bug

编写过程中,还会遇到 RCP 自身的一些 bug,有时不能自动更新效果,有时会给出错误的值。一般解决办法有:

  • 重启 RCP
  • 重新创建出错的 Node 并重新连线
  • 选中出错的节点,点击输入输出面板后面的 Remov Override 按钮↩️

如果你在编写 Shader graph 过程中,遇到特别奇怪的问题:所有节点和连线都是正确的,但效果就是不对。那就需要查找一下,很可能就是某个节点出错了。删除再重新创建这个节点,或者点击 Remov Override 按钮↩️,重置输入输出可能就会恢复正常。

Instancing 技术

我在创建项目中的 Node Graph 时使用了 InstancingInstancing类似于单例,它可以节省 CPU 和内存成本,因为它只在内存中加载一个实例并重复使用它。但这样也造成了在使用时,有些许不方便,所以一般有 3 种方式来使用 RealityShaderExtension 中的节点。

  • a. 直接复制粘贴所有 Node Graph,包含嵌套的。无需导入源文件,但需要手工复制嵌套的 Node。
  • b. 将源文件放在项目中,右键创建 Instancing,再复制粘贴 Instancing 节点。适合大量重复使用

如果修改原始 Node Graph,所有 Instancing 的内容将会同步发生变化。

  • c. 创建 Instancing,然后禁用 Instancing。无需导入源文件,相当于自动复制。

如果修改原始 Node Graph,禁用的实例化将不会发生变化,因为它们是不同的节点。

未来展望

在完成 RealityShaderExtension 中近百个节点的迁移工作后,我认为目前的 Shader Graph 使用门槛低适合入门,同时功能上基本完整,能够搭建出复杂效果。

不过 RCP 目前存在一些 bug,功能也需要进一步完善,比如:

  • 增强与 Xcode 中代码的协作功能
  • 增加对材质文件的双向索引功能,移动源文件不会影响引用了它的文件

最后,希望 RealityShaderExtension 对大家的开发有所帮助!

参考

相关推荐
jimumeta2 个月前
虚拟现实(VR)与增强现实(AR)有什么区别?
ar·vr·虚拟现实·增强现实
JovaZou4 个月前
Meta 发布 Quest 3S 头显及 AR 眼镜原型:开启未来交互新视界
ai·ar·交互·虚拟现实·增强现实
虹科数字化与AR4 个月前
安宝特分享 | AR技术重塑工业:数字孪生与沉浸式培训的创新应用
ar·数字孪生·ar眼镜·增强现实·工业ar
JovaZou4 个月前
Snap 发布新一代 AR 眼镜,有什么特别之处?
ai·ar·虚拟现实·华为snap·增强现实
学步_技术5 个月前
利用AI增强现实开发:基于CoreML的深度学习图像场景识别实战教程
人工智能·深度学习·ar·增强现实·coreml
斯裕科技5 个月前
新升级|优化航拍/倾斜模型好消息,支持处理多套贴图模型!
unity·ue5·3dsmax·虚拟现实·maya·增强现实
Successssss~5 个月前
【高校主办,EI稳定检索】2024年人机交互与虚拟现实国际会议(HCIVR 2024)
计算机视觉·人机交互·vr·虚拟现实·增强现实
学步_技术6 个月前
增强现实系列—深入探索ARKit:平面检测、三维模型放置与增强现实交互
机器学习·计算机视觉·交互·增强现实·虚拟现实技术·平面检测·vr/ar
Uncertainty!!6 个月前
初识增强现实(AR)
ar·增强现实