目录
一、节点功能概述
位置节点(Position Node)是 Unity Shader Graph 中用于获取网格顶点或片段位置信息的核心工具。它根据 Shader 执行阶段(顶点 / 片段)自动获取对应位置,并支持在多种坐标空间中输出。该节点在顶点动画、动态光照和空间变换中具有关键作用,核心优势在于:
- 多空间输出:支持对象空间、视图空间、世界空间等 6 种坐标空间
- 管线自适应:自动适配不同渲染管线(HDRP/URP)的世界空间定义
- 阶段感知:根据 Shader 阶段动态获取顶点或插值后的片段位置
二、端口与参数详解
2.1 端口配置
端口名称 | 方向 | 数据类型 | 描述 |
---|---|---|---|
Out | 输出 | Vector 3 | 网格的位置向量(3D 坐标) |
2.2 控制参数
参数名称 | 类型 | 选项 | 描述 |
---|---|---|---|
Space | 下拉菜单 | Object/View/World/Tangent/Absolute World | 输出位置的坐标空间: - Object:对象空间(模型本地坐标) - View:视图空间(摄像机坐标) - World:管线默认世界空间 - Tangent:切线空间 - Absolute World:绝对世界空间(不随管线变化) |
2.3 World 与 Absolute World 详解
2.3.1 渲染管线差异
管线类型 | World 空间定义 | Absolute World 定义 |
---|---|---|
HDRP | 摄像机相对坐标(Camera Relative) | 绝对世界坐标 |
URP | 绝对世界坐标 | 绝对世界坐标 |
旧版管线 | 绝对世界坐标 | 绝对世界坐标 |
2.3.2 版本兼容性
- Shader Graph 6.7.0+:
- 旧版 World 空间自动升级为 Absolute World
- HDRP 中 World 空间变为 Camera Relative
三、技术原理解析
3.1 坐标空间转换基础
位置节点的核心是坐标空间转换,涉及以下关键矩阵:
- 对象空间(Object):模型本地坐标系,位置由顶点数据直接提供
- 世界空间(World):
- 绝对世界坐标:
WorldPos = mul(unity_ObjectToWorld, float4(ObjectPos, 1)).xyz
- HDRP 摄像机相对坐标:基于摄像机位置的相对坐标
- 绝对世界坐标:
- 视图空间(View):
ViewPos = mul(unity_WorldToView, float4(WorldPos, 1)).xyz
- 切线空间(Tangent):表面局部坐标系,由切线、副切线和法线定义
3.2 底层实现逻辑
节点根据 Space 参数执行不同转换:
hlsl
float3 GetPosition(float3 objectPos)
{
float3 worldPos = mul(unity_ObjectToWorld, float4(objectPos, 1)).xyz;
if (Space == View)
{
return mul(unity_WorldToView, float4(worldPos, 1)).xyz;
}
else if (Space == AbsoluteWorld)
{
return worldPos; // 绝对世界坐标
}
else if (Space == World)
{
#if SHADERGRAPH_URP
return worldPos; // 绝对世界坐标
#elif SHADERGRAPH_HDRP
return worldPos - unity_CameraWorldPosition.xyz; // 摄像机相对坐标
#endif
}
// 其他空间转换...
}
四、应用场景与实战案例
4.1 顶点动画效果
场景:地形波浪动态变形
- 需求:基于世界空间位置实现全局波浪动画
- 实现:
hlsl
float3 worldPos = PositionNode.Out; // Space设为World float waveHeight = sin(worldPos.x * 0.1 + worldPos.z * 0.1 + _Time.y) * 0.5; float3 displacedPos = vertex + normal * waveHeight;
4.2 视差映射效果
场景:3D 纹理视差偏移
- 需求:基于视图空间位置计算视差偏移
- 步骤:
hlsl
float3 viewPos = PositionNode.Out; // Space设为View float2 offset = viewPos.xy * (depth * _ParallaxStrength); float3 texColor = tex2D(_MainTex, uv + offset).rgb;
4.3 阴影接收效果
场景:动态物体阴影偏移修正
- 需求:基于绝对世界位置修正阴影偏移
- 实现:
hlsl
float3 absWorldPos = PositionNode.Out; // Space设为AbsoluteWorld float3 shadowPos = absWorldPos + normal * _ShadowBias;
五、使用技巧与注意事项
5.1 空间选择策略
应用场景 | 推荐空间 | 优势 |
---|---|---|
全局光照计算 | Absolute World | 确保不同管线一致性 |
摄像机相关效果 | View | 直接使用视图空间坐标 |
HDRP 特殊效果 | World | 利用摄像机相对坐标 |
模型本地变换 | Object | 基于模型坐标系操作 |
5.2 渲染管线适配
- URP/HDRP 兼容:
hlsl
float3 worldPos = PositionNode.Out; // Space设为World #if SHADERGRAPH_HDRP // HDRP中World是摄像机相对坐标,需转换为绝对世界坐标 worldPos = worldPos + unity_CameraWorldPosition.xyz; #endif
5.3 性能优化
- 减少矩阵运算:
预计算常用空间转换矩阵,避免重复计算 - 顶点阶段优先:
动态位置变换尽量在顶点阶段完成,减少片段阶段计算
六、总结与拓展应用
位置节点通过提供多空间的位置信息,成为 Unity Shader 中空间变换和动态效果的基础支撑,其核心价值在于:
- 跨管线兼容性:通过 Absolute World 确保不同管线的一致性
- 动态效果基础:为顶点动画、视差映射等效果提供位置数据
- 性能高效:直接访问引擎计算的位置数据,无额外开销
拓展方向:
- 结合 DOTS 实现大规模对象的位置批量处理
- 在 VR 中利用位置信息实现更精准的空间交互
- 开发基于位置的程序性生成算法(如地形、建筑)