FiE-Game/Assets/Cinematic Effects/BloomBeta/Scripts/UltimateBloom.cs

1568 lines
60 KiB
C#

using UnityEngine;
using System.Collections;
using System;
#if UNITY_EDITOR
using UnityEditor;
using System.IO;
#endif
[ExecuteInEditMode]
[RequireComponent(typeof(Camera))]
public class UltimateBloom : MonoBehaviour
{
public enum BloomQualityPreset
{
Optimized,
Standard,
HighVisuals,
Custom
}
public enum BloomSamplingQuality
{
VerySmallKernel, // 9
SmallKernel, // 13
MediumKernel, // 17
LargeKernel, // 23
LargerKernel, // 27
VeryLargeKernel // 31
}
public enum BloomScreenBlendMode
{
Screen = 0,
Add = 1,
}
public enum HDRBloomMode
{
Auto = 0,
On = 1,
Off = 2,
}
public enum BlurSampleCount
{
Nine,
Seventeen,
Thirteen,
TwentyThree,
TwentySeven,
ThrirtyOne,
NineCurve,
FourSimple
}
public enum FlareRendering
{
Sharp,
Blurred,
MoreBlurred
}
public enum SimpleSampleCount
{
Four,
Nine,
FourCurve,
ThirteenTemporal,
ThirteenTemporalCurve
}
public enum FlareType
{
Single,
Double
}
public enum BloomIntensityManagement
{
FilmicCurve,
Threshold
}
private enum FlareStripeType
{
Anamorphic,
Star,
DiagonalUpright,
DiagonalUpleft
}
public enum AnamorphicDirection
{
Horizontal,
Vertical
}
public enum BokehFlareQuality
{
Low,
Medium,
High,
VeryHigh
}
public enum BlendMode
{
ADD,
SCREEN
}
public enum SamplingMode
{
Fixed,
HeightRelative
}
public enum FlareBlurQuality
{
Fast,
Normal,
High
}
public enum FlarePresets
{
ChoosePreset,
GhostFast,
Ghost1,
Ghost2,
Ghost3,
Bokeh1,
Bokeh2,
Bokeh3
}
public float m_SamplingMinHeight = 400.0f;
public float[] m_ResSamplingPixelCount = new float[6];
public SamplingMode m_SamplingMode = SamplingMode.Fixed;
public BlendMode m_BlendMode = BlendMode.ADD;
public float m_ScreenMaxIntensity;
public BloomQualityPreset m_QualityPreset;
public HDRBloomMode m_HDR = HDRBloomMode.Auto;
public BloomScreenBlendMode m_ScreenBlendMode = BloomScreenBlendMode.Add;
public float m_BloomIntensity = 1.0f;
public float m_BloomThreshhold = 0.5f;
public Color m_BloomThreshholdColor = Color.white;
public int m_DownscaleCount = 5;
public BloomIntensityManagement m_IntensityManagement = BloomIntensityManagement.FilmicCurve;
public float[] m_BloomIntensities;
public Color[] m_BloomColors;
public bool[] m_BloomUsages;
[SerializeField]
public DeluxeFilmicCurve m_BloomCurve = new DeluxeFilmicCurve();
private int m_LastDownscaleCount = 5;
public bool m_UseLensFlare = false;
public float m_FlareTreshold = 0.8f;
public float m_FlareIntensity = 0.25f;
public Color m_FlareTint0 = new Color(137 / 255.0f, 82 / 255.0f, 0 / 255.0f);
public Color m_FlareTint1 = new Color(0 / 255.0f, 63 / 255.0f, 126 / 255.0f);
public Color m_FlareTint2 = new Color(72 / 255.0f, 151 / 255.0f, 0 / 255.0f);
public Color m_FlareTint3 = new Color(114 / 255.0f, 35 / 255.0f, 0 / 255.0f);
public Color m_FlareTint4 = new Color(122 / 255.0f, 88 / 255.0f, 0 / 255.0f);
public Color m_FlareTint5 = new Color(137 / 255.0f, 71 / 255.0f, 0 / 255.0f);
public Color m_FlareTint6 = new Color(97 / 255.0f, 139 / 255.0f, 0 / 255.0f);
public Color m_FlareTint7 = new Color(40 / 255.0f, 142 / 255.0f, 0 / 255.0f);
public float m_FlareGlobalScale = 1.0f;
public Vector4 m_FlareScales = new Vector4(1.0f, 0.6f, 0.5f, 0.4f);
public Vector4 m_FlareScalesNear = new Vector4(1.0f, 0.8f, 0.6f, 0.5f);
public Texture2D m_FlareMask;
public FlareRendering m_FlareRendering = FlareRendering.Blurred;
public FlareType m_FlareType = FlareType.Double;
public Texture2D m_FlareShape;
public FlareBlurQuality m_FlareBlurQuality = FlareBlurQuality.High;
BokehRenderer m_FlareSpriteRenderer;
Mesh[] m_BokehMeshes;
public bool m_UseBokehFlare = false;
public float m_BokehScale = 0.4f;
//public bool m_HighQualityBokehFlare = true;
public BokehFlareQuality m_BokehFlareQuality = BokehFlareQuality.Medium;
public bool m_UseAnamorphicFlare = false;
public float m_AnamorphicFlareTreshold = 0.8f;
public float m_AnamorphicFlareIntensity = 1.0f;
public int m_AnamorphicDownscaleCount = 3;
public int m_AnamorphicBlurPass = 2;
private int m_LastAnamorphicDownscaleCount;
private RenderTexture[] m_AnamorphicUpscales;
public float[] m_AnamorphicBloomIntensities;
public Color[] m_AnamorphicBloomColors;
public bool[] m_AnamorphicBloomUsages;
public bool m_AnamorphicSmallVerticalBlur = true;
public AnamorphicDirection m_AnamorphicDirection = AnamorphicDirection.Horizontal;
public float m_AnamorphicScale = 3.0f;
public bool m_UseStarFlare = false;
public float m_StarFlareTreshol = 0.8f;
public float m_StarFlareIntensity = 1.0f;
public float m_StarScale = 2.0f;
public int m_StarDownscaleCount = 3;
public int m_StarBlurPass = 2;
private int m_LastStarDownscaleCount;
private RenderTexture[] m_StarUpscales;
public float[] m_StarBloomIntensities;
public Color[] m_StarBloomColors;
public bool[] m_StarBloomUsages;
public bool m_UseLensDust = false;
public float m_DustIntensity = 1.0f;
public Texture2D m_DustTexture;
public float m_DirtLightIntensity = 5.0f;
public BloomSamplingQuality m_DownsamplingQuality;
public BloomSamplingQuality m_UpsamplingQuality;
public bool m_TemporalStableDownsampling = true;
// Misc
public bool m_InvertImage = false;
// Materials/shaders
private Material m_FlareMaterial;
private Shader m_FlareShader;
private Material m_SamplingMaterial;
private Shader m_SamplingShader;
private Material m_CombineMaterial;
private Shader m_CombineShader;
private Material m_BrightpassMaterial;
private Shader m_BrightpassShader;
private Material m_FlareMaskMaterial;
private Shader m_FlareMaskShader;
private Material m_MixerMaterial;
private Shader m_MixerShader;
private Material m_FlareBokehMaterial;
private Shader m_FlareBokehShader;
// Optimization
public bool m_DirectDownSample = false;
public bool m_DirectUpsample = false;
// UI
public bool m_UiShowBloomScales = false;
public bool m_UiShowAnamorphicBloomScales = false;
public bool m_UiShowStarBloomScales = false;
public bool m_UiShowHeightSampling = false;
public bool m_UiShowBloomSettings = false;
public bool m_UiShowSampling = false;
public bool m_UiShowIntensity = false;
public bool m_UiShowOptimizations = false;
public bool m_UiShowLensDirt = false;
public bool m_UiShowLensFlare = false;
public bool m_UiShowAnamorphic = false;
public bool m_UiShowStar = false;
#if UNITY_EDITOR
public bool m_UiInitialized = false;
void OnEnable()
{
if (!m_UiInitialized && !Application.isPlaying)
{
m_UiInitialized = true;
IntializeUltimateBloom();
}
}
public static string GetAbsoluteAssetPath(string path)
{
UltimateBloomPathLocator locator = ScriptableObject.CreateInstance<UltimateBloomPathLocator>();
MonoScript script = MonoScript.FromScriptableObject(locator);
string scriptPath = AssetDatabase.GetAssetPath(script);
ScriptableObject.DestroyImmediate(locator);
return Path.GetDirectoryName(scriptPath) + "/" + path;
}
private void IntializeUltimateBloom()
{
CreateMaterials();
m_BloomUsages[0] = false;
m_AnamorphicBloomUsages[0] = true;
m_AnamorphicBloomUsages[1] = true;
m_StarBloomUsages[0] = true;
m_StarBloomUsages[1] = true;
m_UpsamplingQuality = UltimateBloom.BloomSamplingQuality.SmallKernel;
string flareMaskPath = GetAbsoluteAssetPath("Graphics/FlareMask.png");
Texture2D flareMask = (Texture2D)AssetDatabase.LoadAssetAtPath(flareMaskPath, typeof(Texture2D));
m_FlareMask = flareMask;
string bokehPath = GetAbsoluteAssetPath("Graphics/Bokeh.png");
Texture2D bokeh = (Texture2D)AssetDatabase.LoadAssetAtPath(bokehPath, typeof(Texture2D));
m_FlareShape = bokeh;
string dustPath = GetAbsoluteAssetPath("DirtTextureSample/Dust.tif");
Texture2D dust = (Texture2D)AssetDatabase.LoadAssetAtPath(dustPath, typeof(Texture2D));
m_DustTexture = dust;
m_BloomCurve.UpdateCoefficients();
}
#endif
private void DestroyMaterial(Material mat)
{
if (mat)
{
DestroyImmediate(mat);
mat = null;
}
}
private void LoadShader(ref Material material, ref Shader shader, string shaderPath)
{
if (shader != null)
return;
shader = Shader.Find(shaderPath);
if (shader == null)
{
Debug.LogError("Shader not found: " + shaderPath);
return;
}
if (!shader.isSupported)
{
Debug.LogError("Shader contains error: " + shaderPath + "\n Maybe include path? Try rebuilding the shader.");
return;
}
material = CreateMaterial(shader);
}
public void CreateMaterials()
{
//m_FlareType = FlareType.Double;
int maxScaleCount = 8;
if (m_BloomIntensities == null || m_BloomIntensities.Length < maxScaleCount)
{
m_BloomIntensities = new float[maxScaleCount];
for (int i = 0; i < 8; ++i)
m_BloomIntensities[i] = 1.0f;
}
if (m_BloomColors == null || m_BloomColors.Length < maxScaleCount)
{
m_BloomColors = new Color[maxScaleCount];
for (int i = 0; i < 8; ++i)
m_BloomColors[i] = Color.white;
}
if (m_BloomUsages == null || m_BloomUsages.Length < maxScaleCount )
{
m_BloomUsages = new bool[maxScaleCount];
for (int i = 0; i < 8; ++i)
m_BloomUsages[i] = true;
}
if (m_AnamorphicBloomIntensities == null || m_AnamorphicBloomIntensities.Length < maxScaleCount)
{
m_AnamorphicBloomIntensities = new float[maxScaleCount];
for (int i = 0; i < 8; ++i)
m_AnamorphicBloomIntensities[i] = 1.0f;
}
if (m_AnamorphicBloomColors == null || m_AnamorphicBloomColors.Length < maxScaleCount)
{
m_AnamorphicBloomColors = new Color[maxScaleCount];
for (int i = 0; i < 8; ++i)
m_AnamorphicBloomColors[i] = Color.white;
}
if (m_AnamorphicBloomUsages == null || m_AnamorphicBloomUsages.Length < maxScaleCount )
{
m_AnamorphicBloomUsages = new bool[maxScaleCount];
for (int i = 0; i < 8; ++i)
m_AnamorphicBloomUsages[i] = true;
}
if (m_StarBloomIntensities == null || m_StarBloomIntensities.Length < maxScaleCount)
{
m_StarBloomIntensities = new float[maxScaleCount];
for (int i = 0; i < 8; ++i)
m_StarBloomIntensities[i] = 1.0f;
}
if (m_StarBloomColors == null || m_StarBloomColors.Length < maxScaleCount)
{
m_StarBloomColors = new Color[maxScaleCount];
for (int i = 0; i < 8; ++i)
m_StarBloomColors[i] = Color.white;
}
if (m_StarBloomUsages == null || m_StarBloomUsages.Length < maxScaleCount)
{
m_StarBloomUsages = new bool[maxScaleCount];
for (int i = 0; i < 8; ++i)
m_StarBloomUsages[i] = true;
}
if (m_FlareSpriteRenderer == null && m_FlareShape != null && m_UseBokehFlare)
{
if (m_FlareSpriteRenderer != null)
m_FlareSpriteRenderer.Clear(ref m_BokehMeshes);
m_FlareSpriteRenderer = new BokehRenderer();
}
if (m_SamplingMaterial == null)
{
m_DownSamples = new RenderTexture[GetNeededDownsamples()];
m_UpSamples = new RenderTexture[m_DownscaleCount];
m_AnamorphicUpscales = new RenderTexture[m_AnamorphicDownscaleCount];
m_StarUpscales = new RenderTexture[m_StarDownscaleCount];
}
string flareShaderPath = m_FlareType == FlareType.Single ? "Hidden/Ultimate/FlareSingle" : "Hidden/Ultimate/FlareDouble";
LoadShader(ref m_FlareMaterial, ref m_FlareShader, flareShaderPath);
LoadShader(ref m_SamplingMaterial, ref m_SamplingShader, "Hidden/Ultimate/Sampling");
LoadShader(ref m_BrightpassMaterial, ref m_BrightpassShader, "Hidden/Ultimate/BrightpassMask");
LoadShader(ref m_FlareMaskMaterial, ref m_FlareMaskShader, "Hidden/Ultimate/FlareMask");
LoadShader(ref m_MixerMaterial, ref m_MixerShader, "Hidden/Ultimate/BloomMixer");
LoadShader(ref m_FlareBokehMaterial, ref m_FlareBokehShader, "Hidden/Ultimate/FlareMesh");
bool useDustOrFlare = m_UseLensDust || m_UseLensFlare || m_UseAnamorphicFlare || m_UseStarFlare;
string combineShaderPath = "Hidden/Ultimate/BloomCombine";
if (useDustOrFlare)
combineShaderPath = "Hidden/Ultimate/BloomCombineFlareDirt";
LoadShader(ref m_CombineMaterial, ref m_CombineShader, combineShaderPath);
}
private Material CreateMaterial(Shader shader)
{
if (!shader)
return null;
Material m = new Material(shader);
m.hideFlags = HideFlags.HideAndDontSave;
return m;
}
void OnDisable()
{
ForceShadersReload();
if (m_FlareSpriteRenderer != null)
{
m_FlareSpriteRenderer.Clear(ref m_BokehMeshes);
m_FlareSpriteRenderer = null;
}
}
public void ForceShadersReload()
{
DestroyMaterial(m_FlareMaterial); m_FlareMaterial = null; m_FlareShader = null;
DestroyMaterial(m_SamplingMaterial); m_SamplingMaterial = null; m_SamplingShader = null;
DestroyMaterial(m_CombineMaterial); m_CombineMaterial = null; m_CombineShader = null;
DestroyMaterial(m_BrightpassMaterial); m_BrightpassMaterial = null; m_BrightpassShader = null;
DestroyMaterial(m_FlareBokehMaterial); m_FlareBokehMaterial = null; m_FlareBokehShader = null;
DestroyMaterial(m_FlareMaskMaterial); m_FlareMaskMaterial = null; m_FlareMaskShader = null;
DestroyMaterial(m_MixerMaterial); m_MixerMaterial = null; m_MixerShader = null;
}
private RenderTexture[] m_DownSamples;
private RenderTexture[] m_UpSamples;
int GetNeededDownsamples()
{
int m = Mathf.Max(m_DownscaleCount, m_UseAnamorphicFlare ? m_AnamorphicDownscaleCount : 0);
m = Mathf.Max(m, m_UseLensFlare ? GetGhostBokehLayer() + 1 : 0);
m = Mathf.Max(m, m_UseStarFlare ? m_StarDownscaleCount : 0);
return m;
}
private RenderTextureFormat m_Format;
bool[] m_BufferUsage;
void ComputeBufferOptimization()
{
if (m_BufferUsage == null)
m_BufferUsage = new bool[m_DownSamples.Length];
if (m_BufferUsage.Length != m_DownSamples.Length)
m_BufferUsage = new bool[m_DownSamples.Length];
for (int i = 0; i < m_BufferUsage.Length; ++i)
m_BufferUsage[i] = false;
for (int i = 0; i < m_BufferUsage.Length; ++i)
m_BufferUsage[i] = m_BloomUsages[i] ? true : m_BufferUsage[i];
if (m_UseAnamorphicFlare)
for (int i = 0; i < m_BufferUsage.Length; ++i)
m_BufferUsage[i] = m_AnamorphicBloomUsages[i] ? true : m_BufferUsage[i];
if (m_UseStarFlare)
for (int i = 0; i < m_BufferUsage.Length; ++i)
m_BufferUsage[i] = m_StarBloomUsages[i] ? true : m_BufferUsage[i];
}
int GetGhostBokehLayer()
{
if (m_UseBokehFlare && m_FlareShape != null)
{
if (m_BokehFlareQuality == BokehFlareQuality.VeryHigh)
return 1;
if (m_BokehFlareQuality == BokehFlareQuality.High)
return 2;
if (m_BokehFlareQuality == BokehFlareQuality.Medium)
return 3;
if (m_BokehFlareQuality == BokehFlareQuality.Low)
return 4;
}
return 0;// Ghost
}
BlurSampleCount GetUpsamplingSize()
{
if (m_SamplingMode == SamplingMode.Fixed)
{
BlurSampleCount upsamplingCount = BlurSampleCount.ThrirtyOne;
if (m_UpsamplingQuality == BloomSamplingQuality.VerySmallKernel)
upsamplingCount = BlurSampleCount.Nine;
else if (m_UpsamplingQuality == BloomSamplingQuality.SmallKernel)
upsamplingCount = BlurSampleCount.Thirteen;
else if (m_UpsamplingQuality == BloomSamplingQuality.MediumKernel)
upsamplingCount = BlurSampleCount.Seventeen;
else if (m_UpsamplingQuality == BloomSamplingQuality.LargeKernel)
upsamplingCount = BlurSampleCount.TwentyThree;
else if (m_UpsamplingQuality == BloomSamplingQuality.LargerKernel)
upsamplingCount = BlurSampleCount.TwentySeven;
return upsamplingCount;
}
float pixelCount = Screen.height;//Screen.width * Screen.height;
int nearestIdx = 0;
float nearestDist = float.MaxValue;
for (int i = 0; i < m_ResSamplingPixelCount.Length; ++i)
{
float dist = Math.Abs(pixelCount - m_ResSamplingPixelCount[i]);
if (dist < nearestDist)
{
nearestDist = dist;
nearestIdx = i;
}
}
if (nearestIdx == 0)
return BlurSampleCount.Nine;
if (nearestIdx == 1)
return BlurSampleCount.Thirteen;
if (nearestIdx == 2)
return BlurSampleCount.Seventeen;
if (nearestIdx == 3)
return BlurSampleCount.TwentyThree;
if (nearestIdx == 4)
return BlurSampleCount.TwentySeven;
return BlurSampleCount.ThrirtyOne;
}
public void ComputeResolutionRelativeData()
{
float currentRes = m_SamplingMinHeight;
float currentSampling = 9.0f;
for (int i = 0; i < m_ResSamplingPixelCount.Length; ++i)
{
m_ResSamplingPixelCount[i] = currentRes;
float nextSampling = currentSampling + 4.0f;
float ratio = nextSampling / currentSampling;
currentRes *= ratio;
currentSampling = nextSampling;
}
}
void OnRenderImage(RenderTexture source, RenderTexture destination)
{
// Determine Texture Format
bool doHdr = false;
if (m_HDR == HDRBloomMode.Auto)
doHdr = source.format == RenderTextureFormat.ARGBHalf && GetComponent<Camera>().hdr;
else
doHdr = m_HDR == HDRBloomMode.On;
m_Format = (doHdr) ? RenderTextureFormat.ARGBHalf : RenderTextureFormat.Default;
if (m_DownSamples != null)
{
if (m_DownSamples.Length != GetNeededDownsamples())
{
OnDisable();
}
}
if (m_LastDownscaleCount != m_DownscaleCount
|| m_LastAnamorphicDownscaleCount != m_AnamorphicDownscaleCount
|| m_LastStarDownscaleCount != m_StarDownscaleCount)
{
OnDisable();
}
m_LastDownscaleCount = m_DownscaleCount;
m_LastAnamorphicDownscaleCount = m_AnamorphicDownscaleCount;
m_LastStarDownscaleCount = m_StarDownscaleCount;
CreateMaterials();
if (m_DirectDownSample || m_DirectUpsample)
ComputeBufferOptimization();
bool debugFlareShape = false;
if (m_SamplingMode == SamplingMode.HeightRelative)
ComputeResolutionRelativeData();
//////////////////////////////////
// 1. Bright pass
//////////////////////////////////
RenderTexture brightTexture = RenderTexture.GetTemporary(source.width, source.height, 0, m_Format);
brightTexture.filterMode = FilterMode.Bilinear;
if (m_IntensityManagement == BloomIntensityManagement.Threshold)
BrightPass(source, brightTexture, m_BloomThreshhold * m_BloomThreshholdColor);
else
{
m_BloomCurve.UpdateCoefficients();
Graphics.Blit(source, brightTexture);
}
//////////////////////////////////
// 2. Downscale source texture
//////////////////////////////////
if (m_IntensityManagement == BloomIntensityManagement.Threshold)
CachedDownsample(brightTexture, m_DownSamples, null, doHdr);
else
CachedDownsample(brightTexture, m_DownSamples, m_BloomCurve, doHdr);
//////////////////////////////////
// 3. Upsample
//////////////////////////////////
// Upsampling quality
BlurSampleCount upsamplingCount = GetUpsamplingSize();
// Upsample
CachedUpsample(m_DownSamples, m_UpSamples, source.width, source.height, upsamplingCount);
// Release unused upsamples
/* if (m_DirectUpsample)
{
for (int i = 1; i < m_UpSamples.Length; ++i)
if (m_BufferUsage[i])
RenderTexture.ReleaseTemporary(m_UpSamples[i]);
}
else*/
//for (int i = 1; i < m_UpSamples.Length; ++i)
// RenderTexture.ReleaseTemporary(m_UpSamples[i]);
//////////////////////////////////
// Optional: Ghost lens flare
//////////////////////////////////
Texture flareRT = Texture2D.blackTexture;
RenderTexture flareShapeBuffer = null;
if (m_UseLensFlare)
{
int bokehQuality = GetGhostBokehLayer();
int flareWidth = source.width / (int)Mathf.Pow(2.0f, bokehQuality);
int flareHeigth = source.height / (int)Mathf.Pow(2.0f, bokehQuality);
if (m_FlareShape != null && m_UseBokehFlare)
{
float size = 15.0f;
if (m_BokehFlareQuality == BokehFlareQuality.Medium)
size *= 2;
if (m_BokehFlareQuality == BokehFlareQuality.High)
size *= 4;
if (m_BokehFlareQuality == BokehFlareQuality.VeryHigh)
size *= 8;
size *= m_BokehScale;
m_FlareSpriteRenderer.SetMaterial(m_FlareBokehMaterial);
m_FlareSpriteRenderer.RebuildMeshIfNeeded(flareWidth, flareHeigth, 1.0f / flareWidth * size, 1.0f / flareHeigth * size, ref m_BokehMeshes);
m_FlareSpriteRenderer.SetTexture(m_FlareShape);
flareShapeBuffer = RenderTexture.GetTemporary(source.width / 4 , source.height / 4 , 0, m_Format);
int bokehTargetSize = bokehQuality;
RenderTexture flareBrightTexture = RenderTexture.GetTemporary(source.width / (int)Mathf.Pow(2.0f, (bokehTargetSize + 1)), source.height / (int)Mathf.Pow(2.0f, (bokehTargetSize + 1)), 0, m_Format);
BrightPass(m_DownSamples[bokehQuality], flareBrightTexture, m_FlareTreshold * Vector4.one);
m_FlareSpriteRenderer.RenderFlare(flareBrightTexture, flareShapeBuffer, m_UseBokehFlare ? 1.0f : m_FlareIntensity, ref m_BokehMeshes);
RenderTexture.ReleaseTemporary(flareBrightTexture);
RenderTexture maskFlare = RenderTexture.GetTemporary(flareShapeBuffer.width, flareShapeBuffer.height, 0, m_Format);
m_FlareMaskMaterial.SetTexture("_MaskTex", m_FlareMask);
Graphics.Blit(flareShapeBuffer, maskFlare, m_FlareMaskMaterial, 0);
RenderTexture.ReleaseTemporary(flareShapeBuffer); flareShapeBuffer = null;
RenderFlares(maskFlare, source, ref flareRT);
RenderTexture.ReleaseTemporary(maskFlare);
}
else
{
//BrightPassWithMask(source, brightTexture, m_FlareTreshold * Vector4.one, m_FlareMask);
//RenderFlares( brightTexture, source, ref flareRT);
int ghostLayer = GetGhostBokehLayer();
RenderTexture flareSource = m_DownSamples[ghostLayer];
RenderTexture flareBrightTexture = RenderTexture.GetTemporary(flareSource.width, flareSource.height, 0, m_Format);
BrightPassWithMask(m_DownSamples[ghostLayer], flareBrightTexture, m_FlareTreshold * Vector4.one, m_FlareMask);
RenderFlares(flareBrightTexture, source, ref flareRT);
RenderTexture.ReleaseTemporary(flareBrightTexture);
}
}
if (!m_UseLensFlare && m_FlareSpriteRenderer != null)
m_FlareSpriteRenderer.Clear(ref m_BokehMeshes);
//////////////////////////////////
// Optional: Anamorphic lens flare
//////////////////////////////////
if (m_UseAnamorphicFlare)
{
RenderTexture anamorphicResult = RenderStripe(m_DownSamples, upsamplingCount, source.width, source.height, FlareStripeType.Anamorphic);
if (anamorphicResult != null)
{
if (m_UseLensFlare)
{
RenderTextureAdditive(anamorphicResult, (RenderTexture)flareRT, 1.0f);
RenderTexture.ReleaseTemporary(anamorphicResult);
}
else
{
flareRT = anamorphicResult;
}
}
}
//////////////////////////////////
// Optional: Star lens flare
//////////////////////////////////
if (m_UseStarFlare)
{
//RenderTexture starResult = RenderStar(m_DownSamples, upsamplingCount, source.width, source.height);
RenderTexture starResult = null;
if (m_StarBlurPass == 1)
{
starResult = RenderStripe(m_DownSamples, upsamplingCount, source.width, source.height, FlareStripeType.Star);
if (starResult != null)
{
if (m_UseLensFlare || m_UseAnamorphicFlare)
{
RenderTextureAdditive(starResult, (RenderTexture)flareRT, m_StarFlareIntensity);
}
else
{
flareRT = RenderTexture.GetTemporary(source.width, source.height, 0, m_Format);
BlitIntensity(starResult, (RenderTexture)flareRT, m_StarFlareIntensity);
}
RenderTexture.ReleaseTemporary(starResult);
}
}
else
{
if (m_UseLensFlare || m_UseAnamorphicFlare)
{
starResult = RenderStripe(m_DownSamples, upsamplingCount, source.width, source.height, FlareStripeType.DiagonalUpright);
if (starResult != null)
{
RenderTextureAdditive(starResult, (RenderTexture)flareRT, m_StarFlareIntensity);
RenderTexture.ReleaseTemporary(starResult);
starResult = RenderStripe(m_DownSamples, upsamplingCount, source.width, source.height, FlareStripeType.DiagonalUpleft);
RenderTextureAdditive(starResult, (RenderTexture)flareRT, m_StarFlareIntensity);
RenderTexture.ReleaseTemporary(starResult);
}
}
else
{
starResult = RenderStripe(m_DownSamples, upsamplingCount, source.width, source.height, FlareStripeType.DiagonalUpleft);
if (starResult != null)
{
RenderTexture tmpStarResult = RenderStripe(m_DownSamples, upsamplingCount, source.width, source.height, FlareStripeType.DiagonalUpright);
CombineAdditive(tmpStarResult, starResult, m_StarFlareIntensity, m_StarFlareIntensity);
RenderTexture.ReleaseTemporary(tmpStarResult);
flareRT = starResult;
}
}
}
}
// Release downsamples
if (m_DirectDownSample)
for (int i = 0; i < m_DownSamples.Length; ++i)
{
if (m_BufferUsage[i])
RenderTexture.ReleaseTemporary(m_DownSamples[i]);
}
else
for (int i = 0; i < m_DownSamples.Length; ++i)
RenderTexture.ReleaseTemporary(m_DownSamples[i]);
//////////////////////////////////
// Combine pass
//////////////////////////////////
m_CombineMaterial.SetFloat("_Intensity", m_BloomIntensity);
m_CombineMaterial.SetFloat("_FlareIntensity", m_FlareIntensity);
m_CombineMaterial.SetTexture("_ColorBuffer", source);
m_CombineMaterial.SetTexture("_FlareTexture", flareRT);
m_CombineMaterial.SetTexture("_AdditiveTexture", m_UseLensDust ? m_DustTexture : Texture2D.whiteTexture);
m_CombineMaterial.SetTexture("_brightTexture", brightTexture);
if (m_UseLensDust)
{
m_CombineMaterial.SetFloat("_DirtIntensity", m_DustIntensity);
m_CombineMaterial.SetFloat("_DirtLightIntensity", m_DirtLightIntensity);
}
else
{
m_CombineMaterial.SetFloat("_DirtIntensity", 1.0f);
m_CombineMaterial.SetFloat("_DirtLightIntensity", 0.0f);
}
if (m_BlendMode == BlendMode.SCREEN)
{
m_CombineMaterial.SetFloat("_ScreenMaxIntensity", m_ScreenMaxIntensity);
}
if (m_InvertImage)
Graphics.Blit(m_LastBloomUpsample, destination, m_CombineMaterial, 1);
else
Graphics.Blit(m_LastBloomUpsample, destination, m_CombineMaterial, 0);
for (int i = 0; i < m_UpSamples.Length; ++i)
if (m_UpSamples[i] != null)
RenderTexture.ReleaseTemporary(m_UpSamples[i]);
//Graphics.Blit(m_UpSamples[0], destination);
//////////////////////////////////
// Cleaning
//////////////////////////////////
if (debugFlareShape)
Graphics.Blit(flareShapeBuffer, destination);
if (m_UseLensFlare || m_UseAnamorphicFlare || m_UseStarFlare)
if (flareRT != null && flareRT is RenderTexture)
RenderTexture.ReleaseTemporary((RenderTexture)flareRT);
RenderTexture.ReleaseTemporary(brightTexture);
if (m_FlareShape != null && m_UseBokehFlare && flareShapeBuffer != null)
{
RenderTexture.ReleaseTemporary(flareShapeBuffer);
}
}
RenderTexture RenderStar(RenderTexture[] sources, BlurSampleCount upsamplingCount, int sourceWidth, int sourceHeight)
{
for (int i = m_StarUpscales.Length - 1; i >= 0; --i)
{
m_StarUpscales[i] = RenderTexture.GetTemporary(sourceWidth / (int)Mathf.Pow(2.0f, i), sourceHeight / (int)Mathf.Pow(2.0f, i), 0, m_Format);
m_StarUpscales[i].filterMode = FilterMode.Bilinear;
float horizontalBlur = 1.0f / sources[i].width;
float verticalBlur = 1.0f / sources[i].height;
if (i < m_StarDownscaleCount - 1)
GaussianBlur2(sources[i], m_StarUpscales[i], horizontalBlur * m_StarScale, verticalBlur * m_StarScale, m_StarUpscales[i + 1], upsamplingCount, Color.white, 1.0f);
else
GaussianBlur2(sources[i], m_StarUpscales[i], horizontalBlur * m_StarScale, verticalBlur * m_StarScale, null, upsamplingCount, Color.white, 1.0f);
}
for (int i = 1; i < m_StarUpscales.Length; ++i)
if (m_StarUpscales[i] != null)
RenderTexture.ReleaseTemporary(m_StarUpscales[i]);
return m_StarUpscales[0];
}
delegate void BlurFunction(RenderTexture source, RenderTexture destination, float horizontalBlur, float verticalBlur, RenderTexture additiveTexture, BlurSampleCount sampleCount, Color tint, float intensity);
RenderTexture RenderStripe(RenderTexture[] sources, BlurSampleCount upsamplingCount, int sourceWidth, int sourceHeight, FlareStripeType type)
{
//BlurFunction blur = GaussianBlur1;
//int nbUpscales = m_AnamorphicUpscales.Length;
RenderTexture[] upscales = m_AnamorphicUpscales;
bool[] usages = m_AnamorphicBloomUsages;
float[] intensities = m_AnamorphicBloomIntensities;
Color[] tints = m_AnamorphicBloomColors;
bool antiJitter = m_AnamorphicSmallVerticalBlur;
float blurPass = m_AnamorphicBlurPass;
float scale = m_AnamorphicScale;
float globalIntensity = m_AnamorphicFlareIntensity;
float horiMul = 1.0f;
float vertiMul = 0.0f;
if (m_AnamorphicDirection == AnamorphicDirection.Vertical)
{
horiMul = 0.0f;
vertiMul = 1.0f;
}
if (type != FlareStripeType.Anamorphic)
{
// if (type == FlareStripeType.Star)
// blur = GaussianBlur2;
//nbUpscales = m_StarUpscales.Length;
upscales = m_StarUpscales;
usages = m_StarBloomUsages;
intensities = m_StarBloomIntensities;
tints = m_StarBloomColors;
antiJitter = false;
blurPass = m_StarBlurPass;
scale = m_StarScale;
globalIntensity = m_StarFlareIntensity;
if (type == FlareStripeType.DiagonalUpleft)
vertiMul = -1.0f;
else
vertiMul = 1.0f;
}
for (int i = 0; i < upscales.Length; ++i)
upscales[i] = null;
RenderTexture additiveTexture = null;
for (int i = upscales.Length - 1; i >= 0; --i)
{
if (sources[i] == null && m_DirectUpsample)
continue;
if (!usages[i] && m_DirectUpsample)
continue;
upscales[i] = RenderTexture.GetTemporary(sourceWidth / (int)Mathf.Pow(2.0f, i), sourceHeight / (int)Mathf.Pow(2.0f, i), 0, m_Format);
upscales[i].filterMode = FilterMode.Bilinear;
float horizontalBlur = 1.0f / upscales[i].width;
float verticalBlur = 1.0f / upscales[i].height;
RenderTexture source = sources[i];
RenderTexture dest = upscales[i];
if (!usages[i])
{
if (additiveTexture != null)
{
if (antiJitter)
GaussianBlur1(additiveTexture, dest, m_AnamorphicDirection == AnamorphicDirection.Vertical ? horizontalBlur : 0.0f, m_AnamorphicDirection == AnamorphicDirection.Horizontal ? verticalBlur : 0.0f, null, BlurSampleCount.FourSimple, Color.white, 1.0f);
else
Graphics.Blit(additiveTexture, dest);
}
else
Graphics.Blit(Texture2D.blackTexture, dest);
additiveTexture = upscales[i];
continue;
}
RenderTexture antiJitterBuffer = null;
if (antiJitter && additiveTexture != null)
{
antiJitterBuffer = RenderTexture.GetTemporary(dest.width, dest.height, 0, m_Format);
GaussianBlur1(additiveTexture, antiJitterBuffer, m_AnamorphicDirection == AnamorphicDirection.Vertical ? horizontalBlur : 0.0f, m_AnamorphicDirection == AnamorphicDirection.Horizontal ? verticalBlur : 0.0f, null, BlurSampleCount.FourSimple, Color.white, 1.0f);
additiveTexture = antiJitterBuffer;
}
if (blurPass == 1)
{
if (type != FlareStripeType.Anamorphic)
GaussianBlur2(source, dest, horizontalBlur * scale * horiMul, verticalBlur * scale * vertiMul, additiveTexture, upsamplingCount, tints[i], intensities[i] * globalIntensity);
else
GaussianBlur1(source, dest, horizontalBlur * scale * horiMul, verticalBlur * scale * vertiMul, additiveTexture, upsamplingCount, tints[i], intensities[i] * globalIntensity);
}
else
{
RenderTexture tmp = RenderTexture.GetTemporary(dest.width, dest.height, 0, m_Format);
bool lastTargetIsTmp = false;
for (int j = 0; j < blurPass; ++j)
{
RenderTexture finalAdditiveTexture = (j == blurPass - 1) ? additiveTexture : null;
if (j == 0)
{
if (type != FlareStripeType.Anamorphic)
GaussianBlur2(source, tmp, horizontalBlur * scale * horiMul, verticalBlur * scale * vertiMul, finalAdditiveTexture, upsamplingCount, tints[i], intensities[i] * globalIntensity);
else
GaussianBlur1(source, tmp, horizontalBlur * scale * horiMul, verticalBlur * scale * vertiMul, finalAdditiveTexture, upsamplingCount, tints[i], intensities[i] * globalIntensity);
}
else
{
horizontalBlur = 1.0f / dest.width;
verticalBlur = 1.0f / dest.height;
if (j % 2 == 1)
{
if (type != FlareStripeType.Anamorphic)
GaussianBlur2(tmp, dest, horizontalBlur * scale * horiMul * 1.5f, verticalBlur * scale * vertiMul * 1.5f, finalAdditiveTexture, upsamplingCount, tints[i], intensities[i] * globalIntensity);
else
GaussianBlur1(tmp, dest, horizontalBlur * scale * horiMul * 1.5f, verticalBlur * scale * vertiMul * 1.5f, finalAdditiveTexture, upsamplingCount, tints[i], intensities[i] * globalIntensity);
lastTargetIsTmp = false;
}
else
{
if (type != FlareStripeType.Anamorphic)
GaussianBlur2(dest, tmp, horizontalBlur * scale * horiMul * 1.5f, verticalBlur * scale * vertiMul * 1.5f, finalAdditiveTexture, upsamplingCount, tints[i], intensities[i] * globalIntensity);
else
GaussianBlur1(dest, tmp, horizontalBlur * scale * horiMul * 1.5f, verticalBlur * scale * vertiMul * 1.5f, finalAdditiveTexture, upsamplingCount, tints[i], intensities[i] * globalIntensity);
lastTargetIsTmp = true;
}
}
}
if (lastTargetIsTmp)
Graphics.Blit(tmp, dest);
if (antiJitterBuffer != null)
RenderTexture.ReleaseTemporary(antiJitterBuffer);
RenderTexture.ReleaseTemporary(tmp);
}
additiveTexture = upscales[i];
}
RenderTexture firstFound = null;
for (int i = 0; i < upscales.Length; ++i)
if (upscales[i] != null)
if (firstFound == null) firstFound = upscales[i];
else RenderTexture.ReleaseTemporary(upscales[i]);
return firstFound;
}
void RenderFlares(RenderTexture brightTexture, RenderTexture source,ref Texture flareRT)
{
flareRT = RenderTexture.GetTemporary(source.width, source.height, 0, m_Format);
flareRT.filterMode = FilterMode.Bilinear;
m_FlareMaterial.SetVector("_FlareScales", m_FlareScales * m_FlareGlobalScale);
m_FlareMaterial.SetVector("_FlareScalesNear", m_FlareScalesNear * m_FlareGlobalScale);
m_FlareMaterial.SetVector("_FlareTint0", m_FlareTint0);
m_FlareMaterial.SetVector("_FlareTint1", m_FlareTint1);
m_FlareMaterial.SetVector("_FlareTint2", m_FlareTint2);
m_FlareMaterial.SetVector("_FlareTint3", m_FlareTint3);
m_FlareMaterial.SetVector("_FlareTint4", m_FlareTint4);
m_FlareMaterial.SetVector("_FlareTint5", m_FlareTint5);
m_FlareMaterial.SetVector("_FlareTint6", m_FlareTint6);
m_FlareMaterial.SetVector("_FlareTint7", m_FlareTint7);
m_FlareMaterial.SetFloat("_Intensity", m_FlareIntensity);
//Graphics.Blit(brightTexture, (RenderTexture)flareRT, m_BloomMaterial, 8);
if (m_FlareRendering == FlareRendering.Sharp)
{
RenderTexture HalfTmp = RenderTexture.GetTemporary(source.width / 2, source.height / 2, 0, m_Format);
HalfTmp.filterMode = FilterMode.Bilinear;
RenderSimple(brightTexture, HalfTmp, 1.0f / brightTexture.width, 1.0f / brightTexture.height, SimpleSampleCount.Four);
Graphics.Blit(HalfTmp, (RenderTexture)flareRT, m_FlareMaterial, 0);
RenderTexture.ReleaseTemporary(HalfTmp);
return;
}
// Blur flare
if (m_FlareBlurQuality == FlareBlurQuality.Fast)
{
RenderTexture HalfFlareRT = RenderTexture.GetTemporary(brightTexture.width / 2, brightTexture.height / 2, 0, m_Format);
HalfFlareRT.filterMode = FilterMode.Bilinear;
RenderTexture QuarterFlareRT = RenderTexture.GetTemporary(brightTexture.width / 4, brightTexture.height / 4, 0, m_Format);
QuarterFlareRT.filterMode = FilterMode.Bilinear;
Graphics.Blit(brightTexture, HalfFlareRT, m_FlareMaterial, 0);
if (m_FlareRendering == FlareRendering.Blurred)
{
GaussianBlurSeparate(HalfFlareRT, (RenderTexture)QuarterFlareRT, 1.0f / HalfFlareRT.width, 1.0f / HalfFlareRT.height, null, BlurSampleCount.Thirteen, Color.white, 1.0f);
RenderSimple(QuarterFlareRT, (RenderTexture)flareRT, 1.0f / QuarterFlareRT.width, 1.0f / QuarterFlareRT.height, SimpleSampleCount.Four);
}
else if (m_FlareRendering == FlareRendering.MoreBlurred)
{
GaussianBlurSeparate(HalfFlareRT, (RenderTexture)QuarterFlareRT, 1.0f / HalfFlareRT.width, 1.0f / HalfFlareRT.height, null, BlurSampleCount.ThrirtyOne, Color.white, 1.0f);
RenderSimple(QuarterFlareRT, (RenderTexture)flareRT, 1.0f / QuarterFlareRT.width, 1.0f / QuarterFlareRT.height, SimpleSampleCount.Four);
}
RenderTexture.ReleaseTemporary(HalfFlareRT);
RenderTexture.ReleaseTemporary(QuarterFlareRT);
return;
}
else if (m_FlareBlurQuality == FlareBlurQuality.Normal)
{
RenderTexture HalfFlareRT = RenderTexture.GetTemporary(brightTexture.width / 2, brightTexture.height / 2, 0, m_Format);
HalfFlareRT.filterMode = FilterMode.Bilinear;
RenderTexture QuarterFlareRT = RenderTexture.GetTemporary(brightTexture.width / 4, brightTexture.height / 4, 0, m_Format);
QuarterFlareRT.filterMode = FilterMode.Bilinear;
RenderTexture QuarterFlareRT2 = RenderTexture.GetTemporary(brightTexture.width / 4, brightTexture.height / 4, 0, m_Format);
QuarterFlareRT2.filterMode = FilterMode.Bilinear;
RenderSimple(brightTexture, HalfFlareRT, 1.0f / brightTexture.width, 1.0f / brightTexture.height, SimpleSampleCount.Four);
RenderSimple(HalfFlareRT, QuarterFlareRT, 1.0f / HalfFlareRT.width, 1.0f / HalfFlareRT.height, SimpleSampleCount.Four);
Graphics.Blit(QuarterFlareRT, QuarterFlareRT2, m_FlareMaterial, 0);
if (m_FlareRendering == FlareRendering.Blurred)
{
GaussianBlurSeparate(QuarterFlareRT2, (RenderTexture)QuarterFlareRT, 1.0f / QuarterFlareRT.width, 1.0f / QuarterFlareRT.height, null, BlurSampleCount.Thirteen, Color.white, 1.0f);
RenderSimple(QuarterFlareRT, (RenderTexture)flareRT, 1.0f / QuarterFlareRT.width, 1.0f / QuarterFlareRT.height, SimpleSampleCount.Four);
}
else if (m_FlareRendering == FlareRendering.MoreBlurred)
{
GaussianBlurSeparate(QuarterFlareRT2, (RenderTexture)QuarterFlareRT, 1.0f / QuarterFlareRT.width, 1.0f / QuarterFlareRT.height, null, BlurSampleCount.ThrirtyOne, Color.white, 1.0f);
RenderSimple(QuarterFlareRT, (RenderTexture)flareRT, 1.0f / QuarterFlareRT.width, 1.0f / QuarterFlareRT.height, SimpleSampleCount.Four);
}
RenderTexture.ReleaseTemporary(HalfFlareRT);
RenderTexture.ReleaseTemporary(QuarterFlareRT);
RenderTexture.ReleaseTemporary(QuarterFlareRT2);
}
else if (m_FlareBlurQuality == FlareBlurQuality.High)
{
RenderTexture HalfFlareRT = RenderTexture.GetTemporary(brightTexture.width / 2, brightTexture.height / 2, 0, m_Format);
HalfFlareRT.filterMode = FilterMode.Bilinear;
RenderTexture QuarterFlareRT = RenderTexture.GetTemporary(HalfFlareRT.width / 2, HalfFlareRT.height / 2, 0, m_Format);
QuarterFlareRT.filterMode = FilterMode.Bilinear;
RenderTexture HFlareRT1 = RenderTexture.GetTemporary(QuarterFlareRT.width / 2, QuarterFlareRT.height / 2, 0, m_Format);
HFlareRT1.filterMode = FilterMode.Bilinear;
RenderTexture HFlareRT2 = RenderTexture.GetTemporary(QuarterFlareRT.width / 2, QuarterFlareRT.height / 2, 0, m_Format);
HFlareRT2.filterMode = FilterMode.Bilinear;
RenderSimple(brightTexture, HalfFlareRT, 1.0f / brightTexture.width, 1.0f / brightTexture.height, SimpleSampleCount.Four);
RenderSimple(HalfFlareRT, QuarterFlareRT, 1.0f / HalfFlareRT.width, 1.0f / HalfFlareRT.height, SimpleSampleCount.Four);
RenderSimple(QuarterFlareRT, HFlareRT1, 1.0f / QuarterFlareRT.width, 1.0f / QuarterFlareRT.height, SimpleSampleCount.Four);
Graphics.Blit(HFlareRT1, HFlareRT2, m_FlareMaterial, 0);
if (m_FlareRendering == FlareRendering.Blurred)
{
GaussianBlurSeparate(HFlareRT2, (RenderTexture)HFlareRT1, 1.0f / HFlareRT1.width, 1.0f / HFlareRT1.height, null, BlurSampleCount.Thirteen, Color.white, 1.0f);
RenderSimple(HFlareRT1, (RenderTexture)flareRT, 1.0f / HFlareRT1.width, 1.0f / HFlareRT1.height, SimpleSampleCount.Four);
}
else if (m_FlareRendering == FlareRendering.MoreBlurred)
{
GaussianBlurSeparate(HFlareRT2, (RenderTexture)HFlareRT1, 1.0f / HFlareRT1.width, 1.0f / HFlareRT1.height, null, BlurSampleCount.ThrirtyOne, Color.white, 1.0f);
RenderSimple(HFlareRT1, (RenderTexture)flareRT, 1.0f / HFlareRT1.width, 1.0f / HFlareRT1.height, SimpleSampleCount.Four);
}
RenderTexture.ReleaseTemporary(HalfFlareRT);
RenderTexture.ReleaseTemporary(QuarterFlareRT);
RenderTexture.ReleaseTemporary(HFlareRT1);
RenderTexture.ReleaseTemporary(HFlareRT2);
}
}
RenderTexture m_LastBloomUpsample;
void CachedUpsample(RenderTexture[] sources, RenderTexture[] destinations, int originalWidth, int originalHeight, BlurSampleCount upsamplingCount)
{
RenderTexture lastUpsample = null;
for (int i = 0; i < m_UpSamples.Length; ++i)
m_UpSamples[i] = null;
for (int i = destinations.Length - 1; i >= 0; --i)
{
if (m_BloomUsages[i] || !m_DirectUpsample)
{
m_UpSamples[i] = RenderTexture.GetTemporary(originalWidth / (int)Mathf.Pow(2.0f, i), originalHeight / (int)Mathf.Pow(2.0f, i), 0, m_Format);
m_UpSamples[i].filterMode = FilterMode.Bilinear;
}
float mul = 1.0f;
if (m_BloomUsages[i])
{
float horizontalBlur = 1.0f / sources[i].width;
float verticalBlur = 1.0f / sources[i].height;
GaussianBlurSeparate(m_DownSamples[i], m_UpSamples[i], horizontalBlur * mul, verticalBlur, lastUpsample, upsamplingCount, m_BloomColors[i], m_BloomIntensities[i]);
}
else
{
if (i < m_DownscaleCount - 1)
{
if (!m_DirectUpsample)
RenderSimple(lastUpsample, m_UpSamples[i], 1.0f / m_UpSamples[i].width, 1.0f / m_UpSamples[i].height, SimpleSampleCount.Four);
//Graphics.Blit(m_UpSamples[i + 1], m_UpSamples[i]);
}
else
Graphics.Blit(Texture2D.blackTexture, m_UpSamples[i]);
}
if (m_BloomUsages[i] || !m_DirectUpsample)
lastUpsample = m_UpSamples[i];
}
m_LastBloomUpsample = lastUpsample;
}
void CachedDownsample(RenderTexture source, RenderTexture[] destinations, DeluxeFilmicCurve intensityCurve, bool hdr)
{
int downscaleCount = destinations.Length;
RenderTexture currentSource = source;
bool filmicCurveDone = false;
for (int i = 0; i < downscaleCount; ++i)
{
if (m_DirectDownSample)
{
if (!m_BufferUsage[i])
continue;
}
destinations[i] = RenderTexture.GetTemporary(source.width / (int)Mathf.Pow(2.0f, (i + 1)), source.height / (int)Mathf.Pow(2.0f, (i + 1)), 0, m_Format);
destinations[i].filterMode = FilterMode.Bilinear;
RenderTexture dest = destinations[i];
float dist = 1.0f;
float horizontalBlur = 1.0f / currentSource.width;
float verticalBlur = 1.0f / currentSource.height;
// Render previous into next
{
if (intensityCurve != null && !filmicCurveDone)
{
intensityCurve.StoreK();
m_SamplingMaterial.SetFloat("_CurveExposure", intensityCurve.GetExposure());
m_SamplingMaterial.SetFloat("_K", intensityCurve.m_k);
m_SamplingMaterial.SetFloat("_Crossover", intensityCurve.m_CrossOverPoint);
m_SamplingMaterial.SetVector("_Toe", intensityCurve.m_ToeCoef);
m_SamplingMaterial.SetVector("_Shoulder", intensityCurve.m_ShoulderCoef);
// m_SamplingMaterial.SetFloat("_MaxValue", intensityCurve.m_WhitePoint);
float colorRange = hdr ? 2.0f : 1.0f;
m_SamplingMaterial.SetFloat("_MaxValue", colorRange);
horizontalBlur = 1.0f / currentSource.width;
verticalBlur = 1.0f / currentSource.height;
if (m_TemporalStableDownsampling)
RenderSimple(currentSource, dest, horizontalBlur * dist, verticalBlur * dist, SimpleSampleCount.ThirteenTemporalCurve);
else
RenderSimple(currentSource, dest, horizontalBlur * dist, verticalBlur * dist, SimpleSampleCount.FourCurve);
filmicCurveDone = true;
}
else
{
if (m_TemporalStableDownsampling)
RenderSimple(currentSource, dest, horizontalBlur * dist, verticalBlur * dist, SimpleSampleCount.ThirteenTemporal);
else
RenderSimple(currentSource, dest, horizontalBlur * dist, verticalBlur * dist, SimpleSampleCount.Four);
}
}
currentSource = destinations[i];
}
}
void BrightPass(RenderTexture source, RenderTexture destination, Vector4 treshold)
{
m_BrightpassMaterial.SetTexture("_MaskTex", Texture2D.whiteTexture);
m_BrightpassMaterial.SetVector("_Threshhold", treshold);
Graphics.Blit(source, destination, m_BrightpassMaterial, 0);
}
void BrightPassWithMask(RenderTexture source, RenderTexture destination, Vector4 treshold, Texture mask)
{
m_BrightpassMaterial.SetTexture("_MaskTex", mask);
m_BrightpassMaterial.SetVector("_Threshhold", treshold);
Graphics.Blit(source, destination, m_BrightpassMaterial, 0);
}
void RenderSimple(RenderTexture source, RenderTexture destination, float horizontalBlur, float verticalBlur, SimpleSampleCount sampleCount)
{
m_SamplingMaterial.SetVector("_OffsetInfos", new Vector4(horizontalBlur, verticalBlur, 0, 0));
if (sampleCount == SimpleSampleCount.Four)
Graphics.Blit(source, destination, m_SamplingMaterial, 0);
else if (sampleCount == SimpleSampleCount.Nine)
Graphics.Blit(source, destination, m_SamplingMaterial, 1);
else if (sampleCount == SimpleSampleCount.FourCurve)
Graphics.Blit(source, destination, m_SamplingMaterial, 5);
else if (sampleCount == SimpleSampleCount.ThirteenTemporal)
Graphics.Blit(source, destination, m_SamplingMaterial, 11);
else if (sampleCount == SimpleSampleCount.ThirteenTemporalCurve)
Graphics.Blit(source, destination, m_SamplingMaterial, 12);
}
void GaussianBlur1(RenderTexture source, RenderTexture destination, float horizontalBlur, float verticalBlur, RenderTexture additiveTexture, BlurSampleCount sampleCount, Color tint, float intensity)
{
int passFromSamples = 2;
if (sampleCount == BlurSampleCount.Seventeen)
passFromSamples = 3;
if (sampleCount == BlurSampleCount.Nine)
passFromSamples = 4;
if (sampleCount == BlurSampleCount.NineCurve)
passFromSamples = 6;
if (sampleCount == BlurSampleCount.FourSimple)
passFromSamples = 7;
if (sampleCount == BlurSampleCount.Thirteen)
passFromSamples = 8;
if (sampleCount == BlurSampleCount.TwentyThree)
passFromSamples = 9;
if (sampleCount == BlurSampleCount.TwentySeven)
passFromSamples = 10;
Texture additiveColor = null;
if (additiveTexture == null)
additiveColor = Texture2D.blackTexture;
else
additiveColor = additiveTexture;
m_SamplingMaterial.SetTexture("_AdditiveTexture", additiveColor);
m_SamplingMaterial.SetVector("_OffsetInfos", new Vector4(horizontalBlur, verticalBlur, 0, 0));
m_SamplingMaterial.SetVector("_Tint", tint);
m_SamplingMaterial.SetFloat("_Intensity", intensity);
Graphics.Blit(source, destination, m_SamplingMaterial, passFromSamples);
}
void GaussianBlur2(RenderTexture source, RenderTexture destination, float horizontalBlur, float verticalBlur, RenderTexture additiveTexture, BlurSampleCount sampleCount, Color tint, float intensity)
{
RenderTexture tmpTexture = RenderTexture.GetTemporary(destination.width, destination.height, destination.depth, destination.format);
tmpTexture.filterMode = FilterMode.Bilinear;
int passFromSamples = 2;
if (sampleCount == BlurSampleCount.Seventeen)
passFromSamples = 3;
if (sampleCount == BlurSampleCount.Nine)
passFromSamples = 4;
if (sampleCount == BlurSampleCount.NineCurve)
passFromSamples = 6;
if (sampleCount == BlurSampleCount.FourSimple)
passFromSamples = 7;
if (sampleCount == BlurSampleCount.Thirteen)
passFromSamples = 8;
if (sampleCount == BlurSampleCount.TwentyThree)
passFromSamples = 9;
if (sampleCount == BlurSampleCount.TwentySeven)
passFromSamples = 10;
Texture additiveColor = null;
if (additiveTexture == null)
additiveColor = Texture2D.blackTexture;
else
additiveColor = additiveTexture;
// First pass
m_SamplingMaterial.SetTexture("_AdditiveTexture", additiveColor);
m_SamplingMaterial.SetVector("_OffsetInfos", new Vector4(horizontalBlur, verticalBlur, 0, 0));
m_SamplingMaterial.SetVector("_Tint", tint);
m_SamplingMaterial.SetFloat("_Intensity", intensity);
Graphics.Blit(source, tmpTexture, m_SamplingMaterial, passFromSamples);
additiveColor = tmpTexture;
// Second pass
m_SamplingMaterial.SetTexture("_AdditiveTexture", additiveColor);
m_SamplingMaterial.SetVector("_OffsetInfos", new Vector4(-horizontalBlur, verticalBlur, 0, 0));
m_SamplingMaterial.SetVector("_Tint", tint);
m_SamplingMaterial.SetFloat("_Intensity", intensity);
Graphics.Blit(source, destination, m_SamplingMaterial, passFromSamples);
RenderTexture.ReleaseTemporary(tmpTexture);
}
void GaussianBlurSeparate(RenderTexture source, RenderTexture destination, float horizontalBlur, float verticalBlur, RenderTexture additiveTexture, BlurSampleCount sampleCount, Color tint, float intensity)
{
RenderTexture tmpTexture = RenderTexture.GetTemporary(destination.width, destination.height, destination.depth, destination.format);
tmpTexture.filterMode = FilterMode.Bilinear;
int passFromSamples = 2;
if (sampleCount == BlurSampleCount.Seventeen)
passFromSamples = 3;
if (sampleCount == BlurSampleCount.Nine)
passFromSamples = 4;
if (sampleCount == BlurSampleCount.NineCurve)
passFromSamples = 6;
if (sampleCount == BlurSampleCount.FourSimple)
passFromSamples = 7;
if (sampleCount == BlurSampleCount.Thirteen)
passFromSamples = 8;
if (sampleCount == BlurSampleCount.TwentyThree)
passFromSamples = 9;
if (sampleCount == BlurSampleCount.TwentySeven)
passFromSamples = 10;
// Vertical
m_SamplingMaterial.SetTexture("_AdditiveTexture", Texture2D.blackTexture);
m_SamplingMaterial.SetVector("_OffsetInfos", new Vector4(0.0f, verticalBlur, 0, 0));
m_SamplingMaterial.SetVector("_Tint", tint);
m_SamplingMaterial.SetFloat("_Intensity", intensity);
Graphics.Blit(source, tmpTexture, m_SamplingMaterial, passFromSamples);
Texture additiveColor = null;
if (additiveTexture == null)
additiveColor = Texture2D.blackTexture;
else
additiveColor = additiveTexture;
// Horizontal
m_SamplingMaterial.SetTexture("_AdditiveTexture", additiveColor);
m_SamplingMaterial.SetVector("_OffsetInfos", new Vector4(horizontalBlur, 0.0f, 1.0f / destination.width, 1.0f / destination.height));
m_SamplingMaterial.SetVector("_Tint", Color.white);
m_SamplingMaterial.SetFloat("_Intensity", 1.0f);
Graphics.Blit(tmpTexture, destination, m_SamplingMaterial, passFromSamples);
RenderTexture.ReleaseTemporary(tmpTexture);
}
void RenderTextureAdditive(RenderTexture source, RenderTexture destination, float intensity)
{
RenderTexture tmpTexture = RenderTexture.GetTemporary(source.width, source.height, source.depth, source.format);
Graphics.Blit(destination, tmpTexture);
m_MixerMaterial.SetTexture("_ColorBuffer", tmpTexture);
m_MixerMaterial.SetFloat("_Intensity", intensity);
Graphics.Blit(source, destination, m_MixerMaterial, 0);
RenderTexture.ReleaseTemporary(tmpTexture);
}
void BlitIntensity(RenderTexture source, RenderTexture destination, float intensity)
{
m_MixerMaterial.SetFloat("_Intensity", intensity);
Graphics.Blit(source, destination, m_MixerMaterial, 2);
}
void CombineAdditive(RenderTexture source, RenderTexture destination, float intensitySource, float intensityDestination)
{
RenderTexture tmpTexture = RenderTexture.GetTemporary(source.width, source.height, source.depth, source.format);
Graphics.Blit(destination, tmpTexture);
m_MixerMaterial.SetTexture("_ColorBuffer", tmpTexture);
m_MixerMaterial.SetFloat("_Intensity0", intensitySource);
m_MixerMaterial.SetFloat("_Intensity1", intensityDestination);
Graphics.Blit(source, destination, m_MixerMaterial, 1);
RenderTexture.ReleaseTemporary(tmpTexture);
}
public void SetFilmicCurveParameters(float middle, float dark, float bright, float highlights)
{
m_BloomCurve.m_ToeStrength = -1.0f * dark;
m_BloomCurve.m_ShoulderStrength = bright;
m_BloomCurve.m_Highlights = highlights;
m_BloomCurve.m_CrossOverPoint = middle;
m_BloomCurve.UpdateCoefficients();
}
/* float Gaussian(float Scale, int iSamplePoint)
{
float sigma = (Scale - 1.0f) / 6.5f;
float g = 1.0f / Mathf.Sqrt(2.0f * 3.14159f * sigma * sigma);
return (g * Mathf.Exp(-(iSamplePoint * iSamplePoint) / (2 * sigma * sigma)));
}
void Start()
{
int count = 16;
float scale = 31;
float sum = 0.0f;
float[] weights = new float[count];
for (int i = 0; i < count; ++i)
{
weights[i] = Gaussian(scale, i);
sum += weights[i];
}
string str = "";
for (int i = 0; i < count; ++i)
{
float nWeight = weights[i] / sum;
if (i == 0)
{
str += "color += " + nWeight + " * tex2D (_MainTex, gUV);\n";
}
else
{
str += "color += " + nWeight + " * tex2D (_MainTex, gUV + _OffsetInfos.xy * " + i + ");\n";
str += "color += " + nWeight + " * tex2D (_MainTex, gUV - _OffsetInfos.xy * " + i + ");\n";
}
//Debug.Log("" + i + ": " + nWeight);
}
Debug.Log(str);
}
* */
}