如何在片元着色器中绘制间距可自定义的多行线条
自定义间距线条图案的实现方案
核心思路
不用循环的关键是靠纯数学函数生成线条掩码——通过坐标映射和区间判断,把线条间距、线宽拆成两个完全独立的参数,彻底解决cos()方案中间距与线宽绑定的问题。
具体实现(以2D水平线条为例)
1. 定义独立参数
line_spacing:线条+间隙的总间距(控制线条排列密度)line_width:单条线的宽度(完全独立于间距,想设多宽就多宽)y:当前绘制点的Y坐标(垂直线条替换成X坐标即可)
2. 坐标归一化
用取模运算把Y坐标映射到单个间距周期内,实现循环排列:
float normalized_y = mod(y, line_spacing);
(不同语言写法略有差异:比如Python用np.mod(),Processing用%运算符)
3. 生成线条掩码
判断当前点是否落在线条区域内,生成0/1的掩码(1表示绘制线条,0表示空白):
- 硬边缘线条:
float line_mask = step(normalized_y, line_width);
- 软边缘平滑线条:
float edge_blur = 0.3; // 可调的边缘模糊度 float line_mask = smoothstep(line_width + edge_blur, line_width - edge_blur, normalized_y);
4. 扩展为动态图案
如果想要类似你示例的变化线条,只需给line_width或line_spacing叠加随位置变化的函数即可,比如让线条宽度随X坐标波动:
float varying_width = line_width * (0.6 + 0.4*sin(x*0.05)); float line_mask = step(normalized_y, varying_width);
此时线条宽度动态变化,但间距依然保持均匀,完全不受线宽影响。
为什么这比cos()方案更好
cos()生成的是周期性渐变,线条的有效宽度和间距由余弦波的振幅、周期绑定,没法单独调整;而上面的方法直接拆分了间距和线宽两个参数,间隙 = line_spacing - line_width,完全由你掌控,且全程不需要代码循环,纯数学计算实现。
适配不同工具
这个逻辑在任何支持数学运算的绘图环境都通用:
- Shader(GLSL/HLSL):直接用上述代码片段
- Processing:结合
mod()和step()函数实现 - Python(Matplotlib/Numpy):用向量化运算替代循环,比如
np.where(np.mod(y, line_spacing) < line_width, 1, 0)
内容的提问来源于stack exchange,提问作者Dilado
相关产品推荐
相关产品推荐

