1 using System;
2 using
UnityEngine;
3
4 namespace
UnityStandardAssets.ImageEffects
5 {
6     
[ExecuteInEditMode]
7     
[RequireComponent (typeof(Camera))]
8     
[AddComponentMenu ("Image Effects/Camera/Depth of Field (deprecated)") ]
9     
public class DepthOfFieldDeprecated : PostEffectsBase
10     {
11         
public enum Dof34QualitySetting
12         {
13             OnlyBackground =
1,
14             BackgroundAndForeground =
2,
15         }
16
17         
public enum DofResolution
18         {
19             High =
2,
20             Medium =
3,
21             Low =
4,
22         }
23
24         
public enum DofBlurriness
25         {
26             Low =
1,
27             High =
2,
28             VeryHigh =
4,
29         }
30
31         
public enum BokehDestination
32         {
33             Background =
0x1,
34             Foreground =
0x2,
35             BackgroundAndForeground =
0x3,
36         }
37
38         
static private int SMOOTH_DOWNSAMPLE_PASS = 6;
39         
static private float BOKEH_EXTRA_BLUR = 2.0f;
40
41         
public Dof34QualitySetting quality = Dof34QualitySetting.OnlyBackground;
42         
public DofResolution resolution = DofResolution.Low;
43         
public bool simpleTweakMode = true;
44
45         
public float focalPoint = 1.0f;
46         
public float smoothness = 0.5f;
47
48         
public float focalZDistance = 0.0f;
49         
public float focalZStartCurve = 1.0f;
50         
public float focalZEndCurve = 1.0f;
51
52         
private float focalStartCurve = 2.0f;
53         
private float focalEndCurve = 2.0f;
54         
private float focalDistance01 = 0.1f;
55
56         
public Transform objectFocus = null;
57         
public float focalSize = 0.0f;
58
59         
public DofBlurriness bluriness = DofBlurriness.High;
60         
public float maxBlurSpread = 1.75f;
61
62         
public float foregroundBlurExtrude = 1.15f;
63
64         
public Shader dofBlurShader;
65         
private Material dofBlurMaterial = null;
66
67         
public Shader dofShader;
68         
private Material dofMaterial = null;
69
70         
public bool visualize = false;
71         
public BokehDestination bokehDestination = BokehDestination.Background;
72
73         
private float widthOverHeight = 1.25f;
74         
private float oneOverBaseSize = 1.0f / 512.0f;
75
76         
public bool bokeh = false;
77         
public bool bokehSupport = true;
78         
public Shader bokehShader;
79         
public Texture2D bokehTexture;
80         
public float bokehScale = 2.4f;
81         
public float bokehIntensity = 0.15f;
82         
public float bokehThresholdContrast = 0.1f;
83         
public float bokehThresholdLuminance = 0.55f;
84         
public int bokehDownsample = 1;
85         
private Material bokehMaterial;
86
87         
private Camera _camera;
88
89         
void CreateMaterials () {
90             dofBlurMaterial = CheckShaderAndCreateMaterial (dofBlurShader, dofBlurMaterial);
91             dofMaterial = CheckShaderAndCreateMaterial (dofShader,dofMaterial);
92             bokehSupport = bokehShader.isSupported;
93
94             
if (bokeh && bokehSupport && bokehShader)
95                 bokehMaterial = CheckShaderAndCreateMaterial (bokehShader, bokehMaterial);
96         }
97
98
99         
public override bool CheckResources () {
100             CheckSupport (
true);
101
102             dofBlurMaterial = CheckShaderAndCreateMaterial (dofBlurShader, dofBlurMaterial);
103             dofMaterial = CheckShaderAndCreateMaterial (dofShader,dofMaterial);
104             bokehSupport = bokehShader.isSupported;
105
106             
if (bokeh && bokehSupport && bokehShader)
107                 bokehMaterial = CheckShaderAndCreateMaterial (bokehShader, bokehMaterial);
108
109             
if (!isSupported)
110                 ReportAutoDisable ();
111             
return isSupported;
112         }
113
114         
void OnDisable () {
115             Quads.Cleanup ();
116         }
117
118         
void OnEnable () {
119             _camera = GetComponent<Camera>();
120             _camera.depthTextureMode |= DepthTextureMode.Depth;
121         }
122
123         
float FocalDistance01 ( float worldDist) {
124             
return _camera.WorldToViewportPoint((worldDist-_camera.nearClipPlane) * _camera.transform.forward + _camera.transform.position).z / (_camera.farClipPlane-_camera.nearClipPlane);
125         }
126
127         
int GetDividerBasedOnQuality () {
128             
int divider = 1;
129             
if (resolution == DofResolution.Medium)
130                 divider =
2;
131             
else if (resolution == DofResolution.Low)
132                 divider =
2;
133             
return divider;
134         }
135
136         
int GetLowResolutionDividerBasedOnQuality ( int baseDivider) {
137             
int lowTexDivider = baseDivider;
138             
if (resolution == DofResolution.High)
139                 lowTexDivider *=
2;
140             
if (resolution == DofResolution.Low)
141                 lowTexDivider *=
2;
142             
return lowTexDivider;
143         }
144
145         
private RenderTexture foregroundTexture = null;
146         
private RenderTexture mediumRezWorkTexture = null;
147         
private RenderTexture finalDefocus = null;
148         
private RenderTexture lowRezWorkTexture = null;
149         
private RenderTexture bokehSource = null;
150         
private RenderTexture bokehSource2 = null;
151
152         
void OnRenderImage (RenderTexture source, RenderTexture destination) {
153             
if (CheckResources()==false) {
154                 Graphics.Blit (source, destination);
155                 
return;
156             }
157
158             
if (smoothness < 0.1f)
159                 smoothness =
0.1f;
160
161             
// update needed focal & rt size parameter
162
163             bokeh = bokeh && bokehSupport;
164             
float bokehBlurAmplifier = bokeh ? BOKEH_EXTRA_BLUR : 1.0f;
165
166             
bool blurForeground = quality > Dof34QualitySetting.OnlyBackground;
167             
float focal01Size = focalSize / (_camera.farClipPlane - _camera.nearClipPlane);;
168
169             
if (simpleTweakMode) {
170                 focalDistance01 = objectFocus ? (_camera.WorldToViewportPoint (objectFocus.position)).z / (_camera.farClipPlane) : FocalDistance01 (focalPoint);
171                 focalStartCurve = focalDistance01 * smoothness;
172                 focalEndCurve = focalStartCurve;
173                 blurForeground = blurForeground && (focalPoint > (_camera.nearClipPlane + Mathf.Epsilon));
174             }
175             
else {
176                 
if (objectFocus) {
177                     
var vpPoint= _camera.WorldToViewportPoint (objectFocus.position);
178                     vpPoint.z = (vpPoint.z) / (_camera.farClipPlane);
179                     focalDistance01 = vpPoint.z;
180                 }
181                 
else
182                     focalDistance01 = FocalDistance01 (focalZDistance);
183
184                 focalStartCurve = focalZStartCurve;
185                 focalEndCurve = focalZEndCurve;
186                 blurForeground = blurForeground && (focalPoint > (_camera.nearClipPlane + Mathf.Epsilon));
187             }
188
189             widthOverHeight = (
1.0f * source.width) / (1.0f * source.height);
190             oneOverBaseSize =
1.0f / 512.0f;
191
192             dofMaterial.SetFloat (
"_ForegroundBlurExtrude", foregroundBlurExtrude);
193             dofMaterial.SetVector (
"_CurveParams", new Vector4 (simpleTweakMode ? 1.0f / focalStartCurve : focalStartCurve, simpleTweakMode ? 1.0f / focalEndCurve : focalEndCurve, focal01Size * 0.5f, focalDistance01));
194             dofMaterial.SetVector (
"_InvRenderTargetSize", new Vector4 (1.0f / (1.0f * source.width), 1.0f / (1.0f * source.height),0.0f,0.0f));
195
196             
int divider = GetDividerBasedOnQuality ();
197             
int lowTexDivider = GetLowResolutionDividerBasedOnQuality (divider);
198
199             AllocateTextures (blurForeground, source, divider, lowTexDivider);
200
201             
// WRITE COC to alpha channel
202             
// source is only being bound to detect y texcoord flip
203             Graphics.Blit (source, source, dofMaterial,
3);
204
205             
// better DOWNSAMPLE (could actually be weighted for higher quality)
206             Downsample (source, mediumRezWorkTexture);
207
208             
// BLUR A LITTLE first, which has two purposes
209             
// 1.) reduce jitter, noise, aliasing
210             
// 2.) produce the little-blur buffer used in composition later
211             Blur (mediumRezWorkTexture, mediumRezWorkTexture, DofBlurriness.Low,
4, maxBlurSpread);
212
213             
if ((bokeh) && ((BokehDestination.Foreground & bokehDestination) != 0))
214             {
215                 dofMaterial.SetVector (
"_Threshhold", new Vector4(bokehThresholdContrast, bokehThresholdLuminance, 0.95f, 0.0f));
216
217                 
// add and mark the parts that should end up as bokeh shapes
218                 Graphics.Blit (mediumRezWorkTexture, bokehSource2, dofMaterial,
11);
219
220                 
// remove those parts (maybe even a little tittle bittle more) from the regurlarly blurred buffer
221                 
//Graphics.Blit (mediumRezWorkTexture, lowRezWorkTexture, dofMaterial, 10);
222                 Graphics.Blit (mediumRezWorkTexture, lowRezWorkTexture);
//, dofMaterial, 10);
223
224                 
// maybe you want to reblur the small blur ... but not really needed.
225                 
//Blur (mediumRezWorkTexture, mediumRezWorkTexture, DofBlurriness.Low, 4, maxBlurSpread);
226
227                 
// bigger BLUR
228                 Blur (lowRezWorkTexture, lowRezWorkTexture, bluriness,
0, maxBlurSpread * bokehBlurAmplifier);
229             }
230             
else {
231                 
// bigger BLUR
232                 Downsample (mediumRezWorkTexture, lowRezWorkTexture);
233                 Blur (lowRezWorkTexture, lowRezWorkTexture, bluriness,
0, maxBlurSpread);
234             }
235
236             dofBlurMaterial.SetTexture (
"_TapLow", lowRezWorkTexture);
237             dofBlurMaterial.SetTexture (
"_TapMedium", mediumRezWorkTexture);
238             Graphics.Blit (
null, finalDefocus, dofBlurMaterial, 3);
239
240             
// we are only adding bokeh now if the background is the only part we have to deal with
241             
if ((bokeh) && ((BokehDestination.Foreground & bokehDestination) != 0))
242                 AddBokeh (bokehSource2, bokehSource, finalDefocus);
243
244             dofMaterial.SetTexture (
"_TapLowBackground", finalDefocus);
245             dofMaterial.SetTexture (
"_TapMedium", mediumRezWorkTexture); // needed for debugging/visualization
246
247             
// FINAL DEFOCUS (background)
248             Graphics.Blit (source, blurForeground ? foregroundTexture : destination, dofMaterial, visualize ?
2 : 0);
249
250             
// FINAL DEFOCUS (foreground)
251             
if (blurForeground) {
252                 
// WRITE COC to alpha channel
253                 Graphics.Blit (foregroundTexture, source, dofMaterial,
5);
254
255                 
// DOWNSAMPLE (unweighted)
256                 Downsample (source, mediumRezWorkTexture);
257
258                 
// BLUR A LITTLE first, which has two purposes
259                 
// 1.) reduce jitter, noise, aliasing
260                 
// 2.) produce the little-blur buffer used in composition later
261                 BlurFg (mediumRezWorkTexture, mediumRezWorkTexture, DofBlurriness.Low,
2, maxBlurSpread);
262
263                 
if ((bokeh) && ((BokehDestination.Foreground & bokehDestination) != 0))
264                 {
265                     dofMaterial.SetVector (
"_Threshhold", new Vector4(bokehThresholdContrast * 0.5f, bokehThresholdLuminance, 0.0f, 0.0f));
266
267                     
// add and mark the parts that should end up as bokeh shapes
268                     Graphics.Blit (mediumRezWorkTexture, bokehSource2, dofMaterial,
11);
269
270                     
// remove the parts (maybe even a little tittle bittle more) that will end up in bokeh space
271                     
//Graphics.Blit (mediumRezWorkTexture, lowRezWorkTexture, dofMaterial, 10);
272                     Graphics.Blit (mediumRezWorkTexture, lowRezWorkTexture);
//, dofMaterial, 10);
273
274                     
// big BLUR
275                     BlurFg (lowRezWorkTexture, lowRezWorkTexture, bluriness,
1, maxBlurSpread * bokehBlurAmplifier);
276                 }
277                 
else {
278                     
// big BLUR
279                     BlurFg (mediumRezWorkTexture, lowRezWorkTexture, bluriness,
1, maxBlurSpread);
280                 }
281
282                 
// simple upsample once
283                 Graphics.Blit (lowRezWorkTexture, finalDefocus);
284
285                 dofMaterial.SetTexture (
"_TapLowForeground", finalDefocus);
286                 Graphics.Blit (source, destination, dofMaterial, visualize ?
1 : 4);
287
288                 
if ((bokeh) && ((BokehDestination.Foreground & bokehDestination) != 0))
289                     AddBokeh (bokehSource2, bokehSource, destination);
290             }
291
292             ReleaseTextures ();
293         }
294
295         
void Blur ( RenderTexture from, RenderTexture to, DofBlurriness iterations, int blurPass, float spread) {
296             RenderTexture tmp = RenderTexture.GetTemporary (to.width, to.height);
297             
if ((int)iterations > 1) {
298                 BlurHex (
from, to, blurPass, spread, tmp);
299                 
if ((int)iterations > 2) {
300                     dofBlurMaterial.SetVector (
"offsets", new Vector4 (0.0f, spread * oneOverBaseSize, 0.0f, 0.0f));
301                     Graphics.Blit (to, tmp, dofBlurMaterial, blurPass);
302                     dofBlurMaterial.SetVector (
"offsets", new Vector4 (spread / widthOverHeight * oneOverBaseSize, 0.0f, 0.0f, 0.0f));
303                     Graphics.Blit (tmp, to, dofBlurMaterial, blurPass);
304                 }
305             }
306             
else {
307                 dofBlurMaterial.SetVector (
"offsets", new Vector4 (0.0f, spread * oneOverBaseSize, 0.0f, 0.0f));
308                 Graphics.Blit (
from, tmp, dofBlurMaterial, blurPass);
309                 dofBlurMaterial.SetVector (
"offsets", new Vector4 (spread / widthOverHeight * oneOverBaseSize, 0.0f, 0.0f, 0.0f));
310                 Graphics.Blit (tmp, to, dofBlurMaterial, blurPass);
311             }
312             RenderTexture.ReleaseTemporary (tmp);
313         }
314
315         
void BlurFg ( RenderTexture from, RenderTexture to, DofBlurriness iterations, int blurPass, float spread) {
316             
// we want a nice, big coc, hence we need to tap once from this (higher resolution) texture
317             dofBlurMaterial.SetTexture (
"_TapHigh", from);
318
319             RenderTexture tmp = RenderTexture.GetTemporary (to.width, to.height);
320             
if ((int)iterations > 1) {
321                 BlurHex (
from, to, blurPass, spread, tmp);
322                 
if ((int)iterations > 2) {
323                     dofBlurMaterial.SetVector (
"offsets", new Vector4 (0.0f, spread * oneOverBaseSize, 0.0f, 0.0f));
324                     Graphics.Blit (to, tmp, dofBlurMaterial, blurPass);
325                     dofBlurMaterial.SetVector (
"offsets", new Vector4 (spread / widthOverHeight * oneOverBaseSize, 0.0f, 0.0f, 0.0f));
326                     Graphics.Blit (tmp, to, dofBlurMaterial, blurPass);
327                 }
328             }
329             
else {
330                 dofBlurMaterial.SetVector (
"offsets", new Vector4 (0.0f, spread * oneOverBaseSize, 0.0f, 0.0f));
331                 Graphics.Blit (
from, tmp, dofBlurMaterial, blurPass);
332                 dofBlurMaterial.SetVector (
"offsets", new Vector4 (spread / widthOverHeight * oneOverBaseSize, 0.0f, 0.0f, 0.0f));
333                 Graphics.Blit (tmp, to, dofBlurMaterial, blurPass);
334             }
335             RenderTexture.ReleaseTemporary (tmp);
336         }
337
338         
void BlurHex ( RenderTexture from, RenderTexture to, int blurPass, float spread, RenderTexture tmp) {
339             dofBlurMaterial.SetVector (
"offsets", new Vector4 (0.0f, spread * oneOverBaseSize, 0.0f, 0.0f));
340             Graphics.Blit (
from, tmp, dofBlurMaterial, blurPass);
341             dofBlurMaterial.SetVector (
"offsets", new Vector4 (spread / widthOverHeight * oneOverBaseSize, 0.0f, 0.0f, 0.0f));
342             Graphics.Blit (tmp, to, dofBlurMaterial, blurPass);
343             dofBlurMaterial.SetVector (
"offsets", new Vector4 (spread / widthOverHeight * oneOverBaseSize, spread * oneOverBaseSize, 0.0f, 0.0f));
344             Graphics.Blit (to, tmp, dofBlurMaterial, blurPass);
345             dofBlurMaterial.SetVector (
"offsets", new Vector4 (spread / widthOverHeight * oneOverBaseSize, -spread * oneOverBaseSize, 0.0f, 0.0f));
346             Graphics.Blit (tmp, to, dofBlurMaterial, blurPass);
347         }
348
349         
void Downsample ( RenderTexture from, RenderTexture to) {
350             dofMaterial.SetVector (
"_InvRenderTargetSize", new Vector4 (1.0f / (1.0f * to.width), 1.0f / (1.0f * to.height), 0.0f, 0.0f));
351             Graphics.Blit (
from, to, dofMaterial, SMOOTH_DOWNSAMPLE_PASS);
352         }
353
354         
void AddBokeh ( RenderTexture bokehInfo, RenderTexture tempTex, RenderTexture finalTarget) {
355             
if (bokehMaterial) {
356                 
var meshes = Quads.GetMeshes (tempTex.width, tempTex.height); // quads: exchanging more triangles with less overdraw
357
358                 RenderTexture.active = tempTex;
359                 GL.Clear (
false, true, new Color (0.0f, 0.0f, 0.0f, 0.0f));
360
361                 GL.PushMatrix ();
362                 GL.LoadIdentity ();
363
364                 
// point filter mode is important, otherwise we get bokeh shape & size artefacts
365                 bokehInfo.filterMode = FilterMode.Point;
366
367                 
float arW = (bokehInfo.width * 1.0f) / (bokehInfo.height * 1.0f);
368                 
float sc = 2.0f / (1.0f * bokehInfo.width);
369                 sc += bokehScale * maxBlurSpread * BOKEH_EXTRA_BLUR * oneOverBaseSize;
370
371                 bokehMaterial.SetTexture (
"_Source", bokehInfo);
372                 bokehMaterial.SetTexture (
"_MainTex", bokehTexture);
373                 bokehMaterial.SetVector (
"_ArScale",new Vector4 (sc, sc * arW, 0.5f, 0.5f * arW));
374                 bokehMaterial.SetFloat (
"_Intensity", bokehIntensity);
375                 bokehMaterial.SetPass (
0);
376
377                 
foreach(Mesh m in meshes)
378                     
if (m) Graphics.DrawMeshNow (m, Matrix4x4.identity);
379
380                 GL.PopMatrix ();
381
382                 Graphics.Blit (tempTex, finalTarget, dofMaterial,
8);
383
384                 
// important to set back as we sample from this later on
385                 bokehInfo.filterMode = FilterMode.Bilinear;
386             }
387         }
388
389
390         
void ReleaseTextures () {
391             
if (foregroundTexture) RenderTexture.ReleaseTemporary (foregroundTexture);
392             
if (finalDefocus) RenderTexture.ReleaseTemporary (finalDefocus);
393             
if (mediumRezWorkTexture) RenderTexture.ReleaseTemporary (mediumRezWorkTexture);
394             
if (lowRezWorkTexture) RenderTexture.ReleaseTemporary (lowRezWorkTexture);
395             
if (bokehSource) RenderTexture.ReleaseTemporary (bokehSource);
396             
if (bokehSource2) RenderTexture.ReleaseTemporary (bokehSource2);
397         }
398
399         
void AllocateTextures ( bool blurForeground, RenderTexture source, int divider, int lowTexDivider) {
400             foregroundTexture =
null;
401             
if (blurForeground)
402                 foregroundTexture = RenderTexture.GetTemporary (source.width, source.height,
0);
403             mediumRezWorkTexture = RenderTexture.GetTemporary (source.width / divider, source.height / divider,
0);
404             finalDefocus = RenderTexture.GetTemporary (source.width / divider, source.height / divider,
0);
405             lowRezWorkTexture = RenderTexture.GetTemporary (source.width / lowTexDivider, source.height / lowTexDivider,
0);
406             bokehSource =
null;
407             bokehSource2 =
null;
408             
if (bokeh) {
409                 bokehSource = RenderTexture.GetTemporary (source.width / (lowTexDivider * bokehDownsample), source.height / (lowTexDivider * bokehDownsample),
0, RenderTextureFormat.ARGBHalf);
410                 bokehSource2 = RenderTexture.GetTemporary (source.width / (lowTexDivider * bokehDownsample), source.height / (lowTexDivider * bokehDownsample),
0, RenderTextureFormat.ARGBHalf);
411                 bokehSource.filterMode = FilterMode.Bilinear;
412                 bokehSource2.filterMode = FilterMode.Bilinear;
413                 RenderTexture.active = bokehSource2;
414                 GL.Clear (
false, true, new Color(0.0f, 0.0f, 0.0f, 0.0f));
415             }
416
417             
// to make sure: always use bilinear filter setting
418
419             source.filterMode = FilterMode.Bilinear;
420             finalDefocus.filterMode = FilterMode.Bilinear;
421             mediumRezWorkTexture.filterMode = FilterMode.Bilinear;
422             lowRezWorkTexture.filterMode = FilterMode.Bilinear;
423             
if (foregroundTexture)
424                 foregroundTexture.filterMode = FilterMode.Bilinear;
425         }
426     }
427 }


Gõ tìm kiếm nhanh...