GLSL 效果示例

Sobel 边缘检测:从照片中提取亮度轮廓

平坦区域变黑,对比度突变处形成白线,与透明剪影描边不同。

在线示例

修改右侧代码,左侧预览会实时更新。

观察什么

平坦区域变黑,对比度突变处形成白线,与透明剪影描边不同。

实现原理

两个 Sobel 核分别估计水平和垂直亮度变化,再合成为梯度长度;平坦区域应接近黑色。

找到控制效果的代码

vec2 px=vec2(1.+u_parameter*3.)/256.;float gx=0.,gy=0.;for(int y=-1;y<=1;y++)for(int x=-1;x<=1;x++){float l=dot(texture2D(u_texture,uv+vec2(float(x),float(y))*px).rgb,vec3(.299,.587,.114));gx+=l*float(x)*(y==0?2.:1.);gy+=l*float(y)*(x==0?2.:1.);}c=vec3(length(vec2(gx,gy)));

动手修改

把 u_parameter 从 0 调到 1,px=vec2(1.+u_parameter*3.)/256. 会从一个纹理像素增至四个。采样间距增大后,网格和字母边缘会扩展到更宽的区域。

调试与成本

gx 与 gy 共用九次原图读取,再由 length(vec2(gx,gy)) 合并。把最后的 length 换成 abs(gx),可单看横向亮度变化,许多水平线的响应会消失。

深入理解

用到的内置函数

一步步学会这个效果