DepthOfField.shader 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
  2. Shader "PostEffect/DepthOfField" {
  3. Properties{
  4. _MainTex("Base (RGB)", 2D) = "white" {}
  5. _BlurTex("Blur", 2D) = "white"{}
  6. }
  7. CGINCLUDE
  8. #include "UnityCG.cginc"
  9. struct v2f_blur
  10. {
  11. float4 pos : SV_POSITION;
  12. float2 uv : TEXCOORD0;
  13. float4 uv01 : TEXCOORD1;
  14. float4 uv23 : TEXCOORD2;
  15. float4 uv45 : TEXCOORD3;
  16. };
  17. struct v2f_dof
  18. {
  19. float4 pos : SV_POSITION;
  20. float2 uv : TEXCOORD0;
  21. float2 uv1 : TEXCOORD1;
  22. };
  23. sampler2D _MainTex;
  24. float4 _MainTex_TexelSize;
  25. sampler2D _BlurTex;
  26. sampler2D_float _CameraDepthTexture;
  27. float4 _offsets;
  28. float _focalDistance;
  29. float _nearBlurScale;
  30. float _farBlurScale;
  31. //高斯模糊 vert shader(上一篇文章有详细注释)
  32. v2f_blur vert_blur(appdata_img v)
  33. {
  34. v2f_blur o;
  35. _offsets *= _MainTex_TexelSize.xyxy;
  36. o.pos = UnityObjectToClipPos(v.vertex);
  37. o.uv = v.texcoord.xy;
  38. o.uv01 = v.texcoord.xyxy + _offsets.xyxy * float4(1, 1, -1, -1);
  39. o.uv23 = v.texcoord.xyxy + _offsets.xyxy * float4(1, 1, -1, -1) * 2.0;
  40. o.uv45 = v.texcoord.xyxy + _offsets.xyxy * float4(1, 1, -1, -1) * 3.0;
  41. return o;
  42. }
  43. //高斯模糊 pixel shader(上一篇文章有详细注释)
  44. fixed4 frag_blur(v2f_blur i) : SV_Target
  45. {
  46. fixed4 color = fixed4(0,0,0,0);
  47. color += 0.40 * tex2D(_MainTex, i.uv);
  48. color += 0.15 * tex2D(_MainTex, i.uv01.xy);
  49. color += 0.15 * tex2D(_MainTex, i.uv01.zw);
  50. color += 0.10 * tex2D(_MainTex, i.uv23.xy);
  51. color += 0.10 * tex2D(_MainTex, i.uv23.zw);
  52. color += 0.05 * tex2D(_MainTex, i.uv45.xy);
  53. color += 0.05 * tex2D(_MainTex, i.uv45.zw);
  54. return color;
  55. }
  56. //景深效果 vertex shader
  57. v2f_dof vert_dof(appdata_img v)
  58. {
  59. v2f_dof o;
  60. //mvp矩阵变换
  61. o.pos = UnityObjectToClipPos(v.vertex);
  62. //uv坐标传递
  63. o.uv.xy = v.texcoord.xy;
  64. o.uv1.xy = o.uv.xy;
  65. //dx中纹理从左上角为初始坐标,需要反向
  66. #if UNITY_UV_STARTS_AT_TOP
  67. if (_MainTex_TexelSize.y < 0)
  68. o.uv.y = 1 - o.uv.y;
  69. #endif
  70. return o;
  71. }
  72. fixed4 frag_dof(v2f_dof i) : SV_Target
  73. {
  74. //取原始清晰图片进行uv采样
  75. fixed4 ori = tex2D(_MainTex, i.uv1);
  76. //取模糊普片进行uv采样
  77. fixed4 blur = tex2D(_BlurTex, i.uv);
  78. //取当位置对应的深度值
  79. float depth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv);
  80. //将深度值转化到01线性空间
  81. depth = Linear01Depth(depth);
  82. //如果depth小于焦点的物体,那么使用原始清晰图像,否则使用模糊的图像与清晰图像的差值,通过差值避免模糊和清晰之间明显的边界,结果为远景模糊效果
  83. fixed4 final = (depth <= _focalDistance) ? ori : lerp(ori, blur, clamp((depth - _focalDistance) * _farBlurScale, 0, 1));
  84. //上面的结果,再进行一次计算,如果depth大于焦点的物体,使用上面的结果和模糊图像差值,得到近景模糊效果
  85. final = (depth > _focalDistance) ? final : lerp(ori, blur, clamp((_focalDistance - depth) * _nearBlurScale, 0, 1));
  86. //焦点位置是清晰的图像,两边分别用当前像素深度距离焦点的距离进行差值,这样就达到原理焦点位置模糊的效果
  87. //上面的?在编译时会被编译成if语句,GPU并不擅长分支计算,而且如果有分支,两个分支都要跑。这里给了一个更优化一些的计算方式,不过语法比较晦涩
  88. /*float focalTest = clamp(sign(depth - _focalDistance),0,1);
  89. fixed4 final = (1 - focalTest) * ori + focalTest * lerp(ori, blur, clamp((depth - _focalDistance) * _farBlurScale, 0, 1));
  90. final = (focalTest)* final + (1 - focalTest) * lerp(ori, blur, clamp((_focalDistance - depth) * _nearBlurScale, 0, 1)); */
  91. return final;
  92. }
  93. ENDCG
  94. SubShader
  95. {
  96. //pass 0: 高斯模糊
  97. Pass
  98. {
  99. ZTest Off
  100. Cull Off
  101. ZWrite Off
  102. Fog{ Mode Off }
  103. CGPROGRAM
  104. #pragma vertex vert_blur
  105. #pragma fragment frag_blur
  106. ENDCG
  107. }
  108. //pass 1: 景深效果
  109. Pass
  110. {
  111. ZTest Off
  112. Cull Off
  113. ZWrite Off
  114. Fog{ Mode Off }
  115. ColorMask RGBA
  116. CGPROGRAM
  117. #pragma vertex vert_dof
  118. #pragma fragment frag_dof
  119. ENDCG
  120. }
  121. }
  122. }