如何使用Unity无光照Shader绘制等厚度曲线?
解决方案:用垂直距离场实现均匀厚度曲线
你的问题根源是用了UV空间的垂直范围判断——这种方式相当于给曲线套了个水平条带,当曲线倾斜时,条带垂直于曲线的实际宽度会被压缩,视觉上就变细了。用像素到曲线的垂直距离来判断,就能保证任何斜率下厚度都均匀。
具体实现步骤:
- 计算曲线在当前UV.x处的函数值
y和导数dy_dx(即曲线斜率) - 用公式计算像素到曲线的垂直距离:
distance = abs(i.uv.y - y) / sqrt(1 + dy_dx * dy_dx) - 用距离与厚度阈值比较,搭配
smoothstep实现平滑抗锯齿边缘
修改后的frag代码:
float4 frag(v2f i) : SV_Target { float4 color = float4(0, 0, 0, 1); float x = 20 * i.uv.x; float y = 0.45 * sin(x) + 0.5; // 链式法则计算导数:sin(x)对i.uv.x的导数是cos(x)*20,再乘系数0.45 float dy_dx = 0.45 * cos(x) * 20; float thickness = 0.02; // 计算像素到曲线的垂直距离 float distance = abs(i.uv.y - y) / sqrt(1 + dy_dx * dy_dx); // smoothstep实现平滑边缘,避免硬边锯齿 float edge = smoothstep(thickness * 0.5, thickness * 0.5 - 0.002, distance); color = lerp(color, float4(1, 0, 0, 1), edge); return color; }
关键细节说明:
- 导数计算必须遵循链式法则:由于你的x是
20*i.uv.x,所以对i.uv.x求导时要乘上20的系数 smoothstep的参数设置是为了让距离小于厚度一半时完全着色,大于时完全透明,中间有平滑过渡,解决硬边锯齿问题- 这种方法性能开销极低,仅增加了几个基础数学运算,远优于你之前尝试的动态厚度调整方案
内容的提问来源于stack exchange,提问作者groszobquivousemmerde
相关产品推荐
相关产品推荐

