1 using System;
2 using UnityEngine;
3
4 namespace UnityStandardAssets.ImageEffects
5 {
6 public enum LensflareStyle34
7 {
8 Ghosting = 0,
9 Anamorphic = 1,
10 Combined = 2,
11 }
12
13 public enum TweakMode34
14 {
15 Basic = 0,
16 Complex = 1,
17 }
18
19 public enum HDRBloomMode
20 {
21 Auto = 0,
22 On = 1,
23 Off = 2,
24 }
25
26 public enum BloomScreenBlendMode
27 {
28 Screen = 0,
29 Add = 1,
30 }
31
32 [ExecuteInEditMode]
33 [RequireComponent(typeof(Camera))]
34 [AddComponentMenu("Image Effects/Bloom and Glow/BloomAndFlares (3.5, Deprecated)")]
35 public class BloomAndFlares : PostEffectsBase
36 {
37 public TweakMode34 tweakMode = 0;
38 public BloomScreenBlendMode screenBlendMode = BloomScreenBlendMode.Add;
39
40 public HDRBloomMode hdr = HDRBloomMode.Auto;
41 private bool doHdr = false;
42 public float sepBlurSpread = 1.5f;
43 public float useSrcAlphaAsMask = 0.5f;
44
45 public float bloomIntensity = 1.0f;
46 public float bloomThreshold = 0.5f;
47 public int bloomBlurIterations = 2;
48
49 public bool lensflares = false;
50 public int hollywoodFlareBlurIterations = 2;
51 public LensflareStyle34 lensflareMode = (LensflareStyle34)1;
52 public float hollyStretchWidth = 3.5f;
53 public float lensflareIntensity = 1.0f;
54 public float lensflareThreshold = 0.3f;
55 public Color flareColorA = new Color(0.4f, 0.4f, 0.8f, 0.75f);
56 public Color flareColorB = new Color(0.4f, 0.8f, 0.8f, 0.75f);
57 public Color flareColorC = new Color(0.8f, 0.4f, 0.8f, 0.75f);
58 public Color flareColorD = new Color(0.8f, 0.4f, 0.0f, 0.75f);
59 public Texture2D lensFlareVignetteMask;
60
61 public Shader lensFlareShader;
62 private Material lensFlareMaterial;
63
64 public Shader vignetteShader;
65 private Material vignetteMaterial;
66
67 public Shader separableBlurShader;
68 private Material separableBlurMaterial;
69
70 public Shader addBrightStuffOneOneShader;
71 private Material addBrightStuffBlendOneOneMaterial;
72
73 public Shader screenBlendShader;
74 private Material screenBlend;
75
76 public Shader hollywoodFlaresShader;
77 private Material hollywoodFlaresMaterial;
78
79 public Shader brightPassFilterShader;
80 private Material brightPassFilterMaterial;
81
82
83 public override bool CheckResources()
84 {
85 CheckSupport(false);
86
87 screenBlend = CheckShaderAndCreateMaterial(screenBlendShader, screenBlend);
88 lensFlareMaterial = CheckShaderAndCreateMaterial(lensFlareShader, lensFlareMaterial);
89 vignetteMaterial = CheckShaderAndCreateMaterial(vignetteShader, vignetteMaterial);
90 separableBlurMaterial = CheckShaderAndCreateMaterial(separableBlurShader, separableBlurMaterial);
91 addBrightStuffBlendOneOneMaterial = CheckShaderAndCreateMaterial(addBrightStuffOneOneShader, addBrightStuffBlendOneOneMaterial);
92 hollywoodFlaresMaterial = CheckShaderAndCreateMaterial(hollywoodFlaresShader, hollywoodFlaresMaterial);
93 brightPassFilterMaterial = CheckShaderAndCreateMaterial(brightPassFilterShader, brightPassFilterMaterial);
94
95 if (!isSupported)
96 ReportAutoDisable();
97 return isSupported;
98 }
99
100 void OnRenderImage(RenderTexture source, RenderTexture destination)
101 {
102 if (CheckResources() == false)
103 {
104 Graphics.Blit(source, destination);
105 return;
106 }
107
108 // screen blend is not supported when HDR is enabled (will cap values)
109
110 doHdr = false;
111 if (hdr == HDRBloomMode.Auto)
112 doHdr = source.format == RenderTextureFormat.ARGBHalf && GetComponent<Camera>().hdr;
113 else
114 {
115 doHdr = hdr == HDRBloomMode.On;
116 }
117
118 doHdr = doHdr && supportHDRTextures;
119
120 BloomScreenBlendMode realBlendMode = screenBlendMode;
121 if (doHdr)
122 realBlendMode = BloomScreenBlendMode.Add;
123
124 var rtFormat = (doHdr) ? RenderTextureFormat.ARGBHalf : RenderTextureFormat.Default;
125 RenderTexture halfRezColor = RenderTexture.GetTemporary(source.width / 2, source.height / 2, 0, rtFormat);
126 RenderTexture quarterRezColor = RenderTexture.GetTemporary(source.width / 4, source.height / 4, 0, rtFormat);
127 RenderTexture secondQuarterRezColor = RenderTexture.GetTemporary(source.width / 4, source.height / 4, 0, rtFormat);
128 RenderTexture thirdQuarterRezColor = RenderTexture.GetTemporary(source.width / 4, source.height / 4, 0, rtFormat);
129
130 float widthOverHeight = (1.0f * source.width) / (1.0f * source.height);
131 float oneOverBaseSize = 1.0f / 512.0f;
132
133 // downsample
134
135 Graphics.Blit(source, halfRezColor, screenBlend, 2); // <- 2 is stable downsample
136 Graphics.Blit(halfRezColor, quarterRezColor, screenBlend, 2); // <- 2 is stable downsample
137
138 RenderTexture.ReleaseTemporary(halfRezColor);
139
140 // cut colors (thresholding)
141
142 BrightFilter(bloomThreshold, useSrcAlphaAsMask, quarterRezColor, secondQuarterRezColor);
143 quarterRezColor.DiscardContents();
144
145 // blurring
146
147 if (bloomBlurIterations < 1) bloomBlurIterations = 1;
148
149 for (int iter = 0; iter < bloomBlurIterations; iter++)
150 {
151 float spreadForPass = (1.0f + (iter * 0.5f)) * sepBlurSpread;
152 separableBlurMaterial.SetVector("offsets", new Vector4(0.0f, spreadForPass * oneOverBaseSize, 0.0f, 0.0f));
153
154 RenderTexture src = iter == 0 ? secondQuarterRezColor : quarterRezColor;
155 Graphics.Blit(src, thirdQuarterRezColor, separableBlurMaterial);
156 src.DiscardContents();
157
158 separableBlurMaterial.SetVector("offsets", new Vector4((spreadForPass / widthOverHeight) * oneOverBaseSize, 0.0f, 0.0f, 0.0f));
159 Graphics.Blit(thirdQuarterRezColor, quarterRezColor, separableBlurMaterial);
160 thirdQuarterRezColor.DiscardContents();
161 }
162
163 // lens flares: ghosting, anamorphic or a combination
164
165 if (lensflares)
166 {
167
168 if (lensflareMode == 0)
169 {
170
171 BrightFilter(lensflareThreshold, 0.0f, quarterRezColor, thirdQuarterRezColor);
172 quarterRezColor.DiscardContents();
173
174 // smooth a little, this needs to be resolution dependent
175 /*
176 separableBlurMaterial.SetVector ("offsets", Vector4 (0.0ff, (2.0ff) / (1.0ff * quarterRezColor.height), 0.0ff, 0.0ff));
177 Graphics.Blit (thirdQuarterRezColor, secondQuarterRezColor, separableBlurMaterial);
178 separableBlurMaterial.SetVector ("offsets", Vector4 ((2.0ff) / (1.0ff * quarterRezColor.width), 0.0ff, 0.0ff, 0.0ff));
179 Graphics.Blit (secondQuarterRezColor, thirdQuarterRezColor, separableBlurMaterial);
180 */
181 // no ugly edges!
182
183 Vignette(0.975f, thirdQuarterRezColor, secondQuarterRezColor);
184 thirdQuarterRezColor.DiscardContents();
185
186 BlendFlares(secondQuarterRezColor, quarterRezColor);
187 secondQuarterRezColor.DiscardContents();
188 }
189
190 // (b) hollywood/anamorphic flares?
191
192 else
193 {
194
195 // thirdQuarter has the brightcut unblurred colors
196 // quarterRezColor is the blurred, brightcut buffer that will end up as bloom
197
198 hollywoodFlaresMaterial.SetVector("_threshold", new Vector4(lensflareThreshold, 1.0f / (1.0f - lensflareThreshold), 0.0f, 0.0f));
199 hollywoodFlaresMaterial.SetVector("tintColor", new Vector4(flareColorA.r, flareColorA.g, flareColorA.b, flareColorA.a) * flareColorA.a * lensflareIntensity);
200 Graphics.Blit(thirdQuarterRezColor, secondQuarterRezColor, hollywoodFlaresMaterial, 2);
201 thirdQuarterRezColor.DiscardContents();
202
203 Graphics.Blit(secondQuarterRezColor, thirdQuarterRezColor, hollywoodFlaresMaterial, 3);
204 secondQuarterRezColor.DiscardContents();
205
206 hollywoodFlaresMaterial.SetVector("offsets", new Vector4((sepBlurSpread * 1.0f / widthOverHeight) * oneOverBaseSize, 0.0f, 0.0f, 0.0f));
207 hollywoodFlaresMaterial.SetFloat("stretchWidth", hollyStretchWidth);
208 Graphics.Blit(thirdQuarterRezColor, secondQuarterRezColor, hollywoodFlaresMaterial, 1);
209 thirdQuarterRezColor.DiscardContents();
210
211 hollywoodFlaresMaterial.SetFloat("stretchWidth", hollyStretchWidth * 2.0f);
212 Graphics.Blit(secondQuarterRezColor, thirdQuarterRezColor, hollywoodFlaresMaterial, 1);
213 secondQuarterRezColor.DiscardContents();
214
215 hollywoodFlaresMaterial.SetFloat("stretchWidth", hollyStretchWidth * 4.0f);
216 Graphics.Blit(thirdQuarterRezColor, secondQuarterRezColor, hollywoodFlaresMaterial, 1);
217 thirdQuarterRezColor.DiscardContents();
218
219 if (lensflareMode == (LensflareStyle34)1)
220 {
221 for (int itera = 0; itera < hollywoodFlareBlurIterations; itera++)
222 {
223 separableBlurMaterial.SetVector("offsets", new Vector4((hollyStretchWidth * 2.0f / widthOverHeight) * oneOverBaseSize, 0.0f, 0.0f, 0.0f));
224 Graphics.Blit(secondQuarterRezColor, thirdQuarterRezColor, separableBlurMaterial);
225 secondQuarterRezColor.DiscardContents();
226
227 separableBlurMaterial.SetVector("offsets", new Vector4((hollyStretchWidth * 2.0f / widthOverHeight) * oneOverBaseSize, 0.0f, 0.0f, 0.0f));
228 Graphics.Blit(thirdQuarterRezColor, secondQuarterRezColor, separableBlurMaterial);
229 thirdQuarterRezColor.DiscardContents();
230 }
231
232 AddTo(1.0f, secondQuarterRezColor, quarterRezColor);
233 secondQuarterRezColor.DiscardContents();
234 }
235 else
236 {
237
238 // (c) combined
239
240 for (int ix = 0; ix < hollywoodFlareBlurIterations; ix++)
241 {
242 separableBlurMaterial.SetVector("offsets", new Vector4((hollyStretchWidth * 2.0f / widthOverHeight) * oneOverBaseSize, 0.0f, 0.0f, 0.0f));
243 Graphics.Blit(secondQuarterRezColor, thirdQuarterRezColor, separableBlurMaterial);
244 secondQuarterRezColor.DiscardContents();
245
246 separableBlurMaterial.SetVector("offsets", new Vector4((hollyStretchWidth * 2.0f / widthOverHeight) * oneOverBaseSize, 0.0f, 0.0f, 0.0f));
247 Graphics.Blit(thirdQuarterRezColor, secondQuarterRezColor, separableBlurMaterial);
248 thirdQuarterRezColor.DiscardContents();
249 }
250
251 Vignette(1.0f, secondQuarterRezColor, thirdQuarterRezColor);
252 secondQuarterRezColor.DiscardContents();
253
254 BlendFlares(thirdQuarterRezColor, secondQuarterRezColor);
255 thirdQuarterRezColor.DiscardContents();
256
257 AddTo(1.0f, secondQuarterRezColor, quarterRezColor);
258 secondQuarterRezColor.DiscardContents();
259 }
260 }
261 }
262
263 // screen blend bloom results to color buffer
264
265 screenBlend.SetFloat("_Intensity", bloomIntensity);
266 screenBlend.SetTexture("_ColorBuffer", source);
267 Graphics.Blit(quarterRezColor, destination, screenBlend, (int)realBlendMode);
268
269 RenderTexture.ReleaseTemporary(quarterRezColor);
270 RenderTexture.ReleaseTemporary(secondQuarterRezColor);
271 RenderTexture.ReleaseTemporary(thirdQuarterRezColor);
272 }
273
274 private void AddTo(float intensity_, RenderTexture from, RenderTexture to)
275 {
276 addBrightStuffBlendOneOneMaterial.SetFloat("_Intensity", intensity_);
277 Graphics.Blit(from, to, addBrightStuffBlendOneOneMaterial);
278 }
279
280 private void BlendFlares(RenderTexture from, RenderTexture to)
281 {
282 lensFlareMaterial.SetVector("colorA", new Vector4(flareColorA.r, flareColorA.g, flareColorA.b, flareColorA.a) * lensflareIntensity);
283 lensFlareMaterial.SetVector("colorB", new Vector4(flareColorB.r, flareColorB.g, flareColorB.b, flareColorB.a) * lensflareIntensity);
284 lensFlareMaterial.SetVector("colorC", new Vector4(flareColorC.r, flareColorC.g, flareColorC.b, flareColorC.a) * lensflareIntensity);
285 lensFlareMaterial.SetVector("colorD", new Vector4(flareColorD.r, flareColorD.g, flareColorD.b, flareColorD.a) * lensflareIntensity);
286 Graphics.Blit(from, to, lensFlareMaterial);
287 }
288
289 private void BrightFilter(float thresh, float useAlphaAsMask, RenderTexture from, RenderTexture to)
290 {
291 if (doHdr)
292 brightPassFilterMaterial.SetVector("threshold", new Vector4(thresh, 1.0f, 0.0f, 0.0f));
293 else
294 brightPassFilterMaterial.SetVector("threshold", new Vector4(thresh, 1.0f / (1.0f - thresh), 0.0f, 0.0f));
295 brightPassFilterMaterial.SetFloat("useSrcAlphaAsMask", useAlphaAsMask);
296 Graphics.Blit(from, to, brightPassFilterMaterial);
297 }
298
299 private void Vignette(float amount, RenderTexture from, RenderTexture to)
300 {
301 if (lensFlareVignetteMask)
302 {
303 screenBlend.SetTexture("_ColorBuffer", lensFlareVignetteMask);
304 Graphics.Blit(from, to, screenBlend, 3);
305 }
306 else
307 {
308 vignetteMaterial.SetFloat("vignetteIntensity", amount);
309 Graphics.Blit(from, to, vignetteMaterial);
310 }
311 }
312
313 }
314 }
screen blend is not supported when HDR is enabled (will cap values)
downsample
Graphics.Blit(source, halfRezColor, screenBlend, 2); <- 2 is stable downsample
Graphics.Blit(halfRezColor, quarterRezColor, screenBlend, 2); <- 2 is stable downsample
cut colors (thresholding)
blurring
lens flares: ghosting, anamorphic or a combination
smooth a little, this needs to be resolution dependent
no ugly edges!
(b) hollywoodanamorphic flares?
thirdQuarter has the brightcut unblurred colors
quarterRezColor is the blurred, brightcut buffer that will end up as bloom
(c) combined
screen blend bloom results to color buffer