【Unity Shader Graph 使用与特效实现】专栏 - 直达
全息投影着色器效果的核心原理与数学基础
全息投影的视觉本质与空间映射
全息投影特效的核心在于模拟 菲涅尔折射 + 干涉条纹 + 相位调制 的光学现象,通过 Shader Graph 实现虚拟的透明介质对光波的调制效果。其核心数学逻辑围绕以下两点展开:
- 菲涅尔透射率 :利用菲涅尔方程
F(θ) = (n1*cos(θi) - n2*cos(θt))² / (n1*cos(θi) + n2*cos(θt))²计算介质表面随视角变化的透光率,实现边缘更亮、中心更暗的视觉效果。 - 干涉条纹生成 :通过叠加两束虚拟光波的相位差
Δφ = k * (r1 - r2),模拟全息图上的莫尔条纹,公式简化为interference = sin(ω*(x*cos(α) + y*sin(β)) - ω*time)。
关键数学特性
- 折射率映射 :将物理折射率 n 映射到 Shader 中的传输系数 T,使用
T = 1 - F实现透光与反射的动态平衡。 - 干涉条纹频率 :控制全息图条纹密度,公式为
frequency = stripesPerUnit / worldScale。 - 相位调制 :通过顶点偏移
vertexOffset = amplitude * sin(frequency*UV + phaseOffset)模拟光波前畸变。
全息投影着色器效果的 Shader Graph 节点设计
核心节点功能概述
在 Unity Shader Graph 中实现全息投影,需整合菲涅尔计算、干涉条纹生成、相位调制等节点,核心功能包括:
- 菲涅尔遮罩生成 :基于视角与法线的夹角计算半透明度,使用
dot(viewDirection, normal)获得余弦值。 - 莫尔条纹叠加:叠加两组不同频率的正弦波,模拟全息图的网格干涉效果。
- 颜色混合策略:将透射颜色、反射颜色和背景颜色按菲涅尔权重混合,实现虚实结合。
- 动态调制控制:结合时间变量和顶点位移,实现全息图像的流动感和深度层次。
关键端口与参数定义
实现全息投影的核心参数端口设计如下:
| 端口名称 | 类型 | 功能说明 |
|---|---|---|
| World Position | Vector3 | 输入(只读),模型顶点的世界空间坐标 |
| Normal | Vector3 | 输入(只读),表面法线向量 |
| View Direction | Vector3 | 输入(只读),从顶点到相机的方向向量 |
| Time | Float | 输入(只读),实时时间变量,驱动动态调制 |
| Fresnel Power | Float | 输入(可调节),菲涅尔效果的强度指数 |
| Transmission Color | Color | 输入(可调节),透射的背景颜色 |
| Reflection Color | Color | 输入(可调节),表面反射的颜色 |
| Background Color | Color | 输入(可调节),全息图显示的背景 |
| Interference Frequency | Float | 输入(可调节),干涉条纹密度 |
| Moiré Offset | Vector2 | 输入(可调节),莫尔条纹的相位偏移 |
| Phase Shift Speed | Float | 输入(可调节),相位流动速度 |
| Transparency Alpha | Float | 输入(可调节),整体透明度控制 |
| Hologram Glow | Float | 输入(可调节),全息发光强度 |
| Base Color | Color | 输入(可调节),模型的基础颜色 |
| Out Color | Vector4 | 输出,最终的着色器颜色,连接到 Master 节点 |
全息投影着色器效果的实现步骤(可复现)
前置准备
- 环境要求:Unity 2021.3+,URP 渲染管线,已安装 Shader Graph 插件。
- 素材准备:透明或半透明材质(如玻璃板/薄塑料),用于测试全息投影效果。
- 创建基础 Shader :
- 在 Project 窗口右键 → Create → Shader → Universal Render Pipeline → Lit Shader Graph,命名为 "HologramProjectorShader"。
- 双击打开 Shader Graph,确认 Master 节点为 URP Lit Master。
步骤 1:计算视角依赖的菲涅尔遮罩
-
获取相向向量:
- 添加
View Direction节点:viewDir = normalize(cameraPos - worldPosition)。 - 若无 Camera 节点,可用自定义 Vector3 端口输入相机位置。
- 添加
-
菲涅尔强度计算:
- 添加
Dot节点,计算dot(normalize(viewDir), normal)。 - 使用
Lerp(-1, 1, dotResult)映射到 -1,1 范围(Sine 函数需要对称输入)。 - 添加
Pow节点,公式为fresnel = pow(abs(Lerp(-1, 1, dotResult)), fresnelPower)。
- 添加
-
透明度混合:
- 使用
Lerp(transmissionColor, backgroundColor, fresnel * transparencyAlpha)。
- 使用
步骤 2:生成莫尔干涉条纹
-
第一组条纹(X 轴方向):
- 添加
Sine节点,输入公式为xStr = Interference Frequency * worldPosition.x + time * Phase Shift Speed。 - 映射到 0,1:
xMask = Remap(xStr, -1, 1, 0, 1)。
- 添加
-
第二组条纹(Y 轴方向):
- 添加
Sine节点,输入公式为yStr = Interference Frequency * worldPosition.y + time * Phase Shift Speed + MoiréOffset.y。 - 映射到 0,1:
yMask = Remap(yStr, -1, 1, 0, 1)。
- 添加
-
莫尔图案叠加:
- 添加
Multiply节点,将 xStr 和 yStr 相乘得到网格效果。 - 使用
Sin对乘积求正弦值实现干涉条纹。 - 公式:
moire = sin(worldPosition.x * interferenceFreq + worldPosition.y * interferenceFreq - time * phaseSpeed + moiréOffset)。
- 添加
步骤 3:相位调制与顶点偏移
-
法线扰动模拟:
- 添加
Split节点,将 Normal 拆分为 nx、ny、nz 分量。 - 使用
Sin节点对 nx、ny 进行相位调制:distortedNx = sin(nx * interferenceFreq + time * phaseSpeed)。 - 合并扰动后的法线:
distortedNormal = Vector3(distortedNx, distortedNy, nz)。
- 添加
-
归一化 :添加
Normalize确保法线单位长度。
步骤 4:颜色混合与最终输出
-
透射 - 反射混合:
- 添加
Lerp节点,公式为mix = Lerp(Reflection Color, Transmission Color, Fresnel)。
- 添加
-
干涉条纹叠加:
- 添加
Multiply节点,将莫尔条纹与透射颜色相乘:transmissionWithMoire = moire * transmissionColor。 - 添加
Add节点合并基础混合与干涉效果。
- 添加
-
发光效果叠加:
- 添加
Pow节点,对菲涅尔强度取幂:glow = fresnelPow(3) * Hologram Glow。 - 将 glow 连接到 Emission 端口。
- 添加
-
连接到 Master 节点:将最终颜色连接到 URP Lit Master 的 "Base Color" 端口,发光效果连接 "Emission"。
步骤 5:保存并应用 Shader
- 点击 Shader Graph 窗口的 "Save Asset" 保存着色器。
- 在 Project 窗口右键 → Create → Material,命名为 "HologramProjectorMaterial",将 Shader 赋值。
- 重要设置:将材质的渲染模式设为 "Transparent"(透明),排序层次设为 "Queue -1"(前置渲染)。
- 将该材质赋予场景中的平面或薄板模型,进入 Play 模式即可看到全息投影效果。
全息投影着色器效果的实战调优与扩展案例
基础案例:边缘发光全息图(科技扫描舱效果)
场景描述
在科幻游戏中实现类似《赛博朋克 2077》的扫描舱全息界面,边缘高亮发光,中心显示背景信息。
调整步骤
-
设置菲涅尔参数:
- Fresnel Power:设为 5(强化边缘发光)。
- Transparency Alpha:设为 0.8(整体半透明)。
- Hologram Glow:设为 2(发光强度适中)。
-
颜色配置:
- Transmission Color:(0.1,0.3,0.6,0.5)(蓝色透射)。
- Reflection Color:(0.9,0.9,1,1)(淡银色反射)。
- Background Color:(0.2,0.4,0.8,0.7)(深空蓝背景)。
-
干涉条纹参数:
- Interference Frequency:设为 8(条纹密度适中)。
- Moiré Offset:(0,1)(Y 轴偏移产生斜向条纹)。
- Phase Shift Speed:设为 2(中等流动速度)。
进阶案例:多图层全息投影(信息叠加效果)
场景描述
在 UI 层叠展示多组全息信息,每组具有不同的透明度、条纹频率和颜色。
实现步骤
-
创建多层分支:
- 复制菲涅尔计算节点网络。
- 第一层:高频条纹(frequency=12)用于显示详细数据。
- 第二层:低频条纹(frequency=5)用于背景轮廓。
- 第三层:无条纹纯色层用于文字显示。
-
混合层级:
- 使用
Add节点叠加各层颜色,设置不同 Alpha 实现深度层次。 - 公式:
finalColor = layer1*(0.7) + layer2*(0.3) + layer3*(0.5)。
- 使用
高阶案例:动态全息投影(信息滚动效果)
场景描述
模拟全息屏幕上滚动的数据流,条纹和相位随时间变化,营造数据流动的视觉特征。
实现步骤
-
垂直方向滚动调制:
- 添加
Add节点到 worldPosition.y:scrollY = worldPosition.y + time * scrollSpeed。 - 将 scrollY 代入条纹公式,实现向上滚动的视觉效果。
- 添加
-
闪烁效果叠加:
- 在菲涅尔遮罩后添加
Sin:blink = 0.5 + 0.5*sin(time*3)。 - 用
Multiply将整体透明度与 blink 相乘,实现周期性亮暗变化。
- 在菲涅尔遮罩后添加
全息投影着色器效果的使用技巧与注意事项
空间坐标选择
- 对象空间(Object Space):全息图随模型移动而移动,适合手持设备、可动投影平台。
- 世界空间(World Space):全息图固定于场景,适合场景装饰、固定信息台。
- 相机空间(View Space):结合 View Position 节点,使全息图始终面向相机,增强可见性。
性能优化
- 减少条纹密度:Interference Frequency 建议不超过 15,避免 GPU 高频采样。
- 复用 Shader Function:将菲涅尔计算封装为独立 Function,便于多个全息表面共享。
- 控制层数叠加:多图层时限制在 3 层内,超过会显著增加性能开销。
视觉增强技巧
- 景深模糊:结合 Depth 节点,对远距离的全息图添加模糊效果,增强空间层次。
- 屏幕泛光 :使用
Screen Space Ambient Occlusion(SSAO)或自定义 Screen Glow 节点模拟环境反射。 - 动态颜色变化:将 Background Color 与场景主色调联动,实现自适应色彩融合。
常见问题排查
- 全息图不可见:检查材质渲染模式是否为 Transparent,排序层次是否在 Queue -1 到 240 之间。
- 条纹过于密集:降低 Interference Frequency,或增加世界缩放比例(将 position 除以 scale)。
- 发光过强导致烧屏 :减小 Hologram Glow 值,或在 Emission 前添加
Clamp限制范围。
全息投影着色器效果的拓展应用
总结
Unity Shader Graph 中的全息投影效果核心是通过 "菲涅尔视角依赖 + 莫尔干涉条纹 + 相位动态调制",实现从物理光学现象到虚拟视觉特效的转换。通过调整透射/反射/背景颜色、条纹频率、发光强度等参数,可适配科幻界面、数据可视化、AR 增强等多种场景需求。
拓展应用
- AR 全息标记:结合 AR Foundation,将全息图与真实世界锚点绑定,实现增强现实中的虚拟物体投影。
- 全息菜单 UI:在技能栏/任务菜单中替代传统 UI,使用全息效果提升沉浸感。
- 动态信息流:将数据更新速率映射到 Phase Shift Speed,快速滚动显示高优先级信息。
- 多色全息分屏:将不同区域分配 RGB 通道颜色,实现 RGB 分离的全息显示效果,增强赛博朋克风格。
【Unity Shader Graph 使用与特效实现】专栏 - 直达 (欢迎点赞留言探讨,更多人加入进来能更加完善这个探索的过程,🙏)