using System; using UnityEngine; [Serializable] [RequireComponent(typeof(Camera))] [AddComponentMenu("Image Effects/Depth of Field (3.4)")] [ExecuteInEditMode] public class DepthOfField34 : PostEffectsBase { [NonSerialized] private static int SMOOTH_DOWNSAMPLE_PASS = 6; [NonSerialized] private static float BOKEH_EXTRA_BLUR = 2f; public Dof34QualitySetting quality; public DofResolution resolution; public bool simpleTweakMode; public float focalPoint; public float smoothness; public float focalZDistance; public float focalZStartCurve; public float focalZEndCurve; private float focalStartCurve; private float focalEndCurve; private float focalDistance01; public Transform objectFocus; public float focalSize; public DofBlurriness bluriness; public float maxBlurSpread; public float foregroundBlurExtrude; public Shader dofBlurShader; private Material dofBlurMaterial; public Shader dofShader; private Material dofMaterial; public bool visualize; public BokehDestination bokehDestination; private float widthOverHeight; private float oneOverBaseSize; public bool bokeh; public bool bokehSupport; public Shader bokehShader; public Texture2D bokehTexture; public float bokehScale; public float bokehIntensity; public float bokehThreshholdContrast; public float bokehThreshholdLuminance; public int bokehDownsample; private Material bokehMaterial; private RenderTexture foregroundTexture; private RenderTexture mediumRezWorkTexture; private RenderTexture finalDefocus; private RenderTexture lowRezWorkTexture; private RenderTexture bokehSource; private RenderTexture bokehSource2; public DepthOfField34() { quality = Dof34QualitySetting.OnlyBackground; resolution = DofResolution.Low; simpleTweakMode = true; focalPoint = 1f; smoothness = 0.5f; focalZStartCurve = 1f; focalZEndCurve = 1f; focalStartCurve = 2f; focalEndCurve = 2f; focalDistance01 = 0.1f; bluriness = DofBlurriness.High; maxBlurSpread = 1.75f; foregroundBlurExtrude = 1.15f; bokehDestination = BokehDestination.Background; widthOverHeight = 1.25f; oneOverBaseSize = 0.001953125f; bokehSupport = true; bokehScale = 2.4f; bokehIntensity = 0.15f; bokehThreshholdContrast = 0.1f; bokehThreshholdLuminance = 0.55f; bokehDownsample = 1; } public virtual void CreateMaterials() { dofBlurMaterial = CheckShaderAndCreateMaterial(dofBlurShader, dofBlurMaterial); dofMaterial = CheckShaderAndCreateMaterial(dofShader, dofMaterial); bokehSupport = bokehShader.isSupported; if (bokeh && bokehSupport && (bool)bokehShader) { bokehMaterial = CheckShaderAndCreateMaterial(bokehShader, bokehMaterial); } } public override bool CheckResources() { CheckSupport(true); dofBlurMaterial = CheckShaderAndCreateMaterial(dofBlurShader, dofBlurMaterial); dofMaterial = CheckShaderAndCreateMaterial(dofShader, dofMaterial); bokehSupport = bokehShader.isSupported; if (bokeh && bokehSupport && (bool)bokehShader) { bokehMaterial = CheckShaderAndCreateMaterial(bokehShader, bokehMaterial); } if (!isSupported) { ReportAutoDisable(); } return isSupported; } public virtual void OnDisable() { Quads.Cleanup(); if ((bool)dofBlurMaterial) { UnityEngine.Object.DestroyImmediate(dofBlurMaterial); } if ((bool)dofMaterial) { UnityEngine.Object.DestroyImmediate(dofMaterial); } if ((bool)bokehMaterial) { UnityEngine.Object.DestroyImmediate(bokehMaterial); } } public override void OnEnable() { GetComponent().depthTextureMode |= DepthTextureMode.Depth; } public virtual float FocalDistance01(float worldDist) { return GetComponent().WorldToViewportPoint((worldDist - GetComponent().nearClipPlane) * GetComponent().transform.forward + GetComponent().transform.position).z / (GetComponent().farClipPlane - GetComponent().nearClipPlane); } public virtual int GetDividerBasedOnQuality() { int result = 1; if (resolution == DofResolution.Medium) { result = 2; } else if (resolution == DofResolution.Low) { result = 2; } return result; } public virtual int GetLowResolutionDividerBasedOnQuality(int baseDivider) { int num = baseDivider; if (resolution == DofResolution.High) { num *= 2; } if (resolution == DofResolution.Low) { num *= 2; } return num; } public virtual void OnRenderImage(RenderTexture source, RenderTexture destination) { if (!CheckResources()) { Graphics.Blit(source, destination); return; } if (!(smoothness >= 0.1f)) { smoothness = 0.1f; } bool num = bokeh; if (num) { num = bokehSupport; } bokeh = num; float num2 = ((!bokeh) ? 1f : BOKEH_EXTRA_BLUR); bool flag = quality > Dof34QualitySetting.OnlyBackground; float num3 = focalSize / (GetComponent().farClipPlane - GetComponent().nearClipPlane); if (simpleTweakMode) { focalDistance01 = ((!objectFocus) ? FocalDistance01(focalPoint) : (GetComponent().WorldToViewportPoint(objectFocus.position).z / GetComponent().farClipPlane)); focalStartCurve = focalDistance01 * smoothness; focalEndCurve = focalStartCurve; bool num4 = flag; if (num4) { num4 = focalPoint > GetComponent().nearClipPlane + float.Epsilon; } flag = num4; } else { if ((bool)objectFocus) { Vector3 vector = GetComponent().WorldToViewportPoint(objectFocus.position); vector.z /= GetComponent().farClipPlane; focalDistance01 = vector.z; } else { focalDistance01 = FocalDistance01(focalZDistance); } focalStartCurve = focalZStartCurve; focalEndCurve = focalZEndCurve; bool num5 = flag; if (num5) { num5 = focalPoint > GetComponent().nearClipPlane + float.Epsilon; } flag = num5; } widthOverHeight = 1f * (float)source.width / (1f * (float)source.height); oneOverBaseSize = 0.001953125f; dofMaterial.SetFloat("_ForegroundBlurExtrude", foregroundBlurExtrude); dofMaterial.SetVector("_CurveParams", new Vector4((!simpleTweakMode) ? focalStartCurve : (1f / focalStartCurve), (!simpleTweakMode) ? focalEndCurve : (1f / focalEndCurve), num3 * 0.5f, focalDistance01)); dofMaterial.SetVector("_InvRenderTargetSize", new Vector4(1f / (1f * (float)source.width), 1f / (1f * (float)source.height), 0f, 0f)); int dividerBasedOnQuality = GetDividerBasedOnQuality(); int lowResolutionDividerBasedOnQuality = GetLowResolutionDividerBasedOnQuality(dividerBasedOnQuality); AllocateTextures(flag, source, dividerBasedOnQuality, lowResolutionDividerBasedOnQuality); Graphics.Blit(source, source, dofMaterial, 3); Downsample(source, mediumRezWorkTexture); Blur(mediumRezWorkTexture, mediumRezWorkTexture, DofBlurriness.Low, 4, maxBlurSpread); if (bokeh && (bokehDestination & BokehDestination.Background) != 0) { dofMaterial.SetVector("_Threshhold", new Vector4(bokehThreshholdContrast, bokehThreshholdLuminance, 0.95f, 0f)); Graphics.Blit(mediumRezWorkTexture, bokehSource2, dofMaterial, 11); Graphics.Blit(mediumRezWorkTexture, lowRezWorkTexture); Blur(lowRezWorkTexture, lowRezWorkTexture, bluriness, 0, maxBlurSpread * num2); } else { Downsample(mediumRezWorkTexture, lowRezWorkTexture); Blur(lowRezWorkTexture, lowRezWorkTexture, bluriness, 0, maxBlurSpread); } dofBlurMaterial.SetTexture("_TapLow", lowRezWorkTexture); dofBlurMaterial.SetTexture("_TapMedium", mediumRezWorkTexture); Graphics.Blit(null, finalDefocus, dofBlurMaterial, 3); if (bokeh && (bokehDestination & BokehDestination.Background) != 0) { AddBokeh(bokehSource2, bokehSource, finalDefocus); } dofMaterial.SetTexture("_TapLowBackground", finalDefocus); dofMaterial.SetTexture("_TapMedium", mediumRezWorkTexture); Graphics.Blit(source, (!flag) ? destination : foregroundTexture, dofMaterial, visualize ? 2 : 0); if (flag) { Graphics.Blit(foregroundTexture, source, dofMaterial, 5); Downsample(source, mediumRezWorkTexture); BlurFg(mediumRezWorkTexture, mediumRezWorkTexture, DofBlurriness.Low, 2, maxBlurSpread); if (bokeh && (bokehDestination & BokehDestination.Foreground) != 0) { dofMaterial.SetVector("_Threshhold", new Vector4(bokehThreshholdContrast * 0.5f, bokehThreshholdLuminance, 0f, 0f)); Graphics.Blit(mediumRezWorkTexture, bokehSource2, dofMaterial, 11); Graphics.Blit(mediumRezWorkTexture, lowRezWorkTexture); BlurFg(lowRezWorkTexture, lowRezWorkTexture, bluriness, 1, maxBlurSpread * num2); } else { BlurFg(mediumRezWorkTexture, lowRezWorkTexture, bluriness, 1, maxBlurSpread); } Graphics.Blit(lowRezWorkTexture, finalDefocus); dofMaterial.SetTexture("_TapLowForeground", finalDefocus); Graphics.Blit(source, destination, dofMaterial, visualize ? 1 : 4); if (bokeh && (bokehDestination & BokehDestination.Foreground) != 0) { AddBokeh(bokehSource2, bokehSource, destination); } } ReleaseTextures(); } public virtual void Blur(RenderTexture from, RenderTexture to, DofBlurriness iterations, int blurPass, float spread) { RenderTexture temporary = RenderTexture.GetTemporary(to.width, to.height); if (iterations > DofBlurriness.Low) { BlurHex(from, to, blurPass, spread, temporary); if (iterations > DofBlurriness.High) { dofBlurMaterial.SetVector("offsets", new Vector4(0f, spread * oneOverBaseSize, 0f, 0f)); Graphics.Blit(to, temporary, dofBlurMaterial, blurPass); dofBlurMaterial.SetVector("offsets", new Vector4(spread / widthOverHeight * oneOverBaseSize, 0f, 0f, 0f)); Graphics.Blit(temporary, to, dofBlurMaterial, blurPass); } } else { dofBlurMaterial.SetVector("offsets", new Vector4(0f, spread * oneOverBaseSize, 0f, 0f)); Graphics.Blit(from, temporary, dofBlurMaterial, blurPass); dofBlurMaterial.SetVector("offsets", new Vector4(spread / widthOverHeight * oneOverBaseSize, 0f, 0f, 0f)); Graphics.Blit(temporary, to, dofBlurMaterial, blurPass); } RenderTexture.ReleaseTemporary(temporary); } public virtual void BlurFg(RenderTexture from, RenderTexture to, DofBlurriness iterations, int blurPass, float spread) { dofBlurMaterial.SetTexture("_TapHigh", from); RenderTexture temporary = RenderTexture.GetTemporary(to.width, to.height); if (iterations > DofBlurriness.Low) { BlurHex(from, to, blurPass, spread, temporary); if (iterations > DofBlurriness.High) { dofBlurMaterial.SetVector("offsets", new Vector4(0f, spread * oneOverBaseSize, 0f, 0f)); Graphics.Blit(to, temporary, dofBlurMaterial, blurPass); dofBlurMaterial.SetVector("offsets", new Vector4(spread / widthOverHeight * oneOverBaseSize, 0f, 0f, 0f)); Graphics.Blit(temporary, to, dofBlurMaterial, blurPass); } } else { dofBlurMaterial.SetVector("offsets", new Vector4(0f, spread * oneOverBaseSize, 0f, 0f)); Graphics.Blit(from, temporary, dofBlurMaterial, blurPass); dofBlurMaterial.SetVector("offsets", new Vector4(spread / widthOverHeight * oneOverBaseSize, 0f, 0f, 0f)); Graphics.Blit(temporary, to, dofBlurMaterial, blurPass); } RenderTexture.ReleaseTemporary(temporary); } public virtual void BlurHex(RenderTexture from, RenderTexture to, int blurPass, float spread, RenderTexture tmp) { dofBlurMaterial.SetVector("offsets", new Vector4(0f, spread * oneOverBaseSize, 0f, 0f)); Graphics.Blit(from, tmp, dofBlurMaterial, blurPass); dofBlurMaterial.SetVector("offsets", new Vector4(spread / widthOverHeight * oneOverBaseSize, 0f, 0f, 0f)); Graphics.Blit(tmp, to, dofBlurMaterial, blurPass); dofBlurMaterial.SetVector("offsets", new Vector4(spread / widthOverHeight * oneOverBaseSize, spread * oneOverBaseSize, 0f, 0f)); Graphics.Blit(to, tmp, dofBlurMaterial, blurPass); dofBlurMaterial.SetVector("offsets", new Vector4(spread / widthOverHeight * oneOverBaseSize, (0f - spread) * oneOverBaseSize, 0f, 0f)); Graphics.Blit(tmp, to, dofBlurMaterial, blurPass); } public virtual void Downsample(RenderTexture from, RenderTexture to) { dofMaterial.SetVector("_InvRenderTargetSize", new Vector4(1f / (1f * (float)to.width), 1f / (1f * (float)to.height), 0f, 0f)); Graphics.Blit(from, to, dofMaterial, SMOOTH_DOWNSAMPLE_PASS); } public virtual void AddBokeh(RenderTexture bokehInfo, RenderTexture tempTex, RenderTexture finalTarget) { if (!bokehMaterial) { return; } Mesh[] meshes = Quads.GetMeshes(tempTex.width, tempTex.height); RenderTexture.active = tempTex; GL.Clear(false, true, new Color(0f, 0f, 0f, 0f)); GL.PushMatrix(); GL.LoadIdentity(); bokehInfo.filterMode = FilterMode.Point; float num = (float)bokehInfo.width * 1f / ((float)bokehInfo.height * 1f); float num2 = 2f / (1f * (float)bokehInfo.width); num2 += bokehScale * maxBlurSpread * BOKEH_EXTRA_BLUR * oneOverBaseSize; bokehMaterial.SetTexture("_Source", bokehInfo); bokehMaterial.SetTexture("_MainTex", bokehTexture); bokehMaterial.SetVector("_ArScale", new Vector4(num2, num2 * num, 0.5f, 0.5f * num)); bokehMaterial.SetFloat("_Intensity", bokehIntensity); bokehMaterial.SetPass(0); int i = 0; Mesh[] array = meshes; for (int length = array.Length; i < length; i++) { if ((bool)array[i]) { Graphics.DrawMeshNow(array[i], Matrix4x4.identity); } } GL.PopMatrix(); Graphics.Blit(tempTex, finalTarget, dofMaterial, 8); bokehInfo.filterMode = FilterMode.Bilinear; } public virtual void ReleaseTextures() { if ((bool)foregroundTexture) { RenderTexture.ReleaseTemporary(foregroundTexture); } if ((bool)finalDefocus) { RenderTexture.ReleaseTemporary(finalDefocus); } if ((bool)mediumRezWorkTexture) { RenderTexture.ReleaseTemporary(mediumRezWorkTexture); } if ((bool)lowRezWorkTexture) { RenderTexture.ReleaseTemporary(lowRezWorkTexture); } if ((bool)bokehSource) { RenderTexture.ReleaseTemporary(bokehSource); } if ((bool)bokehSource2) { RenderTexture.ReleaseTemporary(bokehSource2); } } public virtual void AllocateTextures(bool blurForeground, RenderTexture source, int divider, int lowTexDivider) { foregroundTexture = null; if (blurForeground) { foregroundTexture = RenderTexture.GetTemporary(source.width, source.height, 0); } mediumRezWorkTexture = RenderTexture.GetTemporary(source.width / divider, source.height / divider, 0); finalDefocus = RenderTexture.GetTemporary(source.width / divider, source.height / divider, 0); lowRezWorkTexture = RenderTexture.GetTemporary(source.width / lowTexDivider, source.height / lowTexDivider, 0); bokehSource = null; bokehSource2 = null; if (bokeh) { bokehSource = RenderTexture.GetTemporary(source.width / (lowTexDivider * bokehDownsample), source.height / (lowTexDivider * bokehDownsample), 0, RenderTextureFormat.ARGBHalf); bokehSource2 = RenderTexture.GetTemporary(source.width / (lowTexDivider * bokehDownsample), source.height / (lowTexDivider * bokehDownsample), 0, RenderTextureFormat.ARGBHalf); bokehSource.filterMode = FilterMode.Bilinear; bokehSource2.filterMode = FilterMode.Bilinear; RenderTexture.active = bokehSource2; GL.Clear(false, true, new Color(0f, 0f, 0f, 0f)); } source.filterMode = FilterMode.Bilinear; finalDefocus.filterMode = FilterMode.Bilinear; mediumRezWorkTexture.filterMode = FilterMode.Bilinear; lowRezWorkTexture.filterMode = FilterMode.Bilinear; if ((bool)foregroundTexture) { foregroundTexture.filterMode = FilterMode.Bilinear; } } public override void Main() { } }