mirror of
https://github.com/FriendshipIsEpic/FiE-Game.git
synced 2024-12-02 09:47:59 +01:00
363 lines
16 KiB
C#
363 lines
16 KiB
C#
|
using System;
|
||
|
using UnityEngine;
|
||
|
|
||
|
namespace UnityStandardAssets.ImageEffects
|
||
|
{
|
||
|
[ExecuteInEditMode]
|
||
|
[RequireComponent (typeof(Camera))]
|
||
|
[AddComponentMenu ("Image Effects/Bloom and Glow/Bloom")]
|
||
|
public class Bloom : PostEffectsBase
|
||
|
{
|
||
|
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 = 0;
|
||
|
public BloomScreenBlendMode screenBlendMode = BloomScreenBlendMode.Add;
|
||
|
|
||
|
public HDRBloomMode hdr = HDRBloomMode.Auto;
|
||
|
private bool doHdr = false;
|
||
|
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 = 0.0f;
|
||
|
public LensFlareStyle lensflareMode = (LensFlareStyle) 1;
|
||
|
public float hollyStretchWidth = 2.5f;
|
||
|
public float lensflareIntensity = 0.0f;
|
||
|
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, 0.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 (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()==false)
|
||
|
{
|
||
|
Graphics.Blit (source, destination);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// screen blend is not supported when HDR is enabled (will cap values)
|
||
|
|
||
|
doHdr = false;
|
||
|
if (hdr == HDRBloomMode.Auto)
|
||
|
#if UNITY_5_6_OR_NEWER
|
||
|
doHdr = source.format == RenderTextureFormat.ARGBHalf && GetComponent<Camera>().allowHDR;
|
||
|
#else
|
||
|
doHdr = source.format == RenderTextureFormat.ARGBHalf && GetComponent<Camera>().hdr;
|
||
|
#endif
|
||
|
else {
|
||
|
doHdr = hdr == HDRBloomMode.On;
|
||
|
}
|
||
|
|
||
|
doHdr = doHdr && supportHDRTextures;
|
||
|
|
||
|
BloomScreenBlendMode realBlendMode = screenBlendMode;
|
||
|
if (doHdr)
|
||
|
realBlendMode = BloomScreenBlendMode.Add;
|
||
|
|
||
|
var rtFormat= (doHdr) ? RenderTextureFormat.ARGBHalf : RenderTextureFormat.Default;
|
||
|
var rtW2= source.width/2;
|
||
|
var rtH2= source.height/2;
|
||
|
var rtW4= source.width/4;
|
||
|
var rtH4= source.height/4;
|
||
|
|
||
|
float widthOverHeight = (1.0f * source.width) / (1.0f * source.height);
|
||
|
float oneOverBaseSize = 1.0f / 512.0f;
|
||
|
|
||
|
// downsample
|
||
|
RenderTexture quarterRezColor = RenderTexture.GetTemporary (rtW4, rtH4, 0, rtFormat);
|
||
|
RenderTexture halfRezColorDown = RenderTexture.GetTemporary (rtW2, rtH2, 0, rtFormat);
|
||
|
if (quality > BloomQuality.Cheap) {
|
||
|
Graphics.Blit (source, halfRezColorDown, screenBlend, 2);
|
||
|
RenderTexture rtDown4 = RenderTexture.GetTemporary (rtW4, rtH4, 0, rtFormat);
|
||
|
Graphics.Blit (halfRezColorDown, rtDown4, screenBlend, 2);
|
||
|
Graphics.Blit (rtDown4, quarterRezColor, screenBlend, 6);
|
||
|
RenderTexture.ReleaseTemporary(rtDown4);
|
||
|
}
|
||
|
else {
|
||
|
Graphics.Blit (source, halfRezColorDown);
|
||
|
Graphics.Blit (halfRezColorDown, quarterRezColor, screenBlend, 6);
|
||
|
}
|
||
|
RenderTexture.ReleaseTemporary (halfRezColorDown);
|
||
|
|
||
|
// cut colors (thresholding)
|
||
|
RenderTexture secondQuarterRezColor = RenderTexture.GetTemporary (rtW4, rtH4, 0, rtFormat);
|
||
|
BrightFilter (bloomThreshold * bloomThresholdColor, quarterRezColor, secondQuarterRezColor);
|
||
|
|
||
|
// blurring
|
||
|
|
||
|
if (bloomBlurIterations < 1) bloomBlurIterations = 1;
|
||
|
else if (bloomBlurIterations > 10) bloomBlurIterations = 10;
|
||
|
|
||
|
for (int iter = 0; iter < bloomBlurIterations; iter++)
|
||
|
{
|
||
|
float spreadForPass = (1.0f + (iter * 0.25f)) * sepBlurSpread;
|
||
|
|
||
|
// vertical blur
|
||
|
RenderTexture blur4 = RenderTexture.GetTemporary (rtW4, rtH4, 0, rtFormat);
|
||
|
blurAndFlaresMaterial.SetVector ("_Offsets", new Vector4 (0.0f, spreadForPass * oneOverBaseSize, 0.0f, 0.0f));
|
||
|
Graphics.Blit (secondQuarterRezColor, blur4, blurAndFlaresMaterial, 4);
|
||
|
RenderTexture.ReleaseTemporary(secondQuarterRezColor);
|
||
|
secondQuarterRezColor = blur4;
|
||
|
|
||
|
// horizontal blur
|
||
|
blur4 = RenderTexture.GetTemporary (rtW4, rtH4, 0, rtFormat);
|
||
|
blurAndFlaresMaterial.SetVector ("_Offsets", new Vector4 ((spreadForPass / widthOverHeight) * oneOverBaseSize, 0.0f, 0.0f, 0.0f));
|
||
|
Graphics.Blit (secondQuarterRezColor, blur4, blurAndFlaresMaterial, 4);
|
||
|
RenderTexture.ReleaseTemporary (secondQuarterRezColor);
|
||
|
secondQuarterRezColor = blur4;
|
||
|
|
||
|
if (quality > BloomQuality.Cheap)
|
||
|
{
|
||
|
if (iter == 0)
|
||
|
{
|
||
|
Graphics.SetRenderTarget(quarterRezColor);
|
||
|
GL.Clear(false, true, Color.black); // Clear to avoid RT restore
|
||
|
Graphics.Blit (secondQuarterRezColor, quarterRezColor);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
quarterRezColor.MarkRestoreExpected(); // using max blending, RT restore expected
|
||
|
Graphics.Blit (secondQuarterRezColor, quarterRezColor, screenBlend, 10);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (quality > BloomQuality.Cheap)
|
||
|
{
|
||
|
Graphics.SetRenderTarget(secondQuarterRezColor);
|
||
|
GL.Clear(false, true, Color.black); // Clear to avoid RT restore
|
||
|
Graphics.Blit (quarterRezColor, secondQuarterRezColor, screenBlend, 6);
|
||
|
}
|
||
|
|
||
|
// lens flares: ghosting, anamorphic or both (ghosted anamorphic flares)
|
||
|
|
||
|
if (lensflareIntensity > Mathf.Epsilon)
|
||
|
{
|
||
|
|
||
|
RenderTexture rtFlares4 = RenderTexture.GetTemporary (rtW4, rtH4, 0, rtFormat);
|
||
|
|
||
|
if (lensflareMode == 0)
|
||
|
{
|
||
|
// ghosting only
|
||
|
|
||
|
BrightFilter (lensflareThreshold, secondQuarterRezColor, rtFlares4);
|
||
|
|
||
|
if (quality > BloomQuality.Cheap)
|
||
|
{
|
||
|
// smooth a little
|
||
|
blurAndFlaresMaterial.SetVector ("_Offsets", new Vector4 (0.0f, (1.5f) / (1.0f * quarterRezColor.height), 0.0f, 0.0f));
|
||
|
Graphics.SetRenderTarget(quarterRezColor);
|
||
|
GL.Clear(false, true, Color.black); // Clear to avoid RT restore
|
||
|
Graphics.Blit (rtFlares4, quarterRezColor, blurAndFlaresMaterial, 4);
|
||
|
|
||
|
blurAndFlaresMaterial.SetVector ("_Offsets", new Vector4 ((1.5f) / (1.0f * quarterRezColor.width), 0.0f, 0.0f, 0.0f));
|
||
|
Graphics.SetRenderTarget(rtFlares4);
|
||
|
GL.Clear(false, true, Color.black); // Clear to avoid RT restore
|
||
|
Graphics.Blit (quarterRezColor, rtFlares4, blurAndFlaresMaterial, 4);
|
||
|
}
|
||
|
|
||
|
// no ugly edges!
|
||
|
Vignette (0.975f, rtFlares4, rtFlares4);
|
||
|
BlendFlares (rtFlares4, secondQuarterRezColor);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
|
||
|
//Vignette (0.975ff, rtFlares4, rtFlares4);
|
||
|
//DrawBorder(rtFlares4, screenBlend, 8);
|
||
|
|
||
|
float flareXRot = 1.0f * Mathf.Cos(flareRotation);
|
||
|
float flareyRot = 1.0f * Mathf.Sin(flareRotation);
|
||
|
|
||
|
float stretchWidth = (hollyStretchWidth * 1.0f / widthOverHeight) * oneOverBaseSize;
|
||
|
|
||
|
blurAndFlaresMaterial.SetVector ("_Offsets", new Vector4 (flareXRot, flareyRot, 0.0f, 0.0f));
|
||
|
blurAndFlaresMaterial.SetVector ("_Threshhold", new Vector4 (lensflareThreshold, 1.0f, 0.0f, 0.0f));
|
||
|
blurAndFlaresMaterial.SetVector ("_TintColor", new Vector4 (flareColorA.r, flareColorA.g, flareColorA.b, flareColorA.a) * flareColorA.a * lensflareIntensity);
|
||
|
blurAndFlaresMaterial.SetFloat ("_Saturation", lensFlareSaturation);
|
||
|
|
||
|
// "pre and cut"
|
||
|
quarterRezColor.DiscardContents();
|
||
|
Graphics.Blit (rtFlares4, quarterRezColor, blurAndFlaresMaterial, 2);
|
||
|
// "post"
|
||
|
rtFlares4.DiscardContents();
|
||
|
Graphics.Blit (quarterRezColor, rtFlares4, blurAndFlaresMaterial, 3);
|
||
|
|
||
|
blurAndFlaresMaterial.SetVector ("_Offsets", new Vector4 (flareXRot * stretchWidth, flareyRot * stretchWidth, 0.0f, 0.0f));
|
||
|
// stretch 1st
|
||
|
blurAndFlaresMaterial.SetFloat ("_StretchWidth", hollyStretchWidth);
|
||
|
quarterRezColor.DiscardContents();
|
||
|
Graphics.Blit (rtFlares4, quarterRezColor, blurAndFlaresMaterial, 1);
|
||
|
// stretch 2nd
|
||
|
blurAndFlaresMaterial.SetFloat ("_StretchWidth", hollyStretchWidth * 2.0f);
|
||
|
rtFlares4.DiscardContents();
|
||
|
Graphics.Blit (quarterRezColor, rtFlares4, blurAndFlaresMaterial, 1);
|
||
|
// stretch 3rd
|
||
|
blurAndFlaresMaterial.SetFloat ("_StretchWidth", hollyStretchWidth * 4.0f);
|
||
|
quarterRezColor.DiscardContents();
|
||
|
Graphics.Blit (rtFlares4, quarterRezColor, blurAndFlaresMaterial, 1);
|
||
|
|
||
|
// additional blur passes
|
||
|
for (int iter = 0; iter < hollywoodFlareBlurIterations; iter++)
|
||
|
{
|
||
|
stretchWidth = (hollyStretchWidth * 2.0f / widthOverHeight) * oneOverBaseSize;
|
||
|
|
||
|
blurAndFlaresMaterial.SetVector ("_Offsets", new Vector4 (stretchWidth * flareXRot, stretchWidth * flareyRot, 0.0f, 0.0f));
|
||
|
rtFlares4.DiscardContents();
|
||
|
Graphics.Blit (quarterRezColor, rtFlares4, blurAndFlaresMaterial, 4);
|
||
|
|
||
|
blurAndFlaresMaterial.SetVector ("_Offsets", new Vector4 (stretchWidth * flareXRot, stretchWidth * flareyRot, 0.0f, 0.0f));
|
||
|
quarterRezColor.DiscardContents();
|
||
|
Graphics.Blit (rtFlares4, quarterRezColor, blurAndFlaresMaterial, 4);
|
||
|
}
|
||
|
|
||
|
if (lensflareMode == (LensFlareStyle) 1)
|
||
|
// anamorphic lens flares
|
||
|
AddTo (1.0f, quarterRezColor, secondQuarterRezColor);
|
||
|
else
|
||
|
{
|
||
|
// "combined" lens flares
|
||
|
|
||
|
Vignette (1.0f, quarterRezColor, rtFlares4);
|
||
|
BlendFlares (rtFlares4, quarterRezColor);
|
||
|
AddTo (1.0f, quarterRezColor, secondQuarterRezColor);
|
||
|
}
|
||
|
}
|
||
|
RenderTexture.ReleaseTemporary (rtFlares4);
|
||
|
}
|
||
|
|
||
|
int blendPass = (int) realBlendMode;
|
||
|
//if (Mathf.Abs(chromaticBloom) < Mathf.Epsilon)
|
||
|
// blendPass += 4;
|
||
|
|
||
|
screenBlend.SetFloat ("_Intensity", bloomIntensity);
|
||
|
screenBlend.SetTexture ("_ColorBuffer", source);
|
||
|
|
||
|
if (quality > BloomQuality.Cheap)
|
||
|
{
|
||
|
RenderTexture halfRezColorUp = RenderTexture.GetTemporary (rtW2, rtH2, 0, rtFormat);
|
||
|
Graphics.Blit (secondQuarterRezColor, halfRezColorUp);
|
||
|
Graphics.Blit (halfRezColorUp, destination, screenBlend, blendPass);
|
||
|
RenderTexture.ReleaseTemporary (halfRezColorUp);
|
||
|
}
|
||
|
else
|
||
|
Graphics.Blit (secondQuarterRezColor, destination, screenBlend, blendPass);
|
||
|
|
||
|
RenderTexture.ReleaseTemporary (quarterRezColor);
|
||
|
RenderTexture.ReleaseTemporary (secondQuarterRezColor);
|
||
|
}
|
||
|
|
||
|
private void AddTo (float intensity_, RenderTexture from, RenderTexture to)
|
||
|
{
|
||
|
screenBlend.SetFloat ("_Intensity", intensity_);
|
||
|
to.MarkRestoreExpected(); // additive blending, RT restore expected
|
||
|
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);
|
||
|
to.MarkRestoreExpected(); // additive blending, RT restore expected
|
||
|
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 (lensFlareVignetteMask)
|
||
|
{
|
||
|
screenBlend.SetTexture ("_ColorBuffer", lensFlareVignetteMask);
|
||
|
to.MarkRestoreExpected(); // using blending, RT restore expected
|
||
|
Graphics.Blit (from == to ? null : from, to, screenBlend, from == to ? 7 : 3);
|
||
|
}
|
||
|
else if (from != to)
|
||
|
{
|
||
|
Graphics.SetRenderTarget (to);
|
||
|
GL.Clear(false, true, Color.black); // clear destination to avoid RT restore
|
||
|
Graphics.Blit (from, to);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|