Code Review

1 using System;
2 using
UnityEngine;
3
4 namespace
UnityStandardAssets.ImageEffects
5 {
6     
[ExecuteInEditMode]
7     
[RequireComponent (typeof(Camera))]
8     
[AddComponentMenu ("Image Effects/Bloom and Glow/Bloom")]
9     
public class Bloom : PostEffectsBase
10     {
11         
public enum LensFlareStyle
12         {
13             Ghosting =
0,
14             Anamorphic =
1,
15             Combined =
2,
16         }
17
18         
public enum TweakMode
19         {
20             Basic =
0,
21             Complex =
1,
22         }
23
24         
public enum HDRBloomMode
25         {
26             Auto =
0,
27             On =
1,
28             Off =
2,
29         }
30
31         
public enum BloomScreenBlendMode
32         {
33             Screen =
0,
34             Add =
1,
35         }
36
37         
public enum BloomQuality
38         {
39             Cheap =
0,
40             High =
1,
41         }
42
43         
public TweakMode tweakMode = 0;
44         
public BloomScreenBlendMode screenBlendMode = BloomScreenBlendMode.Add;
45
46         
public HDRBloomMode hdr = HDRBloomMode.Auto;
47         
private bool doHdr = false;
48         
public float sepBlurSpread = 2.5f;
49
50         
public BloomQuality quality = BloomQuality.High;
51
52         
public float bloomIntensity = 0.5f;
53         
public float bloomThreshold = 0.5f;
54         
public Color bloomThresholdColor = Color.white;
55         
public int bloomBlurIterations = 2;
56
57         
public int hollywoodFlareBlurIterations = 2;
58         
public float flareRotation = 0.0f;
59         
public LensFlareStyle lensflareMode = (LensFlareStyle) 1;
60         
public float hollyStretchWidth = 2.5f;
61         
public float lensflareIntensity = 0.0f;
62         
public float lensflareThreshold = 0.3f;
63         
public float lensFlareSaturation = 0.75f;
64         
public Color flareColorA = new Color (0.4f, 0.4f, 0.8f, 0.75f);
65         
public Color flareColorB = new Color (0.4f, 0.8f, 0.8f, 0.75f);
66         
public Color flareColorC = new Color (0.8f, 0.4f, 0.8f, 0.75f);
67         
public Color flareColorD = new Color (0.8f, 0.4f, 0.0f, 0.75f);
68         
public Texture2D lensFlareVignetteMask;
69
70         
public Shader lensFlareShader;
71         
private Material lensFlareMaterial;
72
73         
public Shader screenBlendShader;
74         
private Material screenBlend;
75
76         
public Shader blurAndFlaresShader;
77         
private Material blurAndFlaresMaterial;
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             blurAndFlaresMaterial = CheckShaderAndCreateMaterial (blurAndFlaresShader, blurAndFlaresMaterial);
90             brightPassFilterMaterial = CheckShaderAndCreateMaterial(brightPassFilterShader, brightPassFilterMaterial);
91
92             
if (!isSupported)
93                 ReportAutoDisable ();
94             
return isSupported;
95         }
96
97         
public void OnRenderImage (RenderTexture source, RenderTexture destination)
98         {
99             
if (CheckResources()==false)
100             {
101                 Graphics.Blit (source, destination);
102                 
return;
103             }
104
105             
// screen blend is not supported when HDR is enabled (will cap values)
106
107             doHdr =
false;
108             
if (hdr == HDRBloomMode.Auto)
109                 doHdr = source.format == RenderTextureFormat.ARGBHalf && GetComponent<Camera>().hdr;
110             
else {
111                 doHdr = hdr == HDRBloomMode.On;
112             }
113
114             doHdr = doHdr && supportHDRTextures;
115
116             BloomScreenBlendMode realBlendMode = screenBlendMode;
117             
if (doHdr)
118                 realBlendMode = BloomScreenBlendMode.Add;
119
120             
var rtFormat= (doHdr) ? RenderTextureFormat.ARGBHalf : RenderTextureFormat.Default;
121             
var rtW2= source.width/2;
122             
var rtH2= source.height/2;
123             
var rtW4= source.width/4;
124             
var rtH4= source.height/4;
125
126             
float widthOverHeight = (1.0f * source.width) / (1.0f * source.height);
127             
float oneOverBaseSize = 1.0f / 512.0f;
128
129             
// downsample
130             RenderTexture quarterRezColor = RenderTexture.GetTemporary (rtW4, rtH4,
0, rtFormat);
131             RenderTexture halfRezColorDown = RenderTexture.GetTemporary (rtW2, rtH2,
0, rtFormat);
132             
if (quality > BloomQuality.Cheap) {
133                 Graphics.Blit (source, halfRezColorDown, screenBlend,
2);
134                 RenderTexture rtDown4 = RenderTexture.GetTemporary (rtW4, rtH4,
0, rtFormat);
135                 Graphics.Blit (halfRezColorDown, rtDown4, screenBlend,
2);
136                 Graphics.Blit (rtDown4, quarterRezColor, screenBlend,
6);
137                 RenderTexture.ReleaseTemporary(rtDown4);
138             }
139             
else {
140                 Graphics.Blit (source, halfRezColorDown);
141                 Graphics.Blit (halfRezColorDown, quarterRezColor, screenBlend,
6);
142             }
143             RenderTexture.ReleaseTemporary (halfRezColorDown);
144
145             
// cut colors (thresholding)
146             RenderTexture secondQuarterRezColor = RenderTexture.GetTemporary (rtW4, rtH4,
0, rtFormat);
147             BrightFilter (bloomThreshold * bloomThresholdColor, quarterRezColor, secondQuarterRezColor);
148
149             
// blurring
150
151             
if (bloomBlurIterations < 1) bloomBlurIterations = 1;
152             
else if (bloomBlurIterations > 10) bloomBlurIterations = 10;
153
154             
for (int iter = 0; iter < bloomBlurIterations; iter++)
155             {
156                 
float spreadForPass = (1.0f + (iter * 0.25f)) * sepBlurSpread;
157
158                 
// vertical blur
159                 RenderTexture blur4 = RenderTexture.GetTemporary (rtW4, rtH4,
0, rtFormat);
160                 blurAndFlaresMaterial.SetVector (
"_Offsets", new Vector4 (0.0f, spreadForPass * oneOverBaseSize, 0.0f, 0.0f));
161                 Graphics.Blit (secondQuarterRezColor, blur4, blurAndFlaresMaterial,
4);
162                 RenderTexture.ReleaseTemporary(secondQuarterRezColor);
163                 secondQuarterRezColor = blur4;
164
165                 
// horizontal blur
166                 blur4 = RenderTexture.GetTemporary (rtW4, rtH4,
0, rtFormat);
167                 blurAndFlaresMaterial.SetVector (
"_Offsets", new Vector4 ((spreadForPass / widthOverHeight) * oneOverBaseSize, 0.0f, 0.0f, 0.0f));
168                 Graphics.Blit (secondQuarterRezColor, blur4, blurAndFlaresMaterial,
4);
169                 RenderTexture.ReleaseTemporary (secondQuarterRezColor);
170                 secondQuarterRezColor = blur4;
171
172                 
if (quality > BloomQuality.Cheap)
173                 {
174                     
if (iter == 0)
175                     {
176                         Graphics.SetRenderTarget(quarterRezColor);
177                         GL.Clear(
false, true, Color.black); // Clear to avoid RT restore
178                         Graphics.Blit (secondQuarterRezColor, quarterRezColor);
179                     }
180                     
else
181                     {
182                         quarterRezColor.MarkRestoreExpected();
// using max blending, RT restore expected
183                         Graphics.Blit (secondQuarterRezColor, quarterRezColor, screenBlend,
10);
184                     }
185                 }
186             }
187
188             
if (quality > BloomQuality.Cheap)
189             {
190                 Graphics.SetRenderTarget(secondQuarterRezColor);
191                 GL.Clear(
false, true, Color.black); // Clear to avoid RT restore
192                 Graphics.Blit (quarterRezColor, secondQuarterRezColor, screenBlend,
6);
193             }
194
195             
// lens flares: ghosting, anamorphic or both (ghosted anamorphic flares)
196
197             
if (lensflareIntensity > Mathf.Epsilon)
198             {
199
200                 RenderTexture rtFlares4 = RenderTexture.GetTemporary (rtW4, rtH4,
0, rtFormat);
201
202                 
if (lensflareMode == 0)
203                 {
204                     
// ghosting only
205
206                     BrightFilter (lensflareThreshold, secondQuarterRezColor, rtFlares4);
207
208                     
if (quality > BloomQuality.Cheap)
209                     {
210                         
// smooth a little
211                         blurAndFlaresMaterial.SetVector (
"_Offsets", new Vector4 (0.0f, (1.5f) / (1.0f * quarterRezColor.height), 0.0f, 0.0f));
212                         Graphics.SetRenderTarget(quarterRezColor);
213                         GL.Clear(
false, true, Color.black); // Clear to avoid RT restore
214                         Graphics.Blit (rtFlares4, quarterRezColor, blurAndFlaresMaterial,
4);
215
216                         blurAndFlaresMaterial.SetVector (
"_Offsets", new Vector4 ((1.5f) / (1.0f * quarterRezColor.width), 0.0f, 0.0f, 0.0f));
217                         Graphics.SetRenderTarget(rtFlares4);
218                         GL.Clear(
false, true, Color.black); // Clear to avoid RT restore
219                         Graphics.Blit (quarterRezColor, rtFlares4, blurAndFlaresMaterial,
4);
220                     }
221
222                     
// no ugly edges!
223                     Vignette (
0.975f, rtFlares4, rtFlares4);
224                     BlendFlares (rtFlares4, secondQuarterRezColor);
225                 }
226                 
else
227                 {
228
229                     
//Vignette (0.975ff, rtFlares4, rtFlares4);
230                     
//DrawBorder(rtFlares4, screenBlend, 8);
231
232                     
float flareXRot = 1.0f * Mathf.Cos(flareRotation);
233                     
float flareyRot = 1.0f * Mathf.Sin(flareRotation);
234
235                     
float stretchWidth = (hollyStretchWidth * 1.0f / widthOverHeight) * oneOverBaseSize;
236
237                     blurAndFlaresMaterial.SetVector (
"_Offsets", new Vector4 (flareXRot, flareyRot, 0.0f, 0.0f));
238                     blurAndFlaresMaterial.SetVector (
"_Threshhold", new Vector4 (lensflareThreshold, 1.0f, 0.0f, 0.0f));
239                     blurAndFlaresMaterial.SetVector (
"_TintColor", new Vector4 (flareColorA.r, flareColorA.g, flareColorA.b, flareColorA.a) * flareColorA.a * lensflareIntensity);
240                     blurAndFlaresMaterial.SetFloat (
"_Saturation", lensFlareSaturation);
241
242                     
// "pre and cut"
243                     quarterRezColor.DiscardContents();
244                     Graphics.Blit (rtFlares4, quarterRezColor, blurAndFlaresMaterial,
2);
245                     
// "post"
246                     rtFlares4.DiscardContents();
247                     Graphics.Blit (quarterRezColor, rtFlares4, blurAndFlaresMaterial,
3);
248
249                     blurAndFlaresMaterial.SetVector (
"_Offsets", new Vector4 (flareXRot * stretchWidth, flareyRot * stretchWidth, 0.0f, 0.0f));
250                     
// stretch 1st
251                     blurAndFlaresMaterial.SetFloat (
"_StretchWidth", hollyStretchWidth);
252                     quarterRezColor.DiscardContents();
253                     Graphics.Blit (rtFlares4, quarterRezColor, blurAndFlaresMaterial,
1);
254                     
// stretch 2nd
255                     blurAndFlaresMaterial.SetFloat (
"_StretchWidth", hollyStretchWidth * 2.0f);
256                     rtFlares4.DiscardContents();
257                     Graphics.Blit (quarterRezColor, rtFlares4, blurAndFlaresMaterial,
1);
258                     
// stretch 3rd
259                     blurAndFlaresMaterial.SetFloat (
"_StretchWidth", hollyStretchWidth * 4.0f);
260                     quarterRezColor.DiscardContents();
261                     Graphics.Blit (rtFlares4, quarterRezColor, blurAndFlaresMaterial,
1);
262
263                     
// additional blur passes
264                     
for (int iter = 0; iter < hollywoodFlareBlurIterations; iter++)
265                     {
266                         stretchWidth = (hollyStretchWidth *
2.0f / widthOverHeight) * oneOverBaseSize;
267
268                         blurAndFlaresMaterial.SetVector (
"_Offsets", new Vector4 (stretchWidth * flareXRot, stretchWidth * flareyRot, 0.0f, 0.0f));
269                         rtFlares4.DiscardContents();
270                         Graphics.Blit (quarterRezColor, rtFlares4, blurAndFlaresMaterial,
4);
271
272                         blurAndFlaresMaterial.SetVector (
"_Offsets", new Vector4 (stretchWidth * flareXRot, stretchWidth * flareyRot, 0.0f, 0.0f));
273                         quarterRezColor.DiscardContents();
274                         Graphics.Blit (rtFlares4, quarterRezColor, blurAndFlaresMaterial,
4);
275                     }
276
277                     
if (lensflareMode == (LensFlareStyle) 1)
278                         
// anamorphic lens flares
279                         AddTo (
1.0f, quarterRezColor, secondQuarterRezColor);
280                     
else
281                     {
282                         
// "combined" lens flares
283
284                         Vignette (
1.0f, quarterRezColor, rtFlares4);
285                         BlendFlares (rtFlares4, quarterRezColor);
286                         AddTo (
1.0f, quarterRezColor, secondQuarterRezColor);
287                     }
288                 }
289                 RenderTexture.ReleaseTemporary (rtFlares4);
290             }
291
292             
int blendPass = (int) realBlendMode;
293             
//if (Mathf.Abs(chromaticBloom) < Mathf.Epsilon)
294             
// blendPass += 4;
295
296             screenBlend.SetFloat (
"_Intensity", bloomIntensity);
297             screenBlend.SetTexture (
"_ColorBuffer", source);
298
299             
if (quality > BloomQuality.Cheap)
300             {
301                 RenderTexture halfRezColorUp = RenderTexture.GetTemporary (rtW2, rtH2,
0, rtFormat);
302                 Graphics.Blit (secondQuarterRezColor, halfRezColorUp);
303                 Graphics.Blit (halfRezColorUp, destination, screenBlend, blendPass);
304                 RenderTexture.ReleaseTemporary (halfRezColorUp);
305             }
306             
else
307                 Graphics.Blit (secondQuarterRezColor, destination, screenBlend, blendPass);
308
309             RenderTexture.ReleaseTemporary (quarterRezColor);
310             RenderTexture.ReleaseTemporary (secondQuarterRezColor);
311         }
312
313         
private void AddTo (float intensity_, RenderTexture from, RenderTexture to)
314         {
315             screenBlend.SetFloat (
"_Intensity", intensity_);
316             to.MarkRestoreExpected();
// additive blending, RT restore expected
317             Graphics.Blit (
from, to, screenBlend, 9);
318         }
319
320         
private void BlendFlares (RenderTexture from, RenderTexture to)
321         {
322             lensFlareMaterial.SetVector (
"colorA", new Vector4 (flareColorA.r, flareColorA.g, flareColorA.b, flareColorA.a) * lensflareIntensity);
323             lensFlareMaterial.SetVector (
"colorB", new Vector4 (flareColorB.r, flareColorB.g, flareColorB.b, flareColorB.a) * lensflareIntensity);
324             lensFlareMaterial.SetVector (
"colorC", new Vector4 (flareColorC.r, flareColorC.g, flareColorC.b, flareColorC.a) * lensflareIntensity);
325             lensFlareMaterial.SetVector (
"colorD", new Vector4 (flareColorD.r, flareColorD.g, flareColorD.b, flareColorD.a) * lensflareIntensity);
326             to.MarkRestoreExpected();
// additive blending, RT restore expected
327             Graphics.Blit (
from, to, lensFlareMaterial);
328         }
329
330         
private void BrightFilter (float thresh, RenderTexture from, RenderTexture to)
331         {
332             brightPassFilterMaterial.SetVector (
"_Threshhold", new Vector4 (thresh, thresh, thresh, thresh));
333             Graphics.Blit (
from, to, brightPassFilterMaterial, 0);
334         }
335
336         
private void BrightFilter (Color threshColor, RenderTexture from, RenderTexture to)
337         {
338             brightPassFilterMaterial.SetVector (
"_Threshhold", threshColor);
339             Graphics.Blit (
from, to, brightPassFilterMaterial, 1);
340         }
341
342         
private void Vignette (float amount, RenderTexture from, RenderTexture to)
343         {
344             
if (lensFlareVignetteMask)
345             {
346                 screenBlend.SetTexture (
"_ColorBuffer", lensFlareVignetteMask);
347                 to.MarkRestoreExpected();
// using blending, RT restore expected
348                 Graphics.Blit (
from == to ? null : from, to, screenBlend, from == to ? 7 : 3);
349             }
350             
else if (from != to)
351             {
352                 Graphics.SetRenderTarget (to);
353                 GL.Clear(
false, true, Color.black); // clear destination to avoid RT restore
354                 Graphics.Blit (
from, to);
355             }
356         }
357     }
358 }


Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *