如何为GLSL绘制的圆角矩形实现无瑕疵smoothstep抗锯齿?
解决GLSL圆角矩形抗锯齿黑色条纹问题
核心问题分析
你遇到的黑色条纹是因为错误地用不透明黑色作为混合底色,mix(vec4(0), v_color, 1.0 - smoothing)会让边缘从黑色过渡到目标色,导致出现黑色锯齿痕迹。直接修改背景色为透明白色也不对——抗锯齿的正确逻辑是调整目标颜色的Alpha通道实现边缘透明渐变,而非混合两种实体颜色。
修正后的代码
float roundedBoxSDF(vec2 center, vec2 size, float radius) { return length(max(abs(center) - size + radius, 0.0)) - radius; } void main() { // 基于屏幕分辨率的像素级柔化值(需传入屏幕宽高u_resolution) float edgeSoftness = 1.0 / u_resolution.y; // 计算当前像素到圆角矩形的SDF距离 vec2 boxCenter = v_loc + v_size / 2.0; float distance = roundedBoxSDF(v_pos.xy - boxCenter, v_size / 2.0, v_border_radius); // 计算Alpha通道:距离为负在矩形内(完全不透明),正的在外部(完全透明),中间平滑过渡 float alpha = smoothstep(edgeSoftness, -edgeSoftness, distance); // 直接应用Alpha到目标颜色,背景自动透明 outputColor = vec4(v_color.rgb, v_color.a * alpha); }
关键修改说明
- 移除错误的颜色混合:不再用
mix混合背景色,直接控制目标颜色的Alpha通道,让边缘自然过渡到透明,彻底消除黑色条纹。 - 像素级柔化值:用
1.0 / u_resolution.y作为柔化宽度,确保在任何分辨率下,抗锯齿过渡都精确对应1个屏幕像素,避免过度柔化或锯齿残留。如果没有分辨率 uniforms,也可以用固定值(如1.0,但需确保坐标空间是像素级的)。 - 调整smoothstep参数:
smoothstep(edgeSoftness, -edgeSoftness, distance)实现从外部(distance>edgeSoftness时alpha=0)到内部(distance<-edgeSoftness时alpha=1)的平滑过渡,刚好覆盖1像素的边缘范围。
额外注意事项
- 如果你的渲染管线使用预乘Alpha,需要调整颜色输出为:
outputColor = vec4(v_color.rgb * v_color.a * alpha, v_color.a * alpha); - 确保
v_pos的坐标空间与v_size、v_border_radius匹配:如果v_pos是归一化坐标(如[0,1]范围),1.0 / u_resolution.y已经是对应归一化单位,无需额外转换。
内容的提问来源于stack exchange,提问作者Ryan Peschel
相关产品推荐
相关产品推荐

