shader实现屏幕处理效果——边缘检测

       边缘检测的原理主要是利用一些边缘检测算子来对图像进行卷积操作。

        还是一样的,直接上代码啦。

1.新建一份c#脚本,还是一样的哦,改脚本必须挂在摄像机上,还有就是改脚本所继承的基类脚本在之前的文章中也有PostEffectsBase,不上代码了。需挂在摄像机上的脚本代码如下:

public class EdgeDetection : PostEffectsBase {

public Shader edgeDetectShader;

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;

void OnRenderImage (RenderTexture src, RenderTexture dest) {

if (material != null) {

material.SetFloat("_EdgeOnly", edgesOnly);

material.SetColor("_EdgeColor", edgeColor);

material.SetColor("_BackgroundColor", backgroundColor);

Graphics.Blit(src, dest, material);

} else {

Graphics.Blit(src, dest);

}

}

}

2.新建一个顶点着色器的shader

Shader "Unity Shaders Book/Chapter 12/Edge Detection" {

Properties {

_MainTex ("Base (RGB)", 2D) = "white" {}

_EdgeOnly ("Edge Only", Float) = 1.0

_EdgeColor ("Edge Color", Color) = (0, 0, 0, 1)

_BackgroundColor ("Background Color", Color) = (1, 1, 1, 1)

}

SubShader {

Pass {

ZTest Always Cull Off ZWrite Off

CGPROGRAM

#include "UnityCG.cginc"

#pragma vertex vert

#pragma fragment fragSobel

sampler2D _MainTex;

uniform half4 _MainTex_TexelSize;

fixed _EdgeOnly;

fixed4 _EdgeColor;

fixed4 _BackgroundColor;

struct v2f {

float4 pos : SV_POSITION;

half2 uv[9] : TEXCOORD0;

};

v2f vert(appdata_img v) {

v2f o;

o.pos = mul(UNITY_MATRIX_MVP, v.vertex);

half2 uv = v.texcoord;

o.uv[0] = uv + _MainTex_TexelSize.xy * half2(-1, -1);

o.uv[1] = uv + _MainTex_TexelSize.xy * half2(0, -1);

o.uv[2] = uv + _MainTex_TexelSize.xy * half2(1, -1);

o.uv[3] = uv + _MainTex_TexelSize.xy * half2(-1, 0);

o.uv[4] = uv + _MainTex_TexelSize.xy * half2(0, 0);

o.uv[5] = uv + _MainTex_TexelSize.xy * half2(1, 0);

o.uv[6] = uv + _MainTex_TexelSize.xy * half2(-1, 1);

o.uv[7] = uv + _MainTex_TexelSize.xy * half2(0, 1);

o.uv[8] = uv + _MainTex_TexelSize.xy * half2(1, 1);

return o;

}

fixed luminance(fixed4 color) {

return  0.2125 * color.r + 0.7154 * color.g + 0.0721 * color.b;

}

half Sobel(v2f i) {

const half Gx[9] = {-1,  0,  1,

-2,  0,  2,

-1,  0,  1};

const half Gy[9] = {-1, -2, -1,

0,  0,  0,

1,  2,  1};

half texColor;

half edgeX = 0;

half edgeY = 0;

for (int it = 0; it < 9; it++) {

texColor = luminance(tex2D(_MainTex, i.uv[it]));

edgeX += texColor * Gx[it];

edgeY += texColor * Gy[it];

}

half edge = 1 - abs(edgeX) - abs(edgeY);

return edge;

}

fixed4 fragSobel(v2f i) : SV_Target {

half edge = Sobel(i);

fixed4 withEdgeColor = lerp(_EdgeColor, tex2D(_MainTex, i.uv[4]), edge);

fixed4 onlyEdgeColor = lerp(_EdgeColor, _BackgroundColor, edge);

return lerp(withEdgeColor, onlyEdgeColor, _EdgeOnly);

}

ENDCG

}

}

FallBack Off

}

实现效果如下:


shader实现屏幕处理效果——边缘检测_第1张图片

你可能感兴趣的:(shader实现屏幕处理效果——边缘检测)