原理
利用边缘检测算子对图像进行卷积操作
如何知道哪里才算是边缘呢?
如果相邻像素之间存在差别明显的颜色、亮度、纹理等属性,我们就会认为它们之间应该有一条边界。这种相邻像素之间的插值可以用梯度来表示,边缘处的梯度绝对值会比较大.
三种常见的边缘检测算子
它们都包含了两个方向的卷积核,分别用于检测水平方向和竖直方向上的边缘信息,在进行边缘检测时,我们需要对每个像素分别进行一次卷积计算,得到两个方向上的梯度值GX和GY,整体的梯度计算公式如下:
处于性能考虑,有时会使用绝对值操作来代替开根号操作:
实现
我们使用Sobel算子进行边缘检测,实现描边效果.
首先,创建一个脚本:
public class EdgeDetection : PostEffectsBase
PostEffectsBase实现在饱和度那一篇里面有
然后声明相应的Shader,并据此创建相应的材质
public Shader edgeDetectShader;//相应的shader
private Material edgeDetectMaterial = null;//相应的材料
public Material material
{
get
{
edgeDetectMaterial = CheckShaderAndCreateMaterial(edgeDetectShader, edgeDetectMaterial);
return edgeDetectMaterial;
}
}
然后在脚本中提供用于调整边缘线强度、描边颜色以及背景颜色的参数:
[Range(0.0f, 1.0f)]
public float edgesOnly = 0.0f;//边缘线强度
public Color edgeColor = Color.black;//描边颜色
public Color backgroundColor = Color.white;//背景颜色
最后定义OnRenderImage
函数进行真正的特效处理:
void OnRenderImage(RenderTexture src, RenderTexture dest)
{
if (material != null)
{
material.SetFloat("_EdgeOnly", edgesOnly);
material.SetColor("_EdgeColor"