标签: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