原文地址 [unityshader]产生像素后处理效果
如图,注意(这个shader并不是放在人物身上而是放在一个面片上,透过这个面片去观察角色)
后处理其实就是,使用Grabpass通道获取到当前屏幕图片,再把这张图片存入sampler2D贴图属性中。
然后在shader中进行处理。
像素化的的思路就是降低uv精度。把0.1 0.2 0.3 0.4的数据变成0.1 0.1 0.3 0.3这样的数据
我们可以采用取整的思想来对精度进行降低,把原Uv的值乘上一个数字,再对这个数字进行取整操作就能降低精度,然后再把这个数字变回0-1之间。
这个shader中还设计了菲涅尔值的控制,若不想要菲涅尔效果可自行控制。
Shader "Unlit/Glass"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_Refract("Refract",Range(0,1))=1.0
_CubeMap("cube",Cube)="Skybox"{}
_fresnelPower("fresnelPower",Range(0,9))=0
_fresnelScale("fresnelScale",Range(0,1))=0
_PixelCount("Pixel",Range(30,1000))=30
}
SubShader
{
Tags { "RenderType"="Opaque" "Queue"="Transparent" }
GrabPass{
"_RefractionTex"
}
LOD 100
Pass
{
Name "PIXEL"
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// make fog work
#pragma multi_compile_fog
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
float3 normal:NORMAL;
};
struct v2f
{
float2 uv : TEXCOORD0;
fixed3 worldPos:TEXCOORD3;
fixed3 normal:NORMAL;
fixed3 worldNormal:TEXCOORD2;
float3 worldViewDir:TEXCOORD4;
float4 scrpos:TEXCOORD1;
UNITY_FOG_COORDS(1)
float4 vertex : SV_POSITION;
};
float _PixelCount;
sampler2D _MainTex;
float4 _MainTex_ST;
sampler2D _RefractionTex;
float4 _RefractionTex_TexelSize;
samplerCUBE _CubeMap;
float _fresnelPower;
float _fresnelScale;
v2f vert (appdata v)
{
v2f o;
o.worldPos=mul(unity_ObjectToWorld,v.vertex).xyz;
o.normal=v.normal;
o.worldNormal=UnityObjectToWorldNormal(v.normal);
o.worldViewDir=UnityWorldSpaceViewDir(o.worldPos);
o.vertex = UnityObjectToClipPos(v.vertex);
o.scrpos=ComputeGrabScreenPos(o.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
// sample the texture
float3 viewDir=normalize(i.worldViewDir);
float3 normalDir=normalize(i.worldNormal);
float fresnel=_fresnelScale+(1-_fresnelScale)*pow(1-dot(viewDir,normalDir),_fresnelPower);
float2 f2=i.scrpos.xy/i.scrpos.w;
float nx=floor(f2.x*_PixelCount)/_PixelCount;
float ny=floor(f2.y*_PixelCount)/_PixelCount;
fixed4 col = tex2D(_RefractionTex, fixed2(nx,ny));
fixed3 cubecolor=texCUBE(_CubeMap,i.normal);
// apply fog
UNITY_APPLY_FOG(i.fogCoord, col);
return fixed4(fresnel*cubecolor,1)+col;
}
ENDCG
}
}
}