|
|
using System.Collections;
|
|
|
using System.Collections.Generic;
|
|
|
using UnityEngine;
|
|
|
using UnityEngine.UI;
|
|
|
|
|
|
public class FontBlur : MonoBehaviour {
|
|
|
private Material m_material;//新生成的GameObject RawImage的材质
|
|
|
public Shader m_shader;//需要替换的shader
|
|
|
|
|
|
private GameObject m_RawImage;//使用此对象(类型为RawImage)去代替原有对象完成模糊特效
|
|
|
private GameObject m_Canvas;
|
|
|
private GameObject m_Camera;
|
|
|
private RenderTexture m_RenderTexture;
|
|
|
private float MipMapLeavel;//RT的MipMapLeavel
|
|
|
//模糊采样范围
|
|
|
public float CurBlurSpread = 16;
|
|
|
|
|
|
public GameObject MainCanvas;
|
|
|
public Texture2D WaveMap;
|
|
|
//播放时间
|
|
|
public float Delay = 2;
|
|
|
//每秒的CurBlurSpread变化量
|
|
|
private float DeltaPS;
|
|
|
|
|
|
public Vector2 Tiling = new Vector2(0.25f, 0.25f);
|
|
|
public Vector2 Offset = new Vector2(0.2f, 0.2f);
|
|
|
|
|
|
//扰动幅度
|
|
|
public float WaveFactor = 0.0003f;
|
|
|
|
|
|
|
|
|
void Start () {
|
|
|
BeginBlur();
|
|
|
}
|
|
|
|
|
|
//开始模糊
|
|
|
public void BeginBlur () {
|
|
|
m_RenderTexture = new RenderTexture(512,512,24);
|
|
|
m_RenderTexture.useMipMap = true;//需要生成mipmap
|
|
|
m_RenderTexture.wrapMode = TextureWrapMode.Clamp;
|
|
|
|
|
|
|
|
|
//生成新的Camera
|
|
|
m_Camera = new GameObject("m_Camera", typeof(Camera));
|
|
|
m_Camera.GetComponent<Camera>().orthographic = true;
|
|
|
m_Camera.GetComponent<Camera>().orthographicSize = this.GetComponent<RectTransform>().rect.height / 2;
|
|
|
m_Camera.GetComponent<Camera>().aspect = this.GetComponent<RectTransform>().rect.width / this.GetComponent<RectTransform>().rect.height;
|
|
|
m_Camera.GetComponent<Camera>().clearFlags = CameraClearFlags.Depth;
|
|
|
m_Camera.GetComponent<Camera>().targetTexture = m_RenderTexture;
|
|
|
m_Camera.GetComponent<Transform>().position = this.GetComponent<Transform>().position;
|
|
|
|
|
|
|
|
|
//生成新的Canvas
|
|
|
m_Canvas = new GameObject("m_Canvas", typeof(Canvas));
|
|
|
m_Canvas.GetComponent<Transform>().position = MainCanvas.GetComponent<Transform>().position;//复制位置
|
|
|
m_Canvas.GetComponent<RectTransform>().sizeDelta = MainCanvas.GetComponent<RectTransform>().sizeDelta;//复制大小
|
|
|
m_Canvas.GetComponent<Canvas>().renderMode = RenderMode.WorldSpace;//ScreenSpaceCamera;最终采用了world模式,相机大小可控
|
|
|
m_Canvas.GetComponent<Canvas>().worldCamera = m_Camera.GetComponent<Camera>();
|
|
|
|
|
|
|
|
|
//生成新的RawImage
|
|
|
m_RawImage = new GameObject("m_RawImage", typeof(RawImage));
|
|
|
m_RawImage.GetComponent<Transform>().SetParent(this.transform.parent);
|
|
|
m_RawImage.GetComponent<RectTransform>().sizeDelta = this.GetComponent<RectTransform>().sizeDelta;//复制大小
|
|
|
m_RawImage.GetComponent<RectTransform>().pivot = this.GetComponent<RectTransform>().pivot;//复制pivot坐标
|
|
|
m_RawImage.GetComponent<RectTransform>().anchoredPosition3D = this.GetComponent<RectTransform>().anchoredPosition3D;//复制局部坐标
|
|
|
|
|
|
|
|
|
Transform OrignTransformParent = this.transform.parent;//先记录一下原本的父对象
|
|
|
this.GetComponent<Transform>().SetParent(m_Canvas.GetComponent<Transform>(), true);//将此GameObject转移至新的Canvas下,拍完照再转移回来
|
|
|
Vector3 tmp_pos = this.transform.position;
|
|
|
tmp_pos.z -= 1;//为了使相机照到
|
|
|
m_Camera.GetComponent<Transform>().position = tmp_pos;
|
|
|
|
|
|
m_Camera.GetComponent<Camera>().Render();
|
|
|
m_RawImage.GetComponent<RawImage>().texture = m_RenderTexture;//新的RawImage的材质需要生成
|
|
|
m_Camera.GetComponent<Camera>().targetTexture = null;
|
|
|
|
|
|
|
|
|
//获取RenderTexture结束 销毁新canvas与新相机
|
|
|
this.GetComponent<Transform>().SetParent(OrignTransformParent, true);//转移回原来的父对象
|
|
|
this.GetComponent<Text>().enabled = false;
|
|
|
Destroy(m_Canvas, 0);
|
|
|
Destroy(m_Camera, 0);
|
|
|
|
|
|
//调整m_RawImage
|
|
|
m_RawImage.GetComponent<RawImage>().material = new Material(m_shader);
|
|
|
m_material = m_RawImage.GetComponent<RawImage>().material;
|
|
|
m_material.SetTexture("_WaveMap",WaveMap);
|
|
|
float x = 1f / m_RawImage.GetComponent<RectTransform>().sizeDelta.x;
|
|
|
float y = 1f / m_RawImage.GetComponent<RectTransform>().sizeDelta.y;
|
|
|
m_material.SetFloat("_StepLength", Mathf.Sqrt(x * x + y * y));
|
|
|
|
|
|
DeltaPS = CurBlurSpread / Delay;
|
|
|
}
|
|
|
|
|
|
//模糊结束
|
|
|
void EndBlur(){
|
|
|
Text txt = this.GetComponent<Text>();
|
|
|
if (txt != null)
|
|
|
txt.enabled = true;
|
|
|
|
|
|
Destroy(m_RawImage, 0);
|
|
|
}
|
|
|
|
|
|
void CalculateBlur () {
|
|
|
//倒放
|
|
|
if (CurBlurSpread > 0){
|
|
|
CurBlurSpread -= DeltaPS * Time.deltaTime;
|
|
|
Offset.x -= WaveFactor;
|
|
|
}
|
|
|
if (CurBlurSpread < 0)
|
|
|
CurBlurSpread = 0;
|
|
|
|
|
|
if (CurBlurSpread > 6) MipMapLeavel = 4;
|
|
|
else if (CurBlurSpread > 2) MipMapLeavel = 3;
|
|
|
else if (CurBlurSpread > 1) MipMapLeavel = 2;
|
|
|
else if (CurBlurSpread > 0) MipMapLeavel = 1;
|
|
|
else if (CurBlurSpread == 0) MipMapLeavel = 0;
|
|
|
|
|
|
m_material.SetFloat("_MipMapLeavel", MipMapLeavel);
|
|
|
m_material.SetFloat("_BlurSpread", CurBlurSpread);
|
|
|
m_material.SetTextureScale("_WaveMap", Tiling);
|
|
|
m_material.SetTextureOffset("_WaveMap", Offset);
|
|
|
}
|
|
|
|
|
|
|
|
|
void Update(){
|
|
|
if (m_RawImage != null)
|
|
|
CalculateBlur();
|
|
|
}
|
|
|
}
|