ブログ掲載用
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
}
}
}