[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
        }
    }
}

你可能感兴趣的:([unityshader]产生像素后处理效果)