Files
2026-03-04 10:03:45 +08:00

331 lines
11 KiB
C#

using UnityEngine;
namespace Artngame.SKYMASTER
{
[ExecuteInEditMode]
[RequireComponent(typeof(Camera))]
[AddComponentMenu("Image Effects/SkyMaster/BloomSM")]
public class BloomSkyMaster : PostEffectsBaseSkyMaster
{
public enum LensFlareStyle
{
Ghosting = 0,
Anamorphic = 1,
Combined = 2
}
public enum TweakMode
{
Basic = 0,
Complex = 1
}
public enum HDRBloomMode
{
Auto = 0,
On = 1,
Off = 2
}
public enum BloomScreenBlendMode
{
Screen = 0,
Add = 1
}
public enum BloomQuality
{
Cheap = 0,
High = 1
}
public TweakMode tweakMode;
public BloomScreenBlendMode screenBlendMode = BloomScreenBlendMode.Add;
public HDRBloomMode hdr;
private bool doHdr;
public float sepBlurSpread = 2.5f;
public BloomQuality quality = BloomQuality.High;
public float bloomIntensity = 0.5f;
public float bloomThreshold = 0.5f;
public Color bloomThresholdColor = Color.white;
public int bloomBlurIterations = 2;
public int hollywoodFlareBlurIterations = 2;
public float flareRotation;
public LensFlareStyle lensflareMode = LensFlareStyle.Anamorphic;
public float hollyStretchWidth = 2.5f;
public float lensflareIntensity;
public float lensflareThreshold = 0.3f;
public float lensFlareSaturation = 0.75f;
public Color flareColorA = new Color(0.4f, 0.4f, 0.8f, 0.75f);
public Color flareColorB = new Color(0.4f, 0.8f, 0.8f, 0.75f);
public Color flareColorC = new Color(0.8f, 0.4f, 0.8f, 0.75f);
public Color flareColorD = new Color(0.8f, 0.4f, 0f, 0.75f);
public Texture2D lensFlareVignetteMask;
public Shader lensFlareShader;
private Material lensFlareMaterial;
public Shader screenBlendShader;
private Material screenBlend;
public Shader blurAndFlaresShader;
private Material blurAndFlaresMaterial;
public Shader brightPassFilterShader;
private Material brightPassFilterMaterial;
public override bool CheckResources()
{
CheckSupport(needDepth: false);
screenBlend = CheckShaderAndCreateMaterial(screenBlendShader, screenBlend);
lensFlareMaterial = CheckShaderAndCreateMaterial(lensFlareShader, lensFlareMaterial);
blurAndFlaresMaterial = CheckShaderAndCreateMaterial(blurAndFlaresShader, blurAndFlaresMaterial);
brightPassFilterMaterial = CheckShaderAndCreateMaterial(brightPassFilterShader, brightPassFilterMaterial);
if (!isSupported)
{
ReportAutoDisable();
}
return isSupported;
}
public void OnRenderImage(RenderTexture source, RenderTexture destination)
{
if (!CheckResources())
{
Graphics.Blit(source, destination);
return;
}
doHdr = false;
if (hdr == HDRBloomMode.Auto)
{
doHdr = source.format == RenderTextureFormat.ARGBHalf && GetComponent<Camera>().allowHDR;
}
else
{
doHdr = hdr == HDRBloomMode.On;
}
doHdr = doHdr && supportHDRTextures;
BloomScreenBlendMode bloomScreenBlendMode = screenBlendMode;
if (doHdr)
{
bloomScreenBlendMode = BloomScreenBlendMode.Add;
}
RenderTextureFormat format = (doHdr ? RenderTextureFormat.ARGBHalf : RenderTextureFormat.Default);
int width = source.width / 2;
int height = source.height / 2;
int width2 = source.width / 4;
int height2 = source.height / 4;
float num = 1f * (float)source.width / (1f * (float)source.height);
float num2 = 0.001953125f;
RenderTexture temporary = RenderTexture.GetTemporary(width2, height2, 0, format);
RenderTexture temporary2 = RenderTexture.GetTemporary(width, height, 0, format);
if (quality > BloomQuality.Cheap)
{
Graphics.Blit(source, temporary2, screenBlend, 2);
RenderTexture temporary3 = RenderTexture.GetTemporary(width2, height2, 0, format);
Graphics.Blit(temporary2, temporary3, screenBlend, 2);
Graphics.Blit(temporary3, temporary, screenBlend, 6);
RenderTexture.ReleaseTemporary(temporary3);
}
else
{
Graphics.Blit(source, temporary2);
Graphics.Blit(temporary2, temporary, screenBlend, 6);
}
RenderTexture.ReleaseTemporary(temporary2);
RenderTexture renderTexture = RenderTexture.GetTemporary(width2, height2, 0, format);
BrightFilter(bloomThreshold * bloomThresholdColor, temporary, renderTexture);
if (bloomBlurIterations < 1)
{
bloomBlurIterations = 1;
}
else if (bloomBlurIterations > 10)
{
bloomBlurIterations = 10;
}
for (int i = 0; i < bloomBlurIterations; i++)
{
float num3 = (1f + (float)i * 0.25f) * sepBlurSpread;
RenderTexture temporary4 = RenderTexture.GetTemporary(width2, height2, 0, format);
blurAndFlaresMaterial.SetVector("_Offsets", new Vector4(0f, num3 * num2, 0f, 0f));
Graphics.Blit(renderTexture, temporary4, blurAndFlaresMaterial, 4);
RenderTexture.ReleaseTemporary(renderTexture);
renderTexture = temporary4;
temporary4 = RenderTexture.GetTemporary(width2, height2, 0, format);
blurAndFlaresMaterial.SetVector("_Offsets", new Vector4(num3 / num * num2, 0f, 0f, 0f));
Graphics.Blit(renderTexture, temporary4, blurAndFlaresMaterial, 4);
RenderTexture.ReleaseTemporary(renderTexture);
renderTexture = temporary4;
if (quality > BloomQuality.Cheap)
{
if (i == 0)
{
Graphics.SetRenderTarget(temporary);
GL.Clear(clearDepth: false, clearColor: true, Color.black);
Graphics.Blit(renderTexture, temporary);
}
else
{
Graphics.Blit(renderTexture, temporary, screenBlend, 10);
}
}
}
if (quality > BloomQuality.Cheap)
{
Graphics.SetRenderTarget(renderTexture);
GL.Clear(clearDepth: false, clearColor: true, Color.black);
Graphics.Blit(temporary, renderTexture, screenBlend, 6);
}
if (lensflareIntensity > Mathf.Epsilon)
{
RenderTexture temporary5 = RenderTexture.GetTemporary(width2, height2, 0, format);
if (lensflareMode == LensFlareStyle.Ghosting)
{
BrightFilter(lensflareThreshold, renderTexture, temporary5);
if (quality > BloomQuality.Cheap)
{
blurAndFlaresMaterial.SetVector("_Offsets", new Vector4(0f, 1.5f / (1f * (float)temporary.height), 0f, 0f));
Graphics.SetRenderTarget(temporary);
GL.Clear(clearDepth: false, clearColor: true, Color.black);
Graphics.Blit(temporary5, temporary, blurAndFlaresMaterial, 4);
blurAndFlaresMaterial.SetVector("_Offsets", new Vector4(1.5f / (1f * (float)temporary.width), 0f, 0f, 0f));
Graphics.SetRenderTarget(temporary5);
GL.Clear(clearDepth: false, clearColor: true, Color.black);
Graphics.Blit(temporary, temporary5, blurAndFlaresMaterial, 4);
}
Vignette(0.975f, temporary5, temporary5);
BlendFlares(temporary5, renderTexture);
}
else
{
float num4 = 1f * Mathf.Cos(flareRotation);
float num5 = 1f * Mathf.Sin(flareRotation);
float num6 = hollyStretchWidth * 1f / num * num2;
blurAndFlaresMaterial.SetVector("_Offsets", new Vector4(num4, num5, 0f, 0f));
blurAndFlaresMaterial.SetVector("_Threshhold", new Vector4(lensflareThreshold, 1f, 0f, 0f));
blurAndFlaresMaterial.SetVector("_TintColor", new Vector4(flareColorA.r, flareColorA.g, flareColorA.b, flareColorA.a) * flareColorA.a * lensflareIntensity);
blurAndFlaresMaterial.SetFloat("_Saturation", lensFlareSaturation);
temporary.DiscardContents();
Graphics.Blit(temporary5, temporary, blurAndFlaresMaterial, 2);
temporary5.DiscardContents();
Graphics.Blit(temporary, temporary5, blurAndFlaresMaterial, 3);
blurAndFlaresMaterial.SetVector("_Offsets", new Vector4(num4 * num6, num5 * num6, 0f, 0f));
blurAndFlaresMaterial.SetFloat("_StretchWidth", hollyStretchWidth);
temporary.DiscardContents();
Graphics.Blit(temporary5, temporary, blurAndFlaresMaterial, 1);
blurAndFlaresMaterial.SetFloat("_StretchWidth", hollyStretchWidth * 2f);
temporary5.DiscardContents();
Graphics.Blit(temporary, temporary5, blurAndFlaresMaterial, 1);
blurAndFlaresMaterial.SetFloat("_StretchWidth", hollyStretchWidth * 4f);
temporary.DiscardContents();
Graphics.Blit(temporary5, temporary, blurAndFlaresMaterial, 1);
for (int j = 0; j < hollywoodFlareBlurIterations; j++)
{
num6 = hollyStretchWidth * 2f / num * num2;
blurAndFlaresMaterial.SetVector("_Offsets", new Vector4(num6 * num4, num6 * num5, 0f, 0f));
temporary5.DiscardContents();
Graphics.Blit(temporary, temporary5, blurAndFlaresMaterial, 4);
blurAndFlaresMaterial.SetVector("_Offsets", new Vector4(num6 * num4, num6 * num5, 0f, 0f));
temporary.DiscardContents();
Graphics.Blit(temporary5, temporary, blurAndFlaresMaterial, 4);
}
if (lensflareMode == LensFlareStyle.Anamorphic)
{
AddTo(1f, temporary, renderTexture);
}
else
{
Vignette(1f, temporary, temporary5);
BlendFlares(temporary5, temporary);
AddTo(1f, temporary, renderTexture);
}
}
RenderTexture.ReleaseTemporary(temporary5);
}
int pass = (int)bloomScreenBlendMode;
screenBlend.SetFloat("_Intensity", bloomIntensity);
screenBlend.SetTexture("_ColorBuffer", source);
if (quality > BloomQuality.Cheap)
{
RenderTexture temporary6 = RenderTexture.GetTemporary(width, height, 0, format);
Graphics.Blit(renderTexture, temporary6);
Graphics.Blit(temporary6, destination, screenBlend, pass);
RenderTexture.ReleaseTemporary(temporary6);
}
else
{
Graphics.Blit(renderTexture, destination, screenBlend, pass);
}
RenderTexture.ReleaseTemporary(temporary);
RenderTexture.ReleaseTemporary(renderTexture);
}
private void AddTo(float intensity_, RenderTexture from, RenderTexture to)
{
screenBlend.SetFloat("_Intensity", intensity_);
Graphics.Blit(from, to, screenBlend, 9);
}
private void BlendFlares(RenderTexture from, RenderTexture to)
{
lensFlareMaterial.SetVector("colorA", new Vector4(flareColorA.r, flareColorA.g, flareColorA.b, flareColorA.a) * lensflareIntensity);
lensFlareMaterial.SetVector("colorB", new Vector4(flareColorB.r, flareColorB.g, flareColorB.b, flareColorB.a) * lensflareIntensity);
lensFlareMaterial.SetVector("colorC", new Vector4(flareColorC.r, flareColorC.g, flareColorC.b, flareColorC.a) * lensflareIntensity);
lensFlareMaterial.SetVector("colorD", new Vector4(flareColorD.r, flareColorD.g, flareColorD.b, flareColorD.a) * lensflareIntensity);
Graphics.Blit(from, to, lensFlareMaterial);
}
private void BrightFilter(float thresh, RenderTexture from, RenderTexture to)
{
brightPassFilterMaterial.SetVector("_Threshhold", new Vector4(thresh, thresh, thresh, thresh));
Graphics.Blit(from, to, brightPassFilterMaterial, 0);
}
private void BrightFilter(Color threshColor, RenderTexture from, RenderTexture to)
{
brightPassFilterMaterial.SetVector("_Threshhold", threshColor);
Graphics.Blit(from, to, brightPassFilterMaterial, 1);
}
private void Vignette(float amount, RenderTexture from, RenderTexture to)
{
if ((bool)lensFlareVignetteMask)
{
screenBlend.SetTexture("_ColorBuffer", lensFlareVignetteMask);
Graphics.Blit((from == to) ? null : from, to, screenBlend, (from == to) ? 7 : 3);
}
else if (from != to)
{
Graphics.SetRenderTarget(to);
GL.Clear(clearDepth: false, clearColor: true, Color.black);
Graphics.Blit(from, to);
}
}
}
}