废话不多上代码
C# (肯定是绑定在摄像机上面的,你懂的)
public class MobileBloom : MonoBehaviour
{
//分辨率
public int downSample = 1;
//采样率
public int samplerScale = 1;
//高亮部分提取阈值
public Color colorThreshold = Color.gray;
//Bloom泛光颜色
public Color bloomColor = Color.white;
//Bloom权值
[Range(0.0f, 1.0f)]
public float bloomFactor = 0.5f;
public Material material = null;
void Awake()
{
#if UNITY_EDITOR
material = new Material(Shader.Find("Custom/MobileBloom"));
#else
//获取ab包里面的shader
#endif
}
public void SetAttribute(int _downSample, int _samplerScale, Color _colorThreshold, Color _bloomColor,float _bloomFactor)
{
downSample = _downSample;
samplerScale = _samplerScale;
colorThreshold = _colorThreshold;
bloomColor = _bloomColor;
bloomFactor = _bloomFactor;
}
void OnRenderImage(RenderTexture source, RenderTexture destination)
{
if (material)
{
//申请两块RT,并且分辨率按照downSameple降低
RenderTexture temp1 = RenderTexture.GetTemporary(source.width >> downSample, source.height >> downSample, 0, source.format);
RenderTexture temp2 = RenderTexture.GetTemporary(source.width >> downSample, source.height >> downSample, 0, source.format);
//直接将场景图拷贝到低分辨率的RT上达到降分辨率的效果
Graphics.Blit(source, temp1);
//根据阈值提取高亮部分,使用pass0进行高亮提取
material.SetVector("_colorThreshold", colorThreshold);
Graphics.Blit(temp1, temp2, material, 0);
//高斯模糊,两次模糊,横向纵向,使用pass1进行高斯模糊
material.SetVector("_offsets", new Vector4(0, samplerScale, 0, 0));
Graphics.Blit(temp2, temp1, material, 1);
material.SetVector("_offsets", new Vector4(samplerScale, 0, 0, 0));
Graphics.Blit(temp1, temp2, material, 1);
//Bloom,将模糊后的图作为Material的Blur图参数
material.SetTexture("_BlurTex", temp2);
material.SetVector("_bloomColor", bloomColor);
material.SetFloat("_bloomFactor", bloomFactor);
//使用pass2进行景深效果计算,清晰场景图直接从source输入到shader的_MainTex中
Graphics.Blit(source, destination, material, 2);
//释放申请的RT
RenderTexture.ReleaseTemporary(temp1);
RenderTexture.ReleaseTemporary(temp2);
}
}
Shader
Shader "Custom/MobileBloom" {
Properties{
_MainTex("Base (RGB)", 2D) = "white" {}
_BlurTex("Blur", 2D) = "white"{}
}
CGINCLUDE
#include "UnityCG.cginc"
struct v2f_threshold
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
struct v2f_blur
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
float4 uv01 : TEXCOORD1;
float4 uv23 : TEXCOORD2;
float4 uv45 : TEXCOORD3;
};
struct v2f_bloom
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
float2 uv1 : TEXCOORD1;
};
sampler2D _MainTex;
float4 _MainTex_TexelSize;
sampler2D _BlurTex;
float4 _BlurTex_TexelSize;
float4 _offsets;
float4 _colorThreshold;
float4 _bloomColor;
float _bloomFactor;
v2f_threshold vert_threshold(appdata_img v)
{
v2f_threshold o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = v.texcoord.xy;
#if UNITY_UV_STARTS_AT_TOP
if (_MainTex_TexelSize.y < 0)
o.uv.y =1- o.uv.y;
else
o.uv.y = o.uv.y;
#endif
return o;
}
fixed4 frag_threshold(v2f_threshold i) : SV_Target
{
fixed4 color = tex2D(_MainTex, i.uv);
return saturate(color - _colorThreshold);
}
v2f_blur vert_blur(appdata_img v)
{
v2f_blur o;
_offsets *= _MainTex_TexelSize.xyxy;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = v.texcoord.xy;
o.uv01 = v.texcoord.xyxy + _offsets.xyxy * float4(1, 1, -1, -1);
o.uv23 = v.texcoord.xyxy + _offsets.xyxy * float4(1, 1, -1, -1) * 2.0;
o.uv45 = v.texcoord.xyxy + _offsets.xyxy * float4(1, 1, -1, -1) * 3.0;
return o;
}
fixed4 frag_blur(v2f_blur i) : SV_Target
{
fixed4 color = fixed4(0,0,0,0);
color += 0.40 * tex2D(_MainTex, i.uv);
color += 0.15 * tex2D(_MainTex, i.uv01.xy);
color += 0.15 * tex2D(_MainTex, i.uv01.zw);
color += 0.10 * tex2D(_MainTex, i.uv23.xy);
color += 0.10 * tex2D(_MainTex, i.uv23.zw);
color += 0.05 * tex2D(_MainTex, i.uv45.xy);
color += 0.05 * tex2D(_MainTex, i.uv45.zw);
return color;
}
v2f_bloom vert_bloom(appdata_img v)
{
v2f_bloom o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv.xy = v.texcoord.xy;
o.uv1.xy = o.uv.xy;
#if UNITY_UV_STARTS_AT_TOP
if (_MainTex_TexelSize.y < 0)
o.uv.y =1- o.uv.y;
else
o.uv.y = o.uv.y;
#endif
return o;
}
fixed4 frag_bloom(v2f_bloom i) : SV_Target
{
fixed4 ori = tex2D(_MainTex, i.uv1);
fixed4 blur = tex2D(_BlurTex, i.uv);
fixed4 final = ori + _bloomFactor * blur * _bloomColor;
return final;
}
ENDCG
SubShader
{
Pass
{
ZTest Off
Cull Off
ZWrite Off
Fog{ Mode Off }
CGPROGRAM
#pragma vertex vert_threshold
#pragma fragment frag_threshold
ENDCG
}
Pass
{
ZTest Off
Cull Off
ZWrite Off
Fog{ Mode Off }
CGPROGRAM
#pragma vertex vert_blur
#pragma fragment frag_blur
ENDCG
}
Pass
{
ZTest Off
Cull Off
ZWrite Off
Fog{ Mode Off }
CGPROGRAM
#pragma vertex vert_bloom
#pragma fragment frag_bloom
ENDCG
}
}
}