Shader屏幕后處理效果

Shader屏幕后處理效果

邊緣檢測:

边缘检测的原理是利用一些边缘检测算子对图像进行卷积操作(卷积操作就是使用一个卷积核对一张图像的每一个像素进行一系列的操作,倦急核通常是一个四方形网格结构,例如2x2,3x3的方形区域,该区域内每个方格都有一个权重值。当对图像中的某个像素进行卷积时,我们会把卷积核的中心放置在该像素上,如下图,翻转之后再依次进行计算核中的每个元素和其覆盖的图像像素值的乘积并求和,得到的结果就是改为只的新像素值)

常见的边缘检测算子

卷积操作的神奇指出 在于选择的卷积核,用于边缘检测的卷积核(边缘检测算子)是什么?  首先想一下  如果相邻像素之间存在差别明显的颜色,亮度等属性,那么他们之间应该有一条边界。这种相邻像素之间的差值可以用梯度来表示,边缘处的梯度绝对值比较大,所以,就出现下面几种边缘检测算子;

下面请看注释:
Shader "MyShader/OutLine"
{
	Properties{
		_MainTex("MainTexture",2D) = "White"{}
		_LineColor("OutLineColor",color) = (1,1,1,1)
		_BackGroundColor("BackGroundColor",color) = (1,1,1,1)
		_EdgeOnly("EdgeOnly",float)=3
	}
		SubShader{
			Tags{"RenderType" = "Transparent"}
		Pass
		{
			Cull off
			ZTest Always
			ZWrite off
			CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
			sampler2D  _MainTex;
		float4 _MainTex_TexelSize;
		fixed4 _LineColor;
		fixed4 _BackGroundColor;
		float _EdgeOnly;
			struct a2v {
					fixed4 vertex : POSITION;
					fixed2 uv : TEXCOORD;
				};
			struct v2f {
				fixed4 pos : SV_POSITION;
				fixed2 uv[9]:TEXCOORD;//对应了使用Sobel算子采样是需要的
				//九个领域纹理坐标
			};
			fixed luminance(fixed4 color)
			{
				return color.r*0.21 + color.g*0.37 + color.b*0.44;
			}
			half sobel(v2f v)  
			{
				const half Gx[9] = { 1,2,1,
					0,0,0,
					-1,-2,-1
				};
				const half Gy[9] = { 1,0,-1,
					2,0,-2,
					1,0,-1 };
				half texColor;
				half edgeX = 0;
				half edgeY = 0;
				for (int i = 0; i < 9; i++)
				{
					texColor = luminance(tex2D(_MainTex, v.uv[i])); 
					edgeX += texColor*Gx[i];
					edgeY += texColor*Gy[i];

				}
				return 1 - abs(edgeX) - abs(edgeY);
			}
			v2f vert(a2v v)
			{
				v2f o;
				o.pos = UnityObjectToClipPos(v.vertex);
				o.uv[0] = v.uv + _MainTex_TexelSize.xy*fixed2(-1,1);
				o.uv[1] = v.uv + _MainTex_TexelSize.xy*fixed2(0, 1);
				o.uv[2] = v.uv + _MainTex_TexelSize.xy*fixed2(1, 1);
				o.uv[3] = v.uv + _MainTex_TexelSize.xy*fixed2(-1,0);
				o.uv[4] = v.uv + _MainTex_TexelSize.xy*fixed2(0, 0);
				o.uv[5] = v.uv + _MainTex_TexelSize.xy*fixed2(1, 0);
				o.uv[6] = v.uv + _MainTex_TexelSize.xy*fixed2(-1, -1);
				o.uv[7] = v.uv + _MainTex_TexelSize.xy*fixed2(0, -1);
				o.uv[8] = v.uv + _MainTex_TexelSize.xy*fixed2(1,-1);
				return o;
			}
			fixed4 frag(v2f v):SV_Target
			{
				half edge = sobel(v);  //计算梯度值edge
			fixed4 withEdgeColor = lerp(_LineColor, tex2D(_MainTex, v.uv[0]), edge);
			fixed4 onlyEdgeColor = lerp(_LineColor, _BackGroundColor,edge);
			
			return lerp(withEdgeColor, onlyEdgeColor, _EdgeOnly);
			}
	
			
			ENDCG
		}
	}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值