马赛克效果的实现
最终效果:
将材质付给物体:
左侧是表面着色器,右侧是顶点和片元着色器。
将材质球用来处理屏幕特效:
上图是顶点和片元着色器来处理屏幕特效的效果。表面着色器不能用来处理屏幕特效。(不知道为什么,只显示一片黑)。
表面着色器代码:
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),存储着主贴图的信息。
根据不同的算法,马赛克效果是不同的,这里是正方形马赛克,还有圆形马赛克,蜂窝形马赛克,根据算法可以实现不同的效果。
希望可以帮到想要学习着色器的读者。如果有谁知道为什么表面着色器处理屏幕特效会是一片黑,希望能告诉我一下。谢谢