标签:unity 屏幕特效 马赛克 _maintex_texelsize 蜂巢
Properties { _MainTex ("Base (RGB)", 2D) = "white" {} _MosaicSize("MosaicSize", int)=5 }
half4 _MainTex_TexelSize;
float2 uv = (i.texcoord*_MainTex_TexelSize.zw) ;//将纹理坐标映射到分辨率的大小 uv = floor(uv/_MosaicSize)*_MosaicSize;//根据马赛克块大小进行取整 i.texcoord =uv*_MainTex_TexelSize.xy;//把坐标重新映射回0,1的范围之内 fixed4 col = tex2D(_MainTex, i.texcoord);
Shader "PengLu/Unlit/MosaicVF" { Properties { _MainTex ("Base (RGB)", 2D) = "white" {} _MosaicSize("MosaicSize", int)=5 } SubShader { Tags { "RenderType"="Opaque" } LOD 100 Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata_t { float4 vertex : POSITION; float2 texcoord : TEXCOORD0; }; struct v2f { float4 vertex : SV_POSITION; half2 texcoord : TEXCOORD0; }; sampler2D _MainTex; float4 _MainTex_ST; half4 _MainTex_TexelSize; int _MosaicSize; v2f vert (appdata_t v) { v2f o; o.vertex = mul(UNITY_MATRIX_MVP, v.vertex); o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex); return o; } fixed4 frag (v2f i) : SV_Target { float2 uv = (i.texcoord*_MainTex_TexelSize.zw) ; uv = floor(uv/_MosaicSize)*_MosaicSize; i.texcoord =uv*_MainTex_TexelSize.xy; fixed4 col = tex2D(_MainTex, i.texcoord); UNITY_OPAQUE_ALPHA(col.a); return col; } ENDCG } } }
OnRenderImage (RenderTexture sourceTexture, RenderTexture destTexture)
Graphics.Blit(sourceTexture, destTexture,material)
Graphics.Blit(sourceTexture, destTexture);
using UnityEngine; using System.Collections; using System; [ExecuteInEditMode] [AddComponentMenu ("PengLu/ImageEffect/Mosaic")] public class ImageEffect_Mosaic : MonoBehaviour { #region Variables public Shader MosaicShader = null; private Material MosaicMaterial = null; public int MosaicSize = 8; #endregion //创建材质和shader Material material { get { if(MosaicMaterial == null) { MosaicMaterial = new Material(MosaicShader); MosaicMaterial.hideFlags = HideFlags.HideAndDontSave; } return MosaicMaterial; } } // Use this for initialization void Start () { MosaicShader = Shader.Find("PengLu/Unlit/MosaicVF"); // Disable if we don't support image effects if (!SystemInfo.supportsImageEffects) { enabled = false; return; } // Disable the image effect if the shader can't // run on the users graphics card if (!MosaicShader || !MosaicShader.isSupported) enabled = false; return; } void OnRenderImage (RenderTexture sourceTexture, RenderTexture destTexture) { if(MosaicSize > 0 && MosaicShader != null){ material.SetInt("_MosaicSize", MosaicSize);//将马赛克尺寸传递给shader Graphics.Blit(sourceTexture, destTexture,material);//将抓取的图像传递给gpu并用shader处理后,传回来 } else{ Graphics.Blit(sourceTexture, destTexture); } } // Update is called once per frame void Update () { #if UNITY_EDITOR if (Application.isPlaying!=true) { MosaicShader = Shader.Find("PengLu/Unlit/MosaicVF"); } #endif } public void OnDisable () { if (MosaicMaterial) DestroyImmediate (MosaicMaterial); } }
float2 intUV = (i.texcoord*_MainTex_TexelSize.zw) ; float2 xyUV = floor(intUV/_MosaicSize)*_MosaicSize+0.5*_MosaicSize; float disSample = length(xyUV-intUV); float2 mosaicUV = xyUV*_MainTex_TexelSize.xy; fixed4 col = tex2D(_MainTex, i.texcoord); if(disSample<0.5*_MosaicSize) col = tex2D(_MainTex,mosaicUV);
const float TR = 0.866025f;//TR=√3 float2 xyUV = (i.texcoord*_MainTex_TexelSize.zw); int wx = int (xyUV.x/1.5f/_MosaicSize); int wy = int (xyUV.y/TR/_MosaicSize); float2 v1,v2; float2 wxy =float2(wx,wy); if(wx/2*2==wx){ if(wy/2*2==wy){ v1 = wxy; v2 = wxy+1; } else{ v1 = wxy+float2(0,1); v2 = wxy+float2(1,0); } } else{ if(wy/2*2 == wy){ v1 = wxy+float2(0,1); v2 = wxy+float2(1,0); } else{ v1 = wxy; v2 = wxy+1; } } v1 *= float2(_MosaicSize*1.5f,_MosaicSize*TR); v2 *= float2(_MosaicSize*1.5f,_MosaicSize*TR); float s1 = length(v1.xy-xyUV.xy); float s2 = length(v2.xy-xyUV.xy); fixed4 col = tex2D(_MainTex,v2*_MainTex_TexelSize.xy); if(s1 < s2) col = tex2D(_MainTex,v1*_MainTex_TexelSize.xy);
版权声明:本文为博主原创文章,未经博主允许不得转载。
UnityShader实例11:屏幕特效之马赛克(Mosaic)材质
标签:unity 屏幕特效 马赛克 _maintex_texelsize 蜂巢
原文地址:http://blog.csdn.net/u011047171/article/details/47782801