DepthOfFieldPostEffect.cs 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. [ExecuteInEditMode]
  5. [RequireComponent(typeof(Camera))]
  6. public class DepthOfFieldPostEffect : MonoBehaviour
  7. {
  8. public Material mat;
  9. [Range(0.0f, 100.0f)]
  10. public float focalDistance = 10.0f;
  11. [Range(0.0f, 100.0f)]
  12. public float nearBlurScale = 0.0f;
  13. [Range(0.0f, 1000.0f)]
  14. public float farBlurScale = 50.0f;
  15. //分辨率
  16. public int downSample = 1;
  17. //採樣率
  18. public int samplerScale = 1;
  19. private Camera mCam;
  20. public Camera Cam
  21. {
  22. get
  23. {
  24. if (mCam == null)
  25. {
  26. mCam = GetComponent<Camera>();
  27. }
  28. return mCam;
  29. }
  30. }
  31. private void OnEnable()
  32. {
  33. if(Cam != null)
  34. {
  35. Cam.depthTextureMode |= DepthTextureMode.Depth;
  36. }
  37. }
  38. private void OnDisable()
  39. {
  40. if(Cam != null)
  41. {
  42. Cam.depthTextureMode &= ~DepthTextureMode.Depth;
  43. }
  44. }
  45. // Start is called before the first frame update
  46. void Start()
  47. {
  48. }
  49. // Update is called once per frame
  50. void Update()
  51. {
  52. }
  53. private void OnRenderImage(RenderTexture src, RenderTexture dest)
  54. {
  55. if(mat!=null)
  56. {
  57. //首先將我們設置的焦點限制在遠近裁剪面之間
  58. Mathf.Clamp(focalDistance, Cam.nearClipPlane, Cam.farClipPlane);
  59. //申請兩塊RT,並且分辨率按照downSameple降低
  60. RenderTexture temp1 = RenderTexture.GetTemporary(src.width >> downSample, src.height >> downSample, 0, src.format);
  61. RenderTexture temp2 = RenderTexture.GetTemporary(src.width >> downSample, src.height >> downSample, 0, src.format);
  62. //直接將場景圖拷貝到低分辨率的RT上達到降分辨率的效果
  63. Graphics.Blit(src, temp1);
  64. //高斯模糊,兩次模糊,橫向縱向,使用pass0進行高斯模糊
  65. mat.SetVector("_offsets", new Vector4(0, samplerScale, 0, 0));
  66. Graphics.Blit(temp1, temp2, mat, 0);
  67. mat.SetVector("_offsets", new Vector4(samplerScale, 0, 0, 0));
  68. Graphics.Blit(temp2, temp1, mat, 0);
  69. //景深操作,景深需要兩的模糊效果圖我們通過_BlurTex變量傳入shader
  70. mat.SetTexture("_BlurTex", temp1);
  71. //設置shader的參數,主要是焦點和遠近模糊的權重,權重可以控制插值時使用模糊圖片的權重
  72. mat.SetFloat("_focalDistance", FocalDistance01(focalDistance));
  73. mat.SetFloat("_nearBlurScale", nearBlurScale);
  74. mat.SetFloat("_farBlurScale", farBlurScale);
  75. //使用pass1進行景深效果計算,清晰場景圖直接從source輸入到shader的_MainTex中
  76. Graphics.Blit(src, dest, mat, 1);
  77. //釋放申請的RT
  78. RenderTexture.ReleaseTemporary(temp1);
  79. RenderTexture.ReleaseTemporary(temp2);
  80. }
  81. }
  82. //計算設置的焦點被轉換到01空間中的距離,以便shader中通過這個01空間的焦點距離與depth比較
  83. private float FocalDistance01(float distance)
  84. {
  85. float dist = Cam.WorldToViewportPoint((distance - Cam.nearClipPlane) * Cam.transform.forward + Cam.transform.position).z / (Cam.farClipPlane - Cam.nearClipPlane);
  86. return dist;
  87. }
  88. }