Bloom特效可以将周围将亮的区域扩散到周围的区域中,造成一种朦胧的效果。
using UnityEngine; public class bloom : MonoBehaviour { public Material mat; [Range(0, 4)] public int iterations = 3; //高斯模糊处理次数 [Range(0.2f,3.0f)] public float blurSpread = 0.6f; //模糊程度 [Range(1, 8)] public int downSample = 2; [Range(0.0f, 4.0f)] //亮度阔值,一般不会超过1,但开启HDR的话会有更高的精度 public float luminanceThreshold = 0.6f; private void OnRenderImage(RenderTexture source, RenderTexture destination) { if (mat != null) { mat.SetFloat("_LuminanceThreshold", luminanceThreshold); int w = source.width / downSample; int h = source.height / downSample; RenderTexture buffer0 = RenderTexture.GetTemporary(w, h, 0); buffer0.filterMode = FilterMode.Bilinear; Graphics.Blit(source, buffer0, mat, 0); //将光亮图高斯模糊,扩散到周围 for (int i = 0; i < iterations; i++) { mat.SetFloat("_BlurSize", 1.0f + i * blurSpread); RenderTexture buffer1 = RenderTexture.GetTemporary(w, h, 0); Graphics.Blit(buffer0, buffer1, mat, 1); RenderTexture.ReleaseTemporary(buffer0); buffer0 = buffer1; buffer1 = RenderTexture.GetTemporary(w, h, 0); Graphics.Blit(buffer0, buffer1, mat, 2); RenderTexture.ReleaseTemporary(buffer0); buffer0 = buffer1; } mat.SetTexture("_Bloom", buffer0); Graphics.Blit(source, destination, mat, 3); RenderTexture.ReleaseTemporary(buffer0); } else { Graphics.Blit(source, destination); } } }
Shader "Unlit/bloom" { Properties { _MainTex ("Texture", 2D) = "white" {} _Bloom("Bloom",2D) = "black"{} _LuminanceThreshold("Luminance Threshold",Float) = 0.5 _BlurSize("Blur Size",Float) = 1.0 } SubShader { Tags { "RenderType"="Opaque" } LOD 100 CGINCLUDE #include "UnityCG.cginc" struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; }; sampler2D _MainTex; float4 _MainTex_TexelSize; sampler2D _Bloom; float _LuminanceThreshold; float _BlurSize; v2f vertExtractBright(appdata_img v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = v.texcoord; return o; } //光度贴图的取样,亮度超过阔值的才有值 fixed4 fragExtractBright(v2f i) : SV_Target { fixed4 c = tex2D(_MainTex,i.uv); fixed val = clamp(Luminance(c) - _LuminanceThreshold, 0.0, 1.0); return c * val; } struct v2fBloom { float4 pos : SV_POSITION; half4 uv :TEXCOORD0; }; v2fBloom vertBloom(appdata_img v) { v2fBloom o; o.pos = UnityObjectToClipPos(v.vertex); o.uv.xy = v.texcoord; o.uv.zw = v.texcoord; //平台差异化处理 #if UNITY_UV_STARTS_AT_TOP if (_MainTex_TexelSize.y < 0.0) o.uv.w = 1.0 - o.uv.w; #endif return o; } fixed4 fragBloom(v2fBloom i) :SV_Target { //为较亮区域添加亮度 return tex2D(_MainTex,i.uv.xy) + tex2D(_Bloom,i.uv.zw); } ENDCG ZTest Always Cull Off ZWrite Off //得到较亮区域贴图 Pass { CGPROGRAM #pragma vertex vertExtractBright #pragma fragment fragExtractBright ENDCG } //高斯模糊处理,扩散到周围 UsePass "Unlit/gsMohu/GAUSSING_BLUR_VERTICAL" //上次通过Name UsePass "Unlit/gsMohu/GAUSSING_BLUR_GORIZONTAL" //叠加,较亮区域 Pass { CGPROGRAM #pragma vertex vertBloom #pragma fragment fragBloom ENDCG } } Fallback Off }
UsePass使用的是 “高斯模糊”中使用NAME命名好的Pass,达到重用的目的