图形学应用_着色器实例—马赛克效果

马赛克效果的实现

最终效果:

将材质付给物体:

左侧是表面着色器,右侧是顶点和片元着色器。

将材质球用来处理屏幕特效: 

上图是顶点和片元着色器来处理屏幕特效的效果。表面着色器不能用来处理屏幕特效。(不知道为什么,只显示一片黑)。

表面着色器代码:

Shader "Custom/Mosaic_SurfaceShader" {
	Properties{
		_MainTex("Albedo (RGB)", 2D) = "white" {}
	    _Size("Scale",int) = 1
	}
		SubShader{
			Tags { "RenderType" = "Opaque" "Queue"="Transparent"}
			CGPROGRAM
			#pragma surface surf Lambert alpha
			sampler2D _MainTex;
		    half4 _MainTex_TexelSize;
			half _Size;
			struct Input
			{
				float2 uv_MainTex;
			};
			void surf(Input IN,inout SurfaceOutput o)
			{
				fixed2 u = floor(IN.uv_MainTex*_MainTex_TexelSize.zw / _Size)*_Size;
				u = u * _MainTex_TexelSize.xy;
				o.Albedo = tex2D(_MainTex, u);
				o.Alpha = 1;
			}
			ENDCG
	} 
			FallBack "Diffuse"
}

 

顶点和片元着色器代码:

Shader "Custom/Mosaic_VFShader" {
	Properties{
		_MainTex("Albedo (RGB)", 2D) = "white" {}
	    _Size("Scale",int) = 1
	}
		SubShader{
			Tags { "RenderType" = "Opaque" "Queue" = "Transparent"}
			Pass
		   {
			Blend SrcAlpha OneMinusSrcAlpha
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag

#include "UnityCG.cginc"

			sampler2D _MainTex;
			half _Size;
			half4 _MainTex_TexelSize;
			struct appdata
			{
				float2 uv:TEXCOORD0;
				float4 vertex:POSITION;
			};
			struct v2f
			{
				float2 uv:TEXCOORD0;
				float4 vertex:POSITION;
			};
			v2f vert(appdata IN)
			{
				v2f o;
				o.vertex = UnityObjectToClipPos(IN.vertex);
				o.uv = IN.uv;
				return o;
			}
			fixed4 frag(v2f i) :SV_Target
			{
				fixed4 o;
			    fixed2 u = floor(i.uv*_MainTex_TexelSize.zw/_Size)*_Size;
				u = u * _MainTex_TexelSize.xy;
				o.rgb = tex2D(_MainTex,u);
				return o;
			}
			ENDCG
	} }
}

 注意:

_MainTex_TexelSize是 unity 内置的变量,它的值为 Vector4(1 / width, 1 / height, width, height),存储着主贴图的信息。

根据不同的算法,马赛克效果是不同的,这里是正方形马赛克,还有圆形马赛克,蜂窝形马赛克,根据算法可以实现不同的效果。

希望可以帮到想要学习着色器的读者。如果有谁知道为什么表面着色器处理屏幕特效会是一片黑,希望能告诉我一下。谢谢

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章