Files
2026-02-21 16:45:37 +08:00

215 lines
5.5 KiB
C#

using System;
using UnityEngine;
namespace UnityStandardAssets.CinematicEffects
{
[ExecuteInEditMode]
[RequireComponent(typeof(Camera))]
[AddComponentMenu("Image Effects/Cinematic/Bloom")]
[ImageEffectAllowedInSceneView]
public class Bloom : MonoBehaviour
{
[Serializable]
public struct Settings
{
[SerializeField]
[Tooltip("Filters out pixels under this level of brightness.")]
public float threshold;
[SerializeField]
[Range(0f, 1f)]
[Tooltip("Makes transition between under/over-threshold gradual.")]
public float softKnee;
[SerializeField]
[Range(1f, 7f)]
[Tooltip("Changes extent of veiling effects in a screen resolution-independent fashion.")]
public float radius;
[SerializeField]
[Tooltip("Blend factor of the result image.")]
public float intensity;
[SerializeField]
[Tooltip("Controls filter quality and buffer resolution.")]
public bool highQuality;
[SerializeField]
[Tooltip("Reduces flashing noise with an additional filter.")]
public bool antiFlicker;
[Tooltip("Dirtiness texture to add smudges or dust to the lens.")]
public Texture dirtTexture;
[Min(0f)]
[Tooltip("Amount of lens dirtiness.")]
public float dirtIntensity;
public float thresholdGamma
{
get
{
return Mathf.Max(0f, threshold);
}
set
{
threshold = value;
}
}
public float thresholdLinear
{
get
{
return Mathf.GammaToLinearSpace(thresholdGamma);
}
set
{
threshold = Mathf.LinearToGammaSpace(value);
}
}
public static Settings defaultSettings
{
get
{
return new Settings
{
threshold = 0.9f,
softKnee = 0.5f,
radius = 2f,
intensity = 0.7f,
highQuality = true,
antiFlicker = false,
dirtTexture = null,
dirtIntensity = 2.5f
};
}
}
}
[SerializeField]
public Settings settings = Settings.defaultSettings;
[SerializeField]
[HideInInspector]
private Shader m_Shader;
private Material m_Material;
private const int kMaxIterations = 16;
private RenderTexture[] m_blurBuffer1 = new RenderTexture[16];
private RenderTexture[] m_blurBuffer2 = new RenderTexture[16];
public Shader shader
{
get
{
if (m_Shader == null)
{
m_Shader = Shader.Find("Hidden/Image Effects/Cinematic/Bloom");
}
return m_Shader;
}
}
public Material material
{
get
{
if (m_Material == null)
{
m_Material = ImageEffectHelper.CheckShaderAndCreateMaterial(shader);
}
return m_Material;
}
}
private void OnEnable()
{
if (!ImageEffectHelper.IsSupported(shader, true, false, this))
{
base.enabled = false;
}
}
private void OnDisable()
{
if (m_Material != null)
{
UnityEngine.Object.DestroyImmediate(m_Material);
}
m_Material = null;
}
private void OnRenderImage(RenderTexture source, RenderTexture destination)
{
bool isMobilePlatform = Application.isMobilePlatform;
int num = source.width;
int num2 = source.height;
if (!settings.highQuality)
{
num /= 2;
num2 /= 2;
}
RenderTextureFormat format = ((!isMobilePlatform) ? RenderTextureFormat.DefaultHDR : RenderTextureFormat.Default);
float num3 = Mathf.Log(num2, 2f) + settings.radius - 8f;
int num4 = (int)num3;
int num5 = Mathf.Clamp(num4, 1, 16);
float thresholdLinear = settings.thresholdLinear;
material.SetFloat("_Threshold", thresholdLinear);
float num6 = thresholdLinear * settings.softKnee + 1E-05f;
Vector3 vector = new Vector3(thresholdLinear - num6, num6 * 2f, 0.25f / num6);
material.SetVector("_Curve", vector);
bool flag = !settings.highQuality && settings.antiFlicker;
material.SetFloat("_PrefilterOffs", (!flag) ? 0f : (-0.5f));
material.SetFloat("_SampleScale", 0.5f + num3 - (float)num4);
material.SetFloat("_Intensity", Mathf.Max(0f, settings.intensity));
bool flag2 = false;
if (settings.dirtTexture != null)
{
material.SetTexture("_DirtTex", settings.dirtTexture);
material.SetFloat("_DirtIntensity", settings.dirtIntensity);
flag2 = true;
}
RenderTexture temporary = RenderTexture.GetTemporary(num, num2, 0, format);
Graphics.Blit(source, temporary, material, settings.antiFlicker ? 1 : 0);
RenderTexture renderTexture = temporary;
for (int i = 0; i < num5; i++)
{
m_blurBuffer1[i] = RenderTexture.GetTemporary(renderTexture.width / 2, renderTexture.height / 2, 0, format);
Graphics.Blit(renderTexture, m_blurBuffer1[i], material, (i != 0) ? 4 : ((!settings.antiFlicker) ? 2 : 3));
renderTexture = m_blurBuffer1[i];
}
for (int num7 = num5 - 2; num7 >= 0; num7--)
{
RenderTexture renderTexture2 = m_blurBuffer1[num7];
material.SetTexture("_BaseTex", renderTexture2);
m_blurBuffer2[num7] = RenderTexture.GetTemporary(renderTexture2.width, renderTexture2.height, 0, format);
Graphics.Blit(renderTexture, m_blurBuffer2[num7], material, (!settings.highQuality) ? 5 : 6);
renderTexture = m_blurBuffer2[num7];
}
int num8 = ((!flag2) ? 7 : 9);
num8 += (settings.highQuality ? 1 : 0);
material.SetTexture("_BaseTex", source);
Graphics.Blit(renderTexture, destination, material, num8);
for (int j = 0; j < 16; j++)
{
if (m_blurBuffer1[j] != null)
{
RenderTexture.ReleaseTemporary(m_blurBuffer1[j]);
}
if (m_blurBuffer2[j] != null)
{
RenderTexture.ReleaseTemporary(m_blurBuffer2[j]);
}
m_blurBuffer1[j] = null;
m_blurBuffer2[j] = null;
}
RenderTexture.ReleaseTemporary(temporary);
}
}
}