美文网首页Unity技术分享
shader实现屏幕处理效果——边缘检测

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

作者: 陈_筱英 | 来源:发表于2017-11-23 19:04 被阅读28次

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

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

    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实现屏幕处理效果——边缘检测

        本文链接:https://www.haomeiwen.com/subject/esctbxtx.html