7 [RequireComponent (typeof(Camera))]
8 [AddComponentMenu (
"Image Effects/Camera/Depth of Field (deprecated)") ]
14 BackgroundAndForeground = 2,
35 BackgroundAndForeground = 0x3,
38 static private int SMOOTH_DOWNSAMPLE_PASS = 6;
39 static private float BOKEH_EXTRA_BLUR = 2.0f;
43 public bool simpleTweakMode =
true;
45 public float focalPoint = 1.0f;
46 public float smoothness = 0.5f;
48 public float focalZDistance = 0.0f;
49 public float focalZStartCurve = 1.0f;
50 public float focalZEndCurve = 1.0f;
52 private float focalStartCurve = 2.0f;
53 private float focalEndCurve = 2.0f;
54 private float focalDistance01 = 0.1f;
56 public Transform objectFocus = null;
57 public float focalSize = 0.0f;
60 public float maxBlurSpread = 1.75f;
62 public float foregroundBlurExtrude = 1.15f;
65 private Material dofBlurMaterial = null;
68 private Material dofMaterial = null;
70 public bool visualize =
false;
73 private float widthOverHeight = 1.25f;
74 private float oneOverBaseSize = 1.0f / 512.0f;
76 public bool bokeh =
false;
77 public bool bokehSupport =
true;
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;
90 dofBlurMaterial = CheckShaderAndCreateMaterial (dofBlurShader, dofBlurMaterial);
91 dofMaterial = CheckShaderAndCreateMaterial (dofShader,dofMaterial);
92 bokehSupport = bokehShader.isSupported;
94 if (bokeh && bokehSupport && bokehShader)
95 bokehMaterial = CheckShaderAndCreateMaterial (bokehShader, bokehMaterial);
102 dofBlurMaterial = CheckShaderAndCreateMaterial (dofBlurShader, dofBlurMaterial);
103 dofMaterial = CheckShaderAndCreateMaterial (dofShader,dofMaterial);
104 bokehSupport = bokehShader.isSupported;
106 if (bokeh && bokehSupport && bokehShader)
107 bokehMaterial = CheckShaderAndCreateMaterial (bokehShader, bokehMaterial);
110 ReportAutoDisable ();
119 _camera = GetComponent<Camera>();
120 _camera.depthTextureMode |= DepthTextureMode.Depth;
124 return _camera.WorldToViewportPoint((worldDist-_camera.nearClipPlane) * _camera.transform.forward + _camera.transform.position).z / (_camera.farClipPlane-_camera.nearClipPlane);
137 int lowTexDivider = baseDivider;
142 return lowTexDivider;
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;
153 if (CheckResources()==
false) {
154 Graphics.Blit (source, destination);
158 if (smoothness < 0.1f)
163 bokeh = bokeh && bokehSupport;
164 float bokehBlurAmplifier = bokeh ? BOKEH_EXTRA_BLUR : 1.0f;
167 float focal01Size = focalSize / (_camera.farClipPlane - _camera.nearClipPlane);;
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));
177 var vpPoint= _camera.WorldToViewportPoint (objectFocus.position);
178 vpPoint.z = (vpPoint.z) / (_camera.farClipPlane);
179 focalDistance01 = vpPoint.z;
182 focalDistance01 = FocalDistance01 (focalZDistance);
184 focalStartCurve = focalZStartCurve;
185 focalEndCurve = focalZEndCurve;
186 blurForeground = blurForeground && (focalPoint > (_camera.nearClipPlane + Mathf.Epsilon));
189 widthOverHeight = (1.0f * source.width) / (1.0f * source.height);
190 oneOverBaseSize = 1.0f / 512.0f;
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));
196 int divider = GetDividerBasedOnQuality ();
197 int lowTexDivider = GetLowResolutionDividerBasedOnQuality (divider);
199 AllocateTextures (blurForeground, source, divider, lowTexDivider);
203 Graphics.Blit (source, source, dofMaterial, 3);
206 Downsample (source, mediumRezWorkTexture);
211 Blur (mediumRezWorkTexture, mediumRezWorkTexture,
DofBlurriness.Low, 4, maxBlurSpread);
215 dofMaterial.SetVector (
"_Threshhold",
new Vector4(bokehThresholdContrast, bokehThresholdLuminance, 0.95f, 0.0f));
218 Graphics.Blit (mediumRezWorkTexture, bokehSource2, dofMaterial, 11);
222 Graphics.Blit (mediumRezWorkTexture, lowRezWorkTexture);
228 Blur (lowRezWorkTexture, lowRezWorkTexture, bluriness, 0, maxBlurSpread * bokehBlurAmplifier);
232 Downsample (mediumRezWorkTexture, lowRezWorkTexture);
233 Blur (lowRezWorkTexture, lowRezWorkTexture, bluriness, 0, maxBlurSpread);
236 dofBlurMaterial.SetTexture (
"_TapLow", lowRezWorkTexture);
237 dofBlurMaterial.SetTexture (
"_TapMedium", mediumRezWorkTexture);
238 Graphics.Blit (null, finalDefocus, dofBlurMaterial, 3);
242 AddBokeh (bokehSource2, bokehSource, finalDefocus);
244 dofMaterial.SetTexture (
"_TapLowBackground", finalDefocus);
245 dofMaterial.SetTexture (
"_TapMedium", mediumRezWorkTexture);
248 Graphics.Blit (source, blurForeground ? foregroundTexture : destination, dofMaterial, visualize ? 2 : 0);
251 if (blurForeground) {
253 Graphics.Blit (foregroundTexture, source, dofMaterial, 5);
256 Downsample (source, mediumRezWorkTexture);
261 BlurFg (mediumRezWorkTexture, mediumRezWorkTexture,
DofBlurriness.Low, 2, maxBlurSpread);
265 dofMaterial.SetVector (
"_Threshhold",
new Vector4(bokehThresholdContrast * 0.5f, bokehThresholdLuminance, 0.0f, 0.0f));
268 Graphics.Blit (mediumRezWorkTexture, bokehSource2, dofMaterial, 11);
272 Graphics.Blit (mediumRezWorkTexture, lowRezWorkTexture);
275 BlurFg (lowRezWorkTexture, lowRezWorkTexture, bluriness, 1, maxBlurSpread * bokehBlurAmplifier);
279 BlurFg (mediumRezWorkTexture, lowRezWorkTexture, bluriness, 1, maxBlurSpread);
283 Graphics.Blit (lowRezWorkTexture, finalDefocus);
285 dofMaterial.SetTexture (
"_TapLowForeground", finalDefocus);
286 Graphics.Blit (source, destination, dofMaterial, visualize ? 1 : 4);
289 AddBokeh (bokehSource2, bokehSource, destination);
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);
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);
312 RenderTexture.ReleaseTemporary (tmp);
315 void BlurFg ( RenderTexture from, RenderTexture to,
DofBlurriness iterations,
int blurPass,
float spread) {
317 dofBlurMaterial.SetTexture (
"_TapHigh", from);
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);
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);
335 RenderTexture.ReleaseTemporary (tmp);
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);
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);
354 void AddBokeh ( RenderTexture bokehInfo, RenderTexture tempTex, RenderTexture finalTarget) {
358 RenderTexture.active = tempTex;
359 GL.Clear (
false,
true,
new Color (0.0f, 0.0f, 0.0f, 0.0f));
365 bokehInfo.filterMode = FilterMode.Point;
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;
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);
377 foreach(Mesh m
in meshes)
378 if (m) Graphics.DrawMeshNow (m, Matrix4x4.identity);
382 Graphics.Blit (tempTex, finalTarget, dofMaterial, 8);
385 bokehInfo.filterMode = FilterMode.Bilinear;
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);
399 void AllocateTextures (
bool blurForeground, RenderTexture source,
int divider,
int lowTexDivider) {
400 foregroundTexture = null;
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);
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));
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;
float FocalDistance01(float worldDist)
void BlurHex(RenderTexture from, RenderTexture to, int blurPass, float spread, RenderTexture tmp)
void Blur(RenderTexture from, RenderTexture to, DofBlurriness iterations, int blurPass, float spread)
static Mesh[] GetMeshes(int totalWidth, int totalHeight)
void AddBokeh(RenderTexture bokehInfo, RenderTexture tempTex, RenderTexture finalTarget)
int GetLowResolutionDividerBasedOnQuality(int baseDivider)
override bool CheckResources()
void AllocateTextures(bool blurForeground, RenderTexture source, int divider, int lowTexDivider)
void Downsample(RenderTexture from, RenderTexture to)
void BlurFg(RenderTexture from, RenderTexture to, DofBlurriness iterations, int blurPass, float spread)
int GetDividerBasedOnQuality()
void OnRenderImage(RenderTexture source, RenderTexture destination)