边缘检测两个算法
1 片元着色器中计算每个纹素的卷积,设置阀值,判断该点是否为边缘,在边缘颜色与屏幕图片中做插值,如果为边缘则显示边缘颜色。
通常还会设置一个变量,是否改变出边缘外的颜色。
2 在片元着色器中将纹素重新转换到世界坐标,取得该纹素相对于相机的深度与法线,判断该纹素与周围纹素的深度与法线,如果差距过大(相对于自定义的阀值)则为边缘。
方法1适用于2d图片,方法2在3d的运用效果比较好,但是对于仅仅处理2d图片不适用。
下面方法2介绍
1获取该相机屏幕上的的深度与法线图
C#
获取深度与法线图
GetComponent<Camera>().depthTextureMode |= DepthTextureMode.DepthNormals;
仅获取深度图
GetComponent<Camera>().depthTextureMode |= DepthTextureMode.Depth
在shader中直接声明变量
sampler2D _CameraDepthNormalsTexture;
sampler2D _CameraDepthTexture;
可以通过Shader得出深度与法线
片元
深度图
深度
float d = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv);
法线图
法线-放在_CameraDepthNormalsTexture的xy内
fixed3 normal = DecodeViewNormalStereo(tex2D(_CameraDepthNormalsTexture, 1.uv).xy);
深度 - 放在_CameraDepthNormalsTexture的zw值内
float depth = DecodeFloatRG(tex2D(_CameraDepthNormalsTexture, i.uv).zw)
2 与周围纹素做对比。
首先取得周围纹素,与第一种方法类似
struct v2f {
float4 pos : SV_POSITION;
half2 uv[5]: TEXCOORD0;
};
v2f vert(appdata_img v) {
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
half2 uv = v.texcoord;
o.uv[0] = uv;
#if UNITY_UV_STARTS_AT_TOP
if (_MainTex_TexelSize.y < 0)
uv.y = 1 - uv.y;
#endif
o.uv[1] = uv + _MainTex_TexelSize.xy * half2(1,1) * _SampleDistance;
o.uv[2] = uv + _MainTex_TexelSize.xy * half2(-1,-1) * _SampleDistance;
o.uv[3] = uv + _MainTex_TexelSize.xy * half2(-1,1) * _SampleDistance;
o.uv[4</