using UnityEngine; namespace UnityStandardAssets.ImageEffects { [ExecuteInEditMode] [RequireComponent (typeof(Camera))] [AddComponentMenu ("Image Effects/Bloom and Glow/Bloom (Optimized)")] public class BloomOptimized : PostEffectsBase { public enum Resolution { Low = 0, High = 1, } public enum BlurType { Standard = 0, Sgx = 1, } [Range(0.0f, 1.5f)] public float threshold = 0.25f; [Range(0.0f, 2.5f)] public float intensity = 0.75f; [Range(0.25f, 5.5f)] public float blurSize = 1.0f; Resolution resolution = Resolution.Low; [Range(1, 4)] public int blurIterations = 1; public BlurType blurType= BlurType.Standard; public Shader bloomMaskShader; public Shader fastBloomShader = null; private Material fastBloomMaterial = null; //是否Mask来处理Bloom public bool _useMask; private Camera _maskCamera; private RenderTexture _maskCameraRenderTex; private Camera _selfCamera; public override bool CheckResources () { CheckSupport (false); fastBloomMaterial = CheckShaderAndCreateMaterial (fastBloomShader, fastBloomMaterial); if (!isSupported) ReportAutoDisable (); return isSupported; } private void MaskCameraRender(ref Camera camera,ref RenderTexture rt, int rtW, int rtH,RenderTextureFormat format) { if (bloomMaskShader == null) { bloomMaskShader = Shader.Find("Ares/Bloom/BloomMaskPass"); if (bloomMaskShader == null) { Debug.LogError("找到着色器:Ares/Bloom/BloomMaskPass"); return; } } if (_selfCamera == null) { _selfCamera = GetComponent(); } if (rt == null) { rt = RenderTexture.GetTemporary(rtW, rtH, 16, format); rt.antiAliasing = 1; rt.name = "__WaterRefraction" + GetInstanceID(); rt.isPowerOfTwo = true; rt.hideFlags = HideFlags.DontSave; } if (camera == null) { var trans = transform.Find("[BloomMaskCamera]"); GameObject go; if (trans == null) { go = new GameObject("[BloomMaskCamera]"); trans = go.transform; } else { go = trans.gameObject; } trans.parent = transform; trans.localPosition = Vector3.zero; trans.localRotation = Quaternion.identity; //获取Camera组件 camera = go.GetComponent(); if (camera == null) { camera = go.AddComponent(); } camera.enabled = false; camera.clearFlags = CameraClearFlags.SolidColor; camera.backgroundColor = Color.black; camera.farClipPlane = _selfCamera.farClipPlane; camera.nearClipPlane = _selfCamera.nearClipPlane; camera.orthographic = _selfCamera.orthographic; camera.fieldOfView = _selfCamera.fieldOfView; camera.aspect = _selfCamera.aspect; camera.orthographicSize = _selfCamera.orthographicSize; camera.SetReplacementShader(bloomMaskShader, "RenderType"); camera.targetTexture = rt; } if(camera != null) camera.Render(); } void OnDisable () { if (fastBloomMaterial) DestroyImmediate (fastBloomMaterial); if (_maskCamera != null) { DestroyImmediate(_maskCamera.gameObject); _maskCamera = null; } if (_maskCameraRenderTex != null) { RenderTexture.ReleaseTemporary(_maskCameraRenderTex); _maskCameraRenderTex = null; } } void OnRenderImage(RenderTexture source, RenderTexture destination) { if (CheckResources() == false) { Graphics.Blit(source, destination); return; } int divider = resolution == Resolution.Low ? 4 : 2; float widthMod = resolution == Resolution.Low ? 0.5f : 1.0f; var rtW = source.width / divider; var rtH = source.height / divider; // mask RenderTexture sourceWithMask = null; if (_useMask) { MaskCameraRender(ref _maskCamera, ref _maskCameraRenderTex, rtW, rtH, source.format); sourceWithMask = RenderTexture.GetTemporary(rtW, rtH, 0, source.format); sourceWithMask.name = "RenderTexture100"; sourceWithMask.antiAliasing = 1; sourceWithMask.filterMode = FilterMode.Bilinear; fastBloomMaterial.SetTexture("_BloomMaskTex", _maskCameraRenderTex); Graphics.Blit(source, sourceWithMask, fastBloomMaterial, 6); } else { sourceWithMask = source; } // downsample RenderTexture rt = RenderTexture.GetTemporary(rtW, rtH, 0, source.format); rt.name = "RenderTexture15"; rt.antiAliasing = 1; rt.filterMode = FilterMode.Bilinear; fastBloomMaterial.SetVector("_Parameter", new Vector4(blurSize * widthMod, 0.0f, threshold, intensity)); source.filterMode = FilterMode.Bilinear; Graphics.Blit(sourceWithMask, rt, fastBloomMaterial, 1); if (_useMask) { RenderTexture.ReleaseTemporary(sourceWithMask); } var passOffs= blurType == BlurType.Standard ? 0 : 2; for(int i = 0; i < blurIterations; i++) { fastBloomMaterial.SetVector ("_Parameter", new Vector4 (blurSize * widthMod + (i*1.0f), 0.0f, threshold, intensity)); // vertical blur RenderTexture rt2 = RenderTexture.GetTemporary (rtW, rtH, 0, source.format); rt2.name = "RenderTexture16"; rt2.antiAliasing = 1; rt2.filterMode = FilterMode.Bilinear; Graphics.Blit (rt, rt2, fastBloomMaterial, 2 + passOffs); RenderTexture.ReleaseTemporary (rt); rt = rt2; // horizontal blur rt2 = RenderTexture.GetTemporary (rtW, rtH, 0, source.format); rt2.name = "RenderTexture17"; rt2.antiAliasing = 1; rt2.filterMode = FilterMode.Bilinear; Graphics.Blit (rt, rt2, fastBloomMaterial, 3 + passOffs); RenderTexture.ReleaseTemporary (rt); rt = rt2; } fastBloomMaterial.SetTexture ("_Bloom", rt); Graphics.Blit (source, destination, fastBloomMaterial, 0); //Graphics.Blit(_maskCameraRenderTex, destination); RenderTexture.ReleaseTemporary (rt); } } }