text: 
  #pragma strict
  
  @script ExecuteInEditMode
  @script RequireComponent (Camera)
  @script AddComponentMenu ("Image Effects/Depth of Field (HDR, Scatter, Lens Blur)") 
  
  class DepthOfFieldScatter extends PostEffectsBase {	
      public var visualizeFocus : boolean = false;
  	
  	public var focalLength : float = 10.0f;
  	public var focalSize : float = 0.05f; 
  	public var aperture : float = 10.0f;
  
  	public var focalTransform : Transform = null;
  
  	public var maxBlurSize : float = 2.0f; 
  	
  	public enum BlurQuality {
  		Low = 0,
  		Medium = 1,
  		High = 2,
  	}
  	
  	public enum BlurResolution {
  		High = 0,
  		Low = 1,
  	}
  	 
  	public var blurQuality : BlurQuality = BlurQuality.Medium;
  	public var blurResolution : BlurResolution = BlurResolution.Low;
  	
      public var foregroundBlur : boolean = false;	
  	public var foregroundOverlap : float = 0.55f;
  	
  	public var dofHdrShader : Shader;		
  	
  	private var focalDistance01 : float = 10.0f;	
  	private var dofHdrMaterial : Material = null;		        
          	
  	function CheckResources () : boolean {		
  		CheckSupport (true);
  	
  		dofHdrMaterial = CheckShaderAndCreateMaterial (dofHdrShader, dofHdrMaterial); 
  		
  		if(!isSupported)
  			ReportAutoDisable ();
  		return isSupported;		  
  	}
  	
  	function FocalDistance01 (worldDist : float) : float {
  		return GetComponent.<Camera>().WorldToViewportPoint((worldDist-GetComponent.<Camera>().nearClipPlane) * GetComponent.<Camera>().transform.forward + GetComponent.<Camera>().transform.position).z / (GetComponent.<Camera>().farClipPlane-GetComponent.<Camera>().nearClipPlane);	
  	}
  			
  	function OnRenderImage (source : RenderTexture, destination : RenderTexture) {		
  		if(CheckResources () == false) {
  			Graphics.Blit (source, destination);
  			return;
  		}
  		
  		var i : int = 0;
  		var internalBlurWidth : float = maxBlurSize;
  		var blurRtDivider : int = blurResolution == BlurResolution.High ? 1 : 2;
  		
  		// clamp values so they make sense
  
  		if (aperture < 0.0f) aperture = 0.0f;
  		if (maxBlurSize < 0.0f) maxBlurSize = 0.0f;
  		focalSize = Mathf.Clamp(focalSize, 0.0f, 0.3f);
  					
  		// focal & coc calculations
  
  		focalDistance01 = focalTransform ? (GetComponent.<Camera>().WorldToViewportPoint (focalTransform.position)).z / (GetComponent.<Camera>().farClipPlane) : FocalDistance01 (focalLength);
  		
  		var isInHdr : boolean = source.format == RenderTextureFormat.ARGBHalf;
  		
  		var scene : RenderTexture = blurRtDivider > 1 ? RenderTexture.GetTemporary (source.width/blurRtDivider, source.height/blurRtDivider, 0, source.format) : null;			
  		if (scene) scene.filterMode = FilterMode.Bilinear;
  		var rtLow : RenderTexture = RenderTexture.GetTemporary (source.width/(2*blurRtDivider), source.height/(2*blurRtDivider), 0, source.format);		
  		var rtLow2 : RenderTexture = RenderTexture.GetTemporary (source.width/(2*blurRtDivider), source.height/(2*blurRtDivider), 0, source.format);			
  		if (rtLow) rtLow.filterMode = FilterMode.Bilinear;
  		if (rtLow2) rtLow2.filterMode = FilterMode.Bilinear;
  	
  		dofHdrMaterial.SetVector ("_CurveParams", Vector4 (0.0f, focalSize, aperture/10.0f, focalDistance01));
  		
  		// foreground blur
  		
  		if (foregroundBlur) {			
  			var rtLowTmp : RenderTexture = RenderTexture.GetTemporary (source.width/(2*blurRtDivider), source.height/(2*blurRtDivider), 0, source.format);		
  		
  			// Capture foreground CoC only in alpha channel and increase CoC radius
  			Graphics.Blit (source, rtLow2, dofHdrMaterial, 4); 
  			dofHdrMaterial.SetTexture("_FgOverlap", rtLow2); 
  			
  			var fgAdjustment : float = internalBlurWidth * foregroundOverlap * 0.225f; 
  			dofHdrMaterial.SetVector ("_Offsets", Vector4 (0.0f, fgAdjustment , 0.0f, fgAdjustment));
  			Graphics.Blit (rtLow2, rtLowTmp, dofHdrMaterial, 2);
  			dofHdrMaterial.SetVector ("_Offsets", Vector4 (fgAdjustment, 0.0f, 0.0f, fgAdjustment));		
  			Graphics.Blit (rtLowTmp, rtLow, dofHdrMaterial, 2);	 			
  			
  			dofHdrMaterial.SetTexture("_FgOverlap", null); // NEW: not needed anymore
  			// apply adjust FG coc back to high rez coc texture
  			Graphics.Blit(rtLow, source, dofHdrMaterial, 7);	
  			
  			RenderTexture.ReleaseTemporary(rtLowTmp);					
  		}
  		else 
  			dofHdrMaterial.SetTexture("_FgOverlap", null); // ugly FG overlaps as a result
  		
  		// capture remaing CoC (fore & *background*)
  		
  		Graphics.Blit (source, source, dofHdrMaterial, foregroundBlur ? 3 : 0);		
  		
  		var cocRt : RenderTexture = source;
  		
  		if(blurRtDivider>1) {
  			Graphics.Blit (source, scene, dofHdrMaterial, 6);		
  			cocRt = scene;	
  		}
  		
  		// spawn a few low rez parts in high rez image to get a bigger blur
  		// resulting quality is higher than directly blending preblurred buffers
  		
  		Graphics.Blit(cocRt, rtLow2, dofHdrMaterial, 6); 
  		Graphics.Blit(rtLow2, cocRt, dofHdrMaterial, 8);
  		
  		//  blur and apply to color buffer 
  		
  		var blurPassNumber : int = 10;
  		switch(blurQuality) {
  			case BlurQuality.Low:
  				blurPassNumber = blurRtDivider > 1 ? 13 : 10;
  				break;
  			case BlurQuality.Medium:
  				blurPassNumber = blurRtDivider > 1 ? 12 : 11;
  				break;
  			case BlurQuality.High:
  				blurPassNumber = blurRtDivider > 1 ? 15 : 14;
  				break;				
  			default:
  				Debug.Log("DOF couldn't find valid blur quality setting", transform);
  				break;
  		}
  		
  		if(visualizeFocus) {
  			Graphics.Blit (source, destination, dofHdrMaterial, 1);
  		}
  		else { 		 
  			dofHdrMaterial.SetVector ("_Offsets", Vector4 (0.0f, 0.0f , 0.0f, internalBlurWidth));
  			dofHdrMaterial.SetTexture("_LowRez", cocRt); // only needed in low resolution profile. and then, ugh, we get an ugly transition from nonblur -> blur areas
  			Graphics.Blit (source, destination, dofHdrMaterial, blurPassNumber);	 
  		}
  		
  		if(rtLow) RenderTexture.ReleaseTemporary(rtLow);
  		if(rtLow2) RenderTexture.ReleaseTemporary(rtLow2);		
  		if(scene) RenderTexture.ReleaseTemporary(scene); 
  	}	
  }
  