using FairyGUI; using NBF; using UnityEngine; using UnityEngine.UI; public class UIBlur : MonoBehaviour { [Header("Quality")] public RenderTexture blurRT; [Range(1, 6)] public int iterations = 2; // 模糊迭代次数 [Range(0.5f, 4f)] public float blurSize = 1.2f; [Header("Shader")] public Shader blurShader; Material _mat; RenderTexture _capturedRT; public static UIBlur Instance { get; private set; } void Awake() { blurRT = new RenderTexture((int)(Screen.width * 0.5f), (int)(Screen.height * 0.5f), 0, RenderTextureFormat.ARGB32); _mat = new Material(blurShader); DontDestroyOnLoad(gameObject); Instance = this; } public void CaptureAndBlurOnce() { if (blurRT == null) return; var captureCamera = Camera.main; if (captureCamera == null) return; int w = blurRT.width; int h = blurRT.width; ReleaseRTs(); var oldEnabled = StageCamera.main.enabled; StageCamera.main.enabled = false; _capturedRT = new RenderTexture(w, h, 0, RenderTextureFormat.ARGB32); _capturedRT.Create(); // 1) 抓摄像机画面到RT(不做ReadPixels) var prevTarget = captureCamera.targetTexture; captureCamera.targetTexture = _capturedRT; captureCamera.Render(); captureCamera.targetTexture = prevTarget; StageCamera.main.enabled = oldEnabled; // 2) 模糊:ping-pong var rt1 = RenderTexture.GetTemporary(w, h, 0, RenderTextureFormat.ARGB32); var rt2 = RenderTexture.GetTemporary(w, h, 0, RenderTextureFormat.ARGB32); Graphics.Blit(_capturedRT, rt1); _mat.SetFloat("_BlurSize", blurSize); for (int i = 0; i < iterations; i++) { // 横向 _mat.SetVector("_Direction", new Vector2(1, 0)); Graphics.Blit(rt1, rt2, _mat); // 纵向 _mat.SetVector("_Direction", new Vector2(0, 1)); Graphics.Blit(rt2, rt1, _mat); } Graphics.Blit(rt1, blurRT); RenderTexture.ReleaseTemporary(rt1); RenderTexture.ReleaseTemporary(rt2); } void ReleaseRTs() { if (_capturedRT != null) { _capturedRT.Release(); Destroy(_capturedRT); _capturedRT = null; } } void OnDestroy() { ReleaseRTs(); if (_mat) Destroy(_mat); } }