九月份一篇博都没更新,这段时间一直在unity的坑里爬不起来,感觉真的很绝望啊,仿佛对生活都失去了信心。
渲染问题并没有解决,目前方案只是减轻视觉冲突,降低违和感。项目AR产品也做的越来越艰难,开始经常想一个问题,我从哪里来,我该到哪里去。。。
好吧,唠叨这么多,言归正传,今天说说unity的Post-Processing后期处理的景深 Depth Of Field
官方文档 https://docs.unity3d.com/Manual/PostProcessingOverview.html
先贴完整代码,下载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镜头焦距。
1.Focus Distance具体含义是距离摄像机多远的“距离”拍摄最高清,这个距离是目标点与相机平面的垂直距离,相机平面可以这样确定,1.与nearPlane平面平行,过相机位置点。所以焦距Focus Distance可以通过以下代码求得并设置:
//相机辅助平面
Plane cameraPlane = new Plane(camera.transform.forward,camera.transform.position);
//计算目标距离相机的距离,焦点距离 focusDistance
float focusDistance = cameraPlane.GetDistanceToPoint (focusPosition);
2.focalLength 镜头焦距,通过景深 nearBlurPosition 和 farBlurPosition计算得到。景深计算方式如下:
看成景深、镜头焦距、光圈值的一个方程,将镜头焦距作为要求的跟,根据一元二次方程的解:
得到 :