Unity Shader Example 9 (均值模糊)

Shader:

Shader "ImageEffect/Unlit/BlurBox" {
	Properties {
	_MainTex ("Base (RGB)", 2D) = "white" {}
}

SubShader {	
	Pass {
	  	ZTest Always  	ZWrite Off

		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;
			half2 taps[4] : TEXCOORD1; 
		};

		sampler2D _MainTex;
		half4 _MainTex_TexelSize;
		float _BlurSize;
		
		v2f vert (appdata_t v)
		{
			v2f o;
			o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
			float2 blurOffsets = float2(1, 1) * _BlurSize * _MainTex_TexelSize.xy;
			o.texcoord = v.texcoord;
			// 像素的上下左右
			o.taps[0] = o.texcoord + blurOffsets * half2(0,-1);
			o.taps[1] = o.texcoord + blurOffsets * half2(0,1);
			o.taps[2] = o.texcoord + blurOffsets * half2(-1,0);
			o.taps[3] = o.texcoord + blurOffsets * half2(1,0);
			return o;
			
			
		}
		
		fixed4 frag (v2f i) : SV_Target
		{
			half4 color = tex2D(_MainTex, i.taps[0]);
			color += tex2D(_MainTex, i.taps[1]);
			color += tex2D(_MainTex, i.taps[2]);
			color += tex2D(_MainTex, i.taps[3]); 
			return color * 0.25;
		}
	ENDCG
	}
}
Fallback off
}


注意:

内置四元数变量_MainTex_TexelSize,这个变量的从字面意思是主贴图_MainTex的像素尺寸大小,是一个四元数,它的值为 Vector4(1 / width, 1 / height, width, height);


C#

using UnityEngine;
using System.Collections;

[ExecuteInEditMode]
public class Blur : MonoBehaviour {

    public Shader shader;
    private Material material;

    public float blurSize = 0.5f;
    public int blurIterations = 2;

    void Start()
    {
        //new mat
        if (!material && shader != null)
        {
            material = new Material(shader);
        }
            
    }

    void OnDisable()
    {
        if (material)
        {
            DestroyImmediate(material);
        }
            
    }

    void OnRenderImage(RenderTexture source, RenderTexture destination)
    {
        if (material != null)
        {
            material.SetFloat("_BlurSize", blurSize);
            int rtWidth = source.width / 2;
            int rtHeight = source.height / 2;

            // clone
            RenderTexture tempSrc = RenderTexture.GetTemporary(source.width, source.height, 0, source.format);
            Graphics.Blit(source, tempSrc);
            for (int i = 0; i < blurIterations; i++)
            {
                RenderTexture tempDes = RenderTexture.GetTemporary(rtWidth, rtHeight, 0, source.format);
                Graphics.Blit(tempSrc, tempDes, material);
                RenderTexture.ReleaseTemporary(tempSrc);
                tempSrc = tempDes;
                rtWidth /= 2;
                rtHeight /= 2;
            }
            Graphics.Blit(tempSrc, destination);
            RenderTexture.ReleaseTemporary(tempSrc);
        }
        else
        {
            Graphics.Blit(source, destination);  
        }
    }
	
}



C#:


迭代 blurIterations 次,就是把Source RendererTexture 执行material之后,再存在到缩小 四分之一 的Texture,第二次迭代就是,把缩小 四分之一 的Texture作为Source ,再进行material,再存到本身四分之一 的Texture上,如此类推。


参考:

 UnityShader实例13:屏幕特效之均值模糊(Box Blur)  :  http://blog.csdn.net/u011047171/article/details/47947397


原理:

均值模糊的原理是通过图形滤波器来把一个像素和周围的像素一起求平均值,比如一个三阶的图像滤波器构造其实就是一个3*3的数组(n阶数组中的元素成为滤波器的系数和滤波器的权重,n称为滤波器的阶),相当于把一个像素和周围8个像素相加在一起再除以9求平均值,等于把一个像素和周围的像素搅拌在一起,自然就模糊了。均值滤波器与高斯模糊的滤波器不同的地方,就是采样的像素权重是相等的,因此效果相对而言要比高斯模糊差,但速度却要快一些。本例其实只采样了四个像素求和做平均,然后通过迭代多次采样,实现比较好的模糊效果。下面是一个三阶的均值滤波器:

      [1,1,1]
      [1,1,1]
      [1,1,1]


本例采用的滤波器:

        [0,1,0]
        [1,0,1]
        [0,1,0]







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值