使用 高斯模式 对亮度高于对应阈值的像素进行模糊处理,并于原图形进行混合,来达到柔光的效果
using System;
using UnityEngine;
using UnityEngine.Serialization;
public class Bloom : PostEffectBase
{
public Shader bloomShader;
[Range(0.2f, 3.0f)]
public float blurSpread = 0.6f;
[Range(1, 8)]
public int downSample = 2;
[Range(0, 4)]
public int iteration = 3;
[Range(0f, 4f)]
public float luminanceThreshold = 0.6f;
private Material _bloomMaterial;
public Material material
{
get
{
_bloomMaterial = CheckShaderAndCreateMaterial(bloomShader, _bloomMaterial);
return _bloomMaterial;
}
}
private void OnRenderImage(RenderTexture src, RenderTexture dest)
{
if (material != null)
{
material.SetFloat("_LuminanceThreshold", luminanceThreshold);
int rtw = src.width / downSample;
int rth = src.height / downSample;
RenderTexture buffer0 = RenderTexture.GetTemporary(rtw, rth, 0);
buffer0.filterMode = FilterMode.Bilinear;
Graphics.Blit(src, buffer0, material, 0);
for (int i = 0; i < iteration; i++)
{
material.SetFloat("_BlurSize", 1f + i * blurSpread);
RenderTexture buffer1 = RenderTexture.GetTemporary(rtw, rth, 0);
Graphics.Blit(buffer0, buffer1, material, 1);
RenderTexture.ReleaseTemporary(buffer0);
buffer0 = buffer1;
buffer1 = RenderTexture.GetTemporary(rtw, rth, 0);
Graphics.Blit(buffer0, buffer1, material, 2);
RenderTexture.ReleaseTemporary(buffer0);
buffer0 = buffer1;
}
material.SetTexture("_Bloom", buffer0);
Graphics.Blit(src, dest, material, 3);
RenderTexture.ReleaseTemporary(buffer0);
}
else Graphics.Blit(src, dest);
}
}
Shader "Hidden/Bloom"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_Bloom ("Bloom", 2D) = "black" {}
_BlurSize ("Blur Size", Float) = 1.0
_LuminanceThreshold ("Luminance Threshold", Float) = 0.6
}
SubShader
{
CGINCLUDE
#include
struct a2v
{
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
};
struct v2f
{
float4 pos : SV_POSITION;
float4 uv : TEXCOORD0;
};
sampler2D _MainTex;
half4 _MainTex_TexelSize;
sampler2D _Bloom;
float _LuminanceThreshold;
float _BlurSize;
v2f vertExtractBright(a2v v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv.xy = v.texcoord.xy;
return o;
}
fixed4 fragExtractBright(v2f i) : SV_Target
{
fixed4 color = tex2D(_MainTex, i.uv.xy);
fixed val = clamp(dot(color, unity_ColorSpaceLuminance) - _LuminanceThreshold, 0, 1);
return color * val;
}
v2f vertBloom(a2v v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv.xy = v.texcoord.xy;
o.uv.zw = v.texcoord.xy;
#if UNITY_UV_STARTS_AT_TOP
if (_MainTex_TexelSize.y < 0)
o.uv.w = 1.0 - o.uv.w;
#endif
return o;
}
fixed4 fragBloom(v2f i) : SV_Target
{
return tex2D(_MainTex, i.uv.xy) + tex2D(_Bloom, i.uv.zw);
}
ENDCG
Cull Off ZWrite Off ZTest Always
Pass
{
CGPROGRAM
#pragma vertex vertExtractBright
#pragma fragment fragExtractBright
ENDCG
}
UsePass "Hidden/GaussianBlur/GAUSSIANBLUR_HORIZONTAL"
UsePass "Hidden/GaussianBlur/GAUSSIANBLUR_VERTICAL"
Pass
{
CGPROGRAM
#pragma vertex vertBloom
#pragma fragment fragBloom
ENDCG
}
}
}