Unity3D Shader 高斯模糊
//Shader
Shader "Hidden/GaussianBlur" { Properties { _MainTex ("Texture", 2D) = "white" {} _BlurSize ("Blur Size", Float) = 0.1 } CGINCLUDE #include "UnityCG.cginc" sampler2D _MainTex; uniform half4 _MainTex_TexelSize; uniform float _BlurSize; static const half weight[4] = {0.0205, 0.0855, 0.232, 0.324}; static const half4 coordOffset = half4(1.0h,1.0h,-1.0h,-1.0h); struct v2f_blurSGX { float4 pos:SV_POSITION; half2 uv:TEXCOORD0; half4 uvoff[3]:TEXCOORD1; }; v2f_blurSGX vert_BlurHorizontal(appdata_img v) { v2f_blurSGX o; o.pos = mul(UNITY_MATRIX_MVP,v.vertex); o.uv = v.texcoord.xy; half2 offs = _MainTex_TexelSize.xy*half2(1,0)*_BlurSize; o.uvoff[0] = v.texcoord.xyxy+offs.xyxy*coordOffset*3; o.uvoff[1] = v.texcoord.xyxy+offs.xyxy*coordOffset*2; o.uvoff[2] = v.texcoord.xyxy+offs.xyxy*coordOffset; return o; } v2f_blurSGX vert_BlurVertical(appdata_img v) { v2f_blurSGX o; o.pos = mul(UNITY_MATRIX_MVP,v.vertex); o.uv = v.texcoord.xy; half2 offs = _MainTex_TexelSize.xy*half2(0,1)*_BlurSize; o.uvoff[0] = v.texcoord.xyxy+offs.xyxy*coordOffset*3; o.uvoff[1] = v.texcoord.xyxy+offs.xyxy*coordOffset*2; o.uvoff[2] = v.texcoord.xyxy+offs.xyxy*coordOffset; return o; } fixed4 frag_Blur(v2f_blurSGX i):SV_Target { fixed4 c = tex2D(_MainTex,i.uv)*weight[3]; for(int idx=0; idx<3; idx++) { c+=tex2D(_MainTex,i.uvoff[idx].xy)*weight[idx]; c+=tex2D(_MainTex,i.uvoff[idx].zw)*weight[idx]; } return c; } ENDCG SubShader { // No culling or depth Cull Off ZWrite Off Pass { ZTest Always CGPROGRAM #pragma vertex vert_BlurHorizontal #pragma fragment frag_Blur ENDCG } Pass { ZTest Always CGPROGRAM #pragma vertex vert_BlurVertical #pragma fragment frag_Blur ENDCG } } }
//c#
using UnityEngine; using System.Collections; [RequireComponent(typeof(Camera))] [ExecuteInEditMode] public class Blur : MonoBehaviour { public Material ma; public float BlurSize =10; public int interator = 2; void OnRenderImage (RenderTexture sourceTexture, RenderTexture destTexture) { ma.SetFloat ("_BlurSize", BlurSize); int rtW = sourceTexture.width/8; int rtH = sourceTexture.height/8; RenderTexture rtTempA = RenderTexture.GetTemporary (rtW, rtH, 0, sourceTexture.format); rtTempA.filterMode = FilterMode.Bilinear; RenderTexture rtTempB = RenderTexture.GetTemporary (rtW, rtH, 0, sourceTexture.format); rtTempB.filterMode = FilterMode.Bilinear; for (int i = 0; i < interator; i++) { if (0 == i) { Graphics.Blit (sourceTexture, rtTempA,ma,0); Graphics.Blit (rtTempA, rtTempB, ma, 1); } else { Graphics.Blit (rtTempB, rtTempA, ma, 0); Graphics.Blit (rtTempA, rtTempB,ma,1); } } Graphics.Blit(rtTempB, destTexture); RenderTexture.ReleaseTemporary(rtTempA); RenderTexture.ReleaseTemporary(rtTempB); } }