试玩 RealityComposerPro 中的 Shader Graph:用圆环制作一个 Meta Logo

说明

以前在写计算几何时,写到过 S04E11: 李萨如曲线体网格生成,其中在一个圆环上叠加 2 个周期的正弦波动(即 2*2π),即可生成 Meta Logo 的 Mesh 网格几何体。

实际上,借用同样的思路只用编写 Shader,也能将一个圆环变成一个 Meta Logo。刚好此次 Xcode 15 中的 Reality Composer Pro 支持了 Shader Graph 功能,让我们能够通过拖拖拽拽就能编写好一个 Shader,那就来试玩一下吧!

准备工作

不过首先,我们需要一个圆环体,这里不得不吐槽一下,以前在 SceneKit 编辑器界面可以直接拖拽生成圆环体的,现在 Reality Composer Pro 却只有立方体球体等几种。这里不得不借助 Blender 生成一下基础的圆环体,记得将主环段数设置的稍微大一些,这样变形后的几何体也会平滑。导出为 .usdc 文件即可。

在 Xcode 中打开 Reality Composer Pro,创建一个新的工程。 将模型导入,并拖动到 3D 场景中,因为没有材质,所以整个模型显示为紫红色条纹,我们需要创建一个新的材质。 将材质应用到圆环几何体上,然后选中材质,打开 Shader Graph 面板,可以愉快地编写 Shader 了。 添加新的 Shader 节点的方法是:在空白处双击,或从任一输入或输出拖拽出来,即可弹出选择面板。推荐采用拖拽方式,因为这样可以自动匹配类型,比如从输出拖拽时,输出类型是 vector3 的话,弹出界面中会筛选出可以接受 vector3 类型的节点。

另外需要提前注意的是:圆环模型大环在 XY 平面上,半径 2m,小环是绕 Z 轴旋转,半径 0.25m。要得到 Meta Logo 我们需要编写 Shader 将圆环上的点沿 Z 轴进行偏移。

基本思路

如果直接对所有点沿着 Z 轴进行偏移的话,因为不同位置的偏移量不一致,会导致圆环变得扁平。 这时我们就需要先沿旧法线将小环收缩成一条线并添加 Z 坐标扭曲,然后重新计算扭曲后的法线,再沿新的法线恢复小环,就能让小环恢复成圆形。整体流程和效果如下图所示: 接下来,我们按照五个主要流程来讲解计算的原理。

1.收缩小环

要收缩小环其实非常简单,添加一个 GeometryModifier,然后将所有的点沿法线移动 -0.25,即可将小环缩小到 0。用伪代码表达:

scss 复制代码
newPosition =  position + normal * (-0.25)

当然,如果此时直接缩小到 0 就看不到,为了方便观察可以先移动 -0.245 但是,因为最终返回的是偏移量 Position Offset,也就是将原有的点移动多少而不是每个点的具体位置,这样会导致后续计算出现困难,所以我们还需要做一些小的修改:先加上原始位置,得到偏移后的坐标,中间计算可以在此基础上进行,最终输出时再减去原始位置,得到最终偏移量做为输出。

因为在下一步中,我们需要对 Z 坐标进行单独操作,这时我们就需要用到另外两个节点:Separate3Combine3 ,前者可以将三维向量分解为三个单独的量,后者则是将三个单独的量组合为一个三维向量。 选中前面多个节点,点击右键,选择:Compose Node Graph 来压缩节点整理一下,将压缩后的命名为:CenterLine 。至此,收缩小环的工作完美完成了!

2.扭曲大环

要扭曲大环,我们需要知道每一个点在大环上的位置,或者说角度。这里我们使用 atan2 函数来求夹角,将 XY 坐标输入就得到该点相对于 X 轴的夹角,输出范围为 (-π,π]。 接下来对 Z 坐标添加 2 个周期的扭曲,波动幅度也是 2m,用伪代码表达就是:

ini 复制代码
angle = atan2(x, y)
z = sin(2*angle) * 2

可以看到大环发生了明显的扭曲,转动不同位置观察,就会发现已经和 Meta Logo 比较相似了。

3.计算扭曲切线

要获取扭曲后的法线,需要先计算扭曲后大环的切线。这里我们补充一点数学知识:如果已知一条曲线的数学表达式,要求任意点的切线,只需要对其表达式求导即可。那么收缩后的图形的表达式为:

matlab 复制代码
// 大环半径为 2 米
x = sin(angle) * 2
y = cos(angle) * 2
z = sin(2*angle) * 2

//对其求导后
x' = cos(angle)
y' = -sin(angle)
z' = cos(2*angle) * 2 //复合函数求导链式法则:f[(g(x))]' = f'[g(x)] * g'(x),也就是说:sin'(2x) = cos(2x) * 2;sin'(3x) = cos(3x) * 3;sin'(4x) = cos(4x) * 4

最后要对求出的切线长度进行归一化 Normalize ,以便后续处理,顺便将节点整理压缩一下,如下图:

4.计算扭曲法线

我们先用切线和旧的法线,进行叉乘得到副切线。将副切线与切线再次进行叉乘,即可得到新的法线方向。这里需要副切线,是因为我们扭曲 Z 坐标时,副切线不变,它实际相当于旋转轴。 这里需要注意叉乘的顺序:叉乘遵守右手螺旋法则,右手手指从第一个向量出发,向第二个向量弯曲,大拇指方向就是新向量的方向。 用伪代码表示如下:

ini 复制代码
bitangent = cross(tangent, oldNormal)
newNormal = cross(bitangent, tangent)

修改 Shader Graph 如下,最后记得将求出的新法线,赋值给 GeometryModifierNormal 属性,以便显示出正确的光照效果。

5.恢复小环

恢复小环也很简单,将挤在中心线上的点沿新的法线移动 0.25 米即可,用伪代码表达:

ini 复制代码
newPosition = centerOffset + newNormal * 0.25

还要记得,将前面的 -0.245 改为 -0.25,以便获得更完美的效果。整理好的 Shader Graph 如下: 展开后完全版 Shader Graph 如下:

6.其他

最后,我们选中物体,将其绕 X 轴旋转 90 度,这样看上去更像 Meta Logo 了。因为我们的 Shader Graph 是作用在 Geometry 上,也就是模型空间坐标系,所以外部旋转并不会影响 Shader 的坐标系。 相信大家也发现了,当我们选中物体时,显示的高亮轮廓仍然是原来的圆环的形状,这是因为 Shader 代码工作在 GPU 上,我们只更改了物体的显示效果。当物体与其他物体(包括鼠标,眼动等交互操作)交互时,实际是在 CPU 上处理的物理碰撞计算,这些我们并没有专门处理。

最后的最后,如果想要显示更多周期的波动,只需要将下图中红色框中倍数进行更改即可,比如改为 3个周期:

总结

此次 Reality Composer Pro 的更新非常强大,尤其是对 Shader Graph 的支持让人惊喜,从使用者的角度,使用 Shader Graph 比直接编写 Shader 代码要容易很多,可以有效降低入门门槛。缺点方面:偶尔会遇到一些类型的 bug;另外缺少 Debug 功能让人编写代码时难以调试。

总之,功能强大,简洁好用,推荐初学者都来试试!

本文工程代码已开源,github 地址: github.com/XanderXu/Sh...

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