如何在Unity Shadergraph/HLSL中为任意几何体分布规则间距图案?
在Unity Shadergraph/HLSL中为任意几何体实现规则间距点阵图案的方案
核心问题分析
直接取世界空间坐标frac生成点阵出现拉伸、变暗,本质是投影方向与表面法线不垂直;三平面投影的接缝瑕疵则源于平面过渡权重不平滑或坐标未对齐。
解决方案:基于表面法线的正交投影UV生成
方法原理
为每个表面生成垂直于其法线的2D投影坐标,确保图案在任意倾斜、曲面上都保持规则间距:
- 以表面法线为Z轴,构建局部正交坐标系
- 将世界空间顶点坐标投影到该坐标系的XY平面
- 对投影后的坐标取
frac,生成规整点阵
Shadergraph实现步骤
- 核心节点组合:
- 读取
World Position和World Normal节点 - 用叉乘+正交化生成局部坐标系的X/Y轴:先取与法线不共线的参考向量(如
float3(1,0,0)),和法线叉乘得到第一个正交向量,再用法线与该向量叉乘得到第二个正交向量,最后用Orthonormalize节点修正 - 将
World Position分别与两个正交向量点积,得到投影后的2D坐标 - 对坐标取
frac,用Distance节点计算到点阵中心的距离,结合Smoothstep生成平滑的点阵图案
- 读取
HLSL代码实现(片段着色器)
float3 worldPos = i.worldPos; float3 worldNormal = normalize(i.worldNormal); // 构建正交局部坐标系 float3 tangent = normalize(cross(worldNormal, float3(0,1,0))); if (length(tangent) < 0.01) tangent = normalize(cross(worldNormal, float3(1,0,0))); float3 bitangent = cross(worldNormal, tangent); // 投影到局部XY平面 float2 uv = float2(dot(worldPos, tangent), dot(worldPos, bitangent)); // 生成规则点阵 float2 grid = frac(uv / _GridSpacing); // _GridSpacing为可调的点阵间距参数 float dist = distance(grid, float2(0.5, 0.5)); float dotPattern = smoothstep(_DotRadius + _Softness, _DotRadius, dist);
三平面投影接缝优化方案
若需处理复杂曲面,可优化三平面投影减少瑕疵:
- 采用平滑权重计算:基于法线与平面轴夹角余弦的n次方(n>1)分配权重,让平面过渡更自然
- 对齐采样坐标:确保三个平面的UV原点在世界空间中一致,避免接缝处图案错位
关键注意事项
- 所有几何体共用同一shader时,将
_GridSpacing等参数设为全局可调节的材质参数 - 顶点密度不影响效果,计算基于世界空间坐标而非顶点数量
- 生成式图案可直接基于上述UV计算,图像纹理直接采样该UV即可
内容的提问来源于stack exchange,提问作者Kit MacAllister
相关产品推荐
相关产品推荐

