| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105 |
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- [ExecuteInEditMode]
- [RequireComponent(typeof(Camera))]
- public class DepthOfFieldPostEffect : MonoBehaviour
- {
- public Material mat;
- [Range(0.0f, 100.0f)]
- public float focalDistance = 10.0f;
- [Range(0.0f, 100.0f)]
- public float nearBlurScale = 0.0f;
- [Range(0.0f, 1000.0f)]
- public float farBlurScale = 50.0f;
- //分辨率
- public int downSample = 1;
- //採樣率
- public int samplerScale = 1;
- private Camera mCam;
- public Camera Cam
- {
- get
- {
- if (mCam == null)
- {
- mCam = GetComponent<Camera>();
- }
- return mCam;
- }
- }
- private void OnEnable()
- {
- if(Cam != null)
- {
- Cam.depthTextureMode |= DepthTextureMode.Depth;
- }
- }
- private void OnDisable()
- {
- if(Cam != null)
- {
- Cam.depthTextureMode &= ~DepthTextureMode.Depth;
- }
- }
- // Start is called before the first frame update
- void Start()
- {
-
- }
- // Update is called once per frame
- void Update()
- {
-
- }
- private void OnRenderImage(RenderTexture src, RenderTexture dest)
- {
- if(mat!=null)
- {
- //首先將我們設置的焦點限制在遠近裁剪面之間
- Mathf.Clamp(focalDistance, Cam.nearClipPlane, Cam.farClipPlane);
- //申請兩塊RT,並且分辨率按照downSameple降低
- RenderTexture temp1 = RenderTexture.GetTemporary(src.width >> downSample, src.height >> downSample, 0, src.format);
- RenderTexture temp2 = RenderTexture.GetTemporary(src.width >> downSample, src.height >> downSample, 0, src.format);
- //直接將場景圖拷貝到低分辨率的RT上達到降分辨率的效果
- Graphics.Blit(src, temp1);
- //高斯模糊,兩次模糊,橫向縱向,使用pass0進行高斯模糊
- mat.SetVector("_offsets", new Vector4(0, samplerScale, 0, 0));
- Graphics.Blit(temp1, temp2, mat, 0);
- mat.SetVector("_offsets", new Vector4(samplerScale, 0, 0, 0));
- Graphics.Blit(temp2, temp1, mat, 0);
- //景深操作,景深需要兩的模糊效果圖我們通過_BlurTex變量傳入shader
- mat.SetTexture("_BlurTex", temp1);
- //設置shader的參數,主要是焦點和遠近模糊的權重,權重可以控制插值時使用模糊圖片的權重
- mat.SetFloat("_focalDistance", FocalDistance01(focalDistance));
- mat.SetFloat("_nearBlurScale", nearBlurScale);
- mat.SetFloat("_farBlurScale", farBlurScale);
- //使用pass1進行景深效果計算,清晰場景圖直接從source輸入到shader的_MainTex中
- Graphics.Blit(src, dest, mat, 1);
- //釋放申請的RT
- RenderTexture.ReleaseTemporary(temp1);
- RenderTexture.ReleaseTemporary(temp2);
- }
- }
- //計算設置的焦點被轉換到01空間中的距離,以便shader中通過這個01空間的焦點距離與depth比較
- private float FocalDistance01(float distance)
- {
- float dist = Cam.WorldToViewportPoint((distance - Cam.nearClipPlane) * Cam.transform.forward + Cam.transform.position).z / (Cam.farClipPlane - Cam.nearClipPlane);
- return dist;
- }
- }
|