九月份一篇博都沒更新,這段時間一直在unity的坑裏爬不起來,感受真的很絕望啊,彷彿對生活都失去了信心。html
渲染問題並無解決,目前方案只是減輕視覺衝突,下降違和感。項目AR產品也作的愈來愈艱難,開始常常想一個問題,我從哪裏來,我該到哪裏去。。。前端
好吧,嘮叨這麼多,言歸正傳,今天說說unity的Post-Processing後期處理的景深 Depth Of Fieldpost
官方文檔 https://docs.unity3d.com/Manual/PostProcessingOverview.htmlthis
先貼完整代碼,下載PostProcessing插件並import,將下面腳本掛在camera上,運行插件
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.PostProcessing; public class DepthOfFieldTest : MonoBehaviour { public Transform nearBlurTarget; public Transform farBlurTarget; private PostProcessingProfile profile; // Use this for initialization void Start () { AddPostProcessing (); BlurEffect(); } /// <summary> /// Adds the post processing 後期處理特效. /// </summary> public void AddPostProcessing () { PostProcessingBehaviour postProcessingBehaviour = gameObject.AddComponent<PostProcessingBehaviour> (); this.profile = new PostProcessingProfile (); // this.profile = Resources.Load ("GreenArchPOST") as PostProcessingProfile; postProcessingBehaviour.profile = profile; profile.depthOfField.enabled = false; profile.antialiasing.enabled = true; profile.ambientOcclusion.enabled = true; // AO參數設置,主要是要勾選ambientOnly選項 AmbientOcclusionModel.Settings aoSettings = new AmbientOcclusionModel.Settings () { intensity = 1f, radius = 0.3f, sampleCount = AmbientOcclusionModel.SampleCount.Medium, downsampling = true, forceForwardCompatibility = false, ambientOnly = true, highPrecision = false }; profile.ambientOcclusion.settings = aoSettings; } /// <summary> /// Blurs the effect景深模糊效果. /// </summary> /// <param name="jo">Jo.</param> public void BlurEffect() { DepthOfFieldModel depthOfField = this.profile.depthOfField; Vector3 focusPosition = (1.5f * nearBlurTarget.position + farBlurTarget.position) / 2.5f; Plane cameraPlane = new Plane(gameObject.transform.forward, gameObject.transform.position); float focusDistance = cameraPlane.GetDistanceToPoint (focusPosition); float depthOfFeild = Mathf.Abs (cameraPlane.GetDistanceToPoint (farBlurTarget.position) - cameraPlane.GetDistanceToPoint (nearBlurTarget.position)); // 根據公式計算 景深ΔL=ΔL1+ΔL2=(2f^2FδL^2)/(f^4-F^2δ^2L^2) // 允許彌散圓直徑 δ=0.035mm float ap = 5.6f * 0.035f / 1000f; float focusDistancex2 = Mathf.Pow (focusDistance, 2f); float lengthx2 = ap * focusDistancex2 + ap * focusDistance * Mathf.Sqrt(focusDistancex2 + Mathf.Pow (depthOfFeild, 2f)); float focalLengthByMath = Mathf.Sqrt (lengthx2 / depthOfFeild) * 1000f; Debug.Log ("清晰點距相機距離:" + focusDistance); Debug.Log ("景深:" + depthOfFeild); Debug.Log ("相機焦距 focalLengthByMath (mm):" + focalLengthByMath); depthOfField.enabled = true; UnityEngine.PostProcessing.DepthOfFieldModel.Settings depthOfFieldSetting = new UnityEngine.PostProcessing.DepthOfFieldModel.Settings { focusDistance = focusDistance, aperture = 5.6f, focalLength = focalLengthByMath, useCameraFov = false, kernelSize = DepthOfFieldModel.KernelSize.Medium }; depthOfField.settings = depthOfFieldSetting; } }
採用PostProcessing攝像機後期處理特效,Depth Of Field模塊,根據前端給的三個參數計算Focus Distance 焦點距離 和 focalLength鏡頭焦距。3d
1.Focus Distance具體含義是距離攝像機多遠的「距離」拍攝最高清,這個距離是目標點與相機平面的垂直距離,相機平面能夠這樣肯定,1.與nearPlane平面平行,過相機位置點。因此焦距Focus Distance能夠經過如下代碼求得並設置:orm
//相機輔助平面htm
Plane cameraPlane = new Plane(camera.transform.forward,camera.transform.position);blog
//計算目標距離相機的距離,焦點距離 focusDistanceci
float focusDistance = cameraPlane.GetDistanceToPoint (focusPosition);
2.focalLength 鏡頭焦距,經過景深 nearBlurPosition 和 farBlurPosition計算獲得。景深計算方式以下:
當作景深、鏡頭焦距、光圈值的一個方程,將鏡頭焦距做爲要求的跟,根據一元二次方程的解:
獲得 :