You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
159 lines
5.5 KiB
JavaScript
159 lines
5.5 KiB
JavaScript
|
|
#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 camera.WorldToViewportPoint((worldDist-camera.nearClipPlane) * camera.transform.forward + camera.transform.position).z / (camera.farClipPlane-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 ? (camera.WorldToViewportPoint (focalTransform.position)).z / (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);
|
|
}
|
|
}
|