baobao
4/11/2017 - 2:39 PM

ブログ掲載用

ブログ掲載用

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[ExecuteInEditMode]
public class ImageEffectBase : MonoBehaviour 
{
    Shader m_shader;
    protected Material m_mat;
    public string shaderName;

    void OnRenderImage(RenderTexture src, RenderTexture dest)
    {
        if (m_mat == null)
        {
            m_shader = Shader.Find(shaderName);
            m_mat = new Material(m_shader);
            m_mat.hideFlags = HideFlags.DontSave;
        }
        _OnRenderImage(src, dest);
    }
    protected virtual void _OnRenderImage (RenderTexture src, RenderTexture dest){Graphics.Blit(src, dest, m_mat);}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Outline : ImageEffectBase 
{
    public Color _lineColor;

    protected override void _OnRenderImage(RenderTexture src, RenderTexture dest)
    {
        m_mat.SetColor("_LineColor", _lineColor);
        Graphics.Blit(src, dest, m_mat);
    }
}
Shader "Hidden/Outline"
{
    Properties
    {
        _MainTex ("", 2D) = "" {}
    }

    CGINCLUDE

    #include "UnityCG.cginc"

    sampler2D _MainTex;

    // https://docs.unity3d.com/ja/540/Manual/SL-PropertiesInPrograms.html
    // > x には 1.0/width が含まれます
    // > y には 1.0/height が含まれます
    // > z には width が含まれます
    // > w には height が含まれます
    float2 _MainTex_TexelSize;

    // DepthTexture
    sampler2D_float _CameraDepthTexture;

    half4 _LineColor;

    fixed4 frag(v2f_img i) : SV_Target
    {
        // 4点のサンプリングをする
        // uv0 - uv1
        //  |     |
        // uv3 - uv2
        float2 uv0 = i.uv + float2(-_MainTex_TexelSize.x, -_MainTex_TexelSize.y);
        float2 uv1 = i.uv + float2(_MainTex_TexelSize.x, -_MainTex_TexelSize.y);
        float2 uv2 = i.uv + float2(_MainTex_TexelSize.x, _MainTex_TexelSize.y);
        float2 uv3 = i.uv + float2(-_MainTex_TexelSize.x, _MainTex_TexelSize.y);

        // 各サンプルのDepthTextureのvalue
        float depth0 = tex2D(_CameraDepthTexture, uv0).r;
        float depth1 = tex2D(_CameraDepthTexture, uv1).r;
        float depth2 = tex2D(_CameraDepthTexture, uv2).r;
        float depth3 = tex2D(_CameraDepthTexture, uv3).r;

        // debug
        // return float4(depth0,0,0,1);

        float linearDepth0 = Linear01Depth(depth0);
        float linearDepth1 = Linear01Depth(depth1);
        float linearDepth2 = Linear01Depth(depth2);
        float linearDepth3 = Linear01Depth(depth3);

        // debug
        //return float4(linearDepth3,0,0,1);

        // roberts cross operator
        // https://en.wikipedia.org/wiki/Roberts_cross
        float diff0 = linearDepth2 - linearDepth0;
        float diff1 = linearDepth3 - linearDepth1;

        float diff = diff0 * diff0 + diff1 * diff1;

        // debug
        // return float4(diff,0,0,1);

        fixed4 color = tex2D(_MainTex, i.uv);
        return fixed4(color.rgb + diff * _LineColor.rgb , 1);
    }

    ENDCG
    SubShader
    {
        Pass
        {
            CGPROGRAM
            #pragma vertex vert_img
            #pragma fragment frag
            ENDCG
        }
    }
}