エッジ検出シェーダ
[特徴:支持体調整、エッジ検出畳み込み演算子の任意の2種類の
[[原理:コンボリューション法、画素検出周囲の画素の彼垂直または水平方向それぞれの時間について計算。実現定義重みは、水平または垂直画素のエッジがあるか否かを判定する。値は、特別な処理を、エッジ画素で十分な大きさである場合。
(笑)犬の描画:
Shader "Custom/sobel" {
Properties {
_MainTex ("贴图", 2D) = "white" {}
_Size("力度", range(0.00,2000)) = 40
_IsSobel("Sobel or Roberts or Canny", range(0.0,3.0)) = 0
}
SubShader {
pass{
Tags{"LightMode"="ForwardBase" }
Cull off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
float _Size;
float _IsSobel;
sampler2D _MainTex;
//用于配合TRANSFORM_TEX
float4 _MainTex_ST;
struct v2f {
float4 pos:SV_POSITION;
float2 uv:TEXCOORD0;
};
//顶点着色器
v2f vert (appdata_full v) {
v2f o;
o.pos=UnityObjectToClipPos(v.vertex);
//将模型顶点的uv和Tiling、Offset进行运算求得最终的uv
o.uv = TRANSFORM_TEX(v.texcoord,_MainTex);
return o;
}
//边缘检测因子运算
float4 Get_Sobel(sampler2D mainTex, float2 uv){
//Sobel算子 x
float g_x[9] =
{-1, 0, 1,
-2, 0, 2,
-1, 0, 1};
//Sobel算子 y
float g_y[9] =
{1, 2, 1,
0, 0, 0,
-1,-2,-1};
//要输出的颜色
float GX = 0;
float GY = 0;
//灰度因子
float3 lum = float3(0.2125, 0.7154, 0.0721);
//遍历3*3 算子计算所有的像素]
int gCount = 0;
//0 1 2 该矩阵处理顺序,4是当前像素点
//3 4 5
//6 7 8
for (int i = -1; i < 2; i++)
{
for (int j = -1; j < 2; j++)
{
//获取包含当前像素与其周围在内的9个像素uv位置, uv+ (可调节的偏移)
float2 new_uv = float2(uv.x + j / _Size , uv.y + i / _Size);
//根据uv定位获取该uv位置的像素信息
float4 color = tex2D(mainTex, new_uv);
// luminance点积,求出亮度值(黑白图)
float _g = dot(color.rgb, lum);
//当前亮度值 分别乘以x、y的算子,得到边缘数据
GX += (_g * g_y[gCount]);
GY += (_g * g_x[gCount]);
gCount += 1;
}
}
//length的内部算法就是灰度公式的算法,欧几里得长度
float4 color = length(float2(GX, GY));
//过滤器
if(color.r < 0.5){
//区域区域涂黑
color = 0;
//透明测试,其余区域不显示
//clip(color.a - 1);
}
return color;
}
// Roberts算子
float4 Get_Roberts(sampler2D mainTex, float2 uv){
//Sobel算子 x
float g_x[4] =
{1, 0,
0, -1};
//Sobel算子 y
float g_y[4] =
{0, 1,
-1, 0};
//要输出的颜色
float GX = 0;
float GY = 0;
//灰度因子
float3 lum = float3(0.2125, 0.7154, 0.0721);
//遍历3*3 算子计算所有的像素]
int gCount = 0;
//0 1 2 该矩阵处理顺序,4是当前像素点
//3 4 5
//6 7 8
for (int i = -1; i < 1; i++)
{
for (int j = -1; j < 1; j++)
{
//获取包含当前像素与其周围在内的9个像素uv位置, uv+ (可调节的偏移)
float2 new_uv = float2(uv.x + j / _Size , uv.y + i / _Size);
//根据uv定位获取该uv位置的像素信息
float4 color = tex2D(mainTex, new_uv);
// luminance点积,求出亮度值(黑白图)
float _g = dot(color.rgb, lum);
//当前亮度值 分别乘以x、y的算子,得到边缘数据
GX += (_g * g_y[gCount]);
GY += (_g * g_x[gCount]);
gCount += 1;
}
}
//length的内部算法就是灰度公式的算法,欧几里得长度
float4 color = length(float2(GX, GY));
//过滤器
if(color.r < 0.5){
color = 0;
}
return color;
}
// Canny算子
float4 Get_Canny(sampler2D mainTex, float2 uv){
//Sobel算子 x
float g_x[4] =
{-1, 1,
-1, 1};
//Sobel算子 y
float g_y[4] =
{1, 1,
-1, -1};
//要输出的颜色
float GX = 0;
float GY = 0;
//灰度因子
float3 lum = float3(0.2125, 0.7154, 0.0721);
//遍历3*3 算子计算所有的像素]
int gCount = 0;
//0 1 2 该矩阵处理顺序,4是当前像素点
//3 4 5
//6 7 8
for (int i = -1; i < 1; i++)
{
for (int j = -1; j < 1; j++)
{
//获取包含当前像素与其周围在内的9个像素uv位置, uv+ (可调节的偏移)
float2 new_uv = float2(uv.x + j / _Size , uv.y + i / _Size);
//根据uv定位获取该uv位置的像素信息
float4 color = tex2D(mainTex, new_uv);
// luminance点积,求出亮度值(黑白图)
float _g = dot(color.rgb, lum);
//当前亮度值 分别乘以x、y的算子,得到边缘数据
GX += (_g * g_y[gCount]);
GY += (_g * g_x[gCount]);
gCount += 1;
}
}
//length的内部算法就是灰度公式的算法,欧几里得长度
float4 color = length(float2(GX, GY));
//过滤器
if(color.r < 0.5){
color = 0;
}
return color;
}
//片元着色器
float4 frag(v2f o):SV_Target
{
fixed4 outColor;
if(_IsSobel > 0 && _IsSobel < 1){
outColor = Get_Sobel(_MainTex, o.uv);
}
if(_IsSobel > 1 && _IsSobel < 2){
outColor = Get_Roberts(_MainTex, o.uv);
}
if(_IsSobel > 2 && _IsSobel < 3){
outColor = Get_Canny(_MainTex, o.uv);
}
return outColor;
}
ENDCG
}
}
}