SSAOShader.shader 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
  2. Shader "Hidden/SSAO" {
  3. Properties {
  4. _MainTex ("", 2D) = "" {}
  5. _RandomTexture ("", 2D) = "" {}
  6. _SSAO ("", 2D) = "" {}
  7. }
  8. Subshader {
  9. ZTest Always Cull Off ZWrite Off
  10. CGINCLUDE
  11. // Common code used by several SSAO passes below
  12. #include "UnityCG.cginc"
  13. struct v2f_ao {
  14. float4 pos : SV_POSITION;
  15. float2 uv : TEXCOORD0;
  16. float2 uvr : TEXCOORD1;
  17. };
  18. uniform float2 _NoiseScale;
  19. float4 _CameraDepthNormalsTexture_ST;
  20. v2f_ao vert_ao (appdata_img v)
  21. {
  22. v2f_ao o;
  23. o.pos = UnityObjectToClipPos (v.vertex);
  24. o.uv = TRANSFORM_TEX(v.texcoord, _CameraDepthNormalsTexture);
  25. o.uvr = v.texcoord.xy * _NoiseScale;
  26. return o;
  27. }
  28. sampler2D _CameraDepthNormalsTexture;
  29. sampler2D _RandomTexture;
  30. float4 _Params; // x=radius, y=minz, z=attenuation power, w=SSAO power
  31. // HLSL and GLSL do not support arbitrarily sized arrays as function parameters (eg. float bla[]), whereas Cg does.
  32. #if !defined(UNITY_COMPILER_CG)
  33. # define INPUT_SAMPLE_COUNT 8
  34. # include "frag_ao.cginc"
  35. # undef INPUT_SAMPLE_COUNT
  36. # define INPUT_SAMPLE_COUNT 14
  37. # include "frag_ao.cginc"
  38. # undef INPUT_SAMPLE_COUNT
  39. # define INPUT_SAMPLE_COUNT 26
  40. # include "frag_ao.cginc"
  41. # undef INPUT_SAMPLE_COUNT
  42. # define INPUT_SAMPLE_COUNT 34
  43. # include "frag_ao.cginc"
  44. # undef INPUT_SAMPLE_COUNT
  45. #else
  46. # define INPUT_SAMPLE_COUNT
  47. # include "frag_ao.cginc"
  48. #endif
  49. ENDCG
  50. // ---- SSAO pass, 8 samples
  51. Pass {
  52. CGPROGRAM
  53. #pragma vertex vert_ao
  54. #pragma fragment frag
  55. #pragma target 3.0
  56. half4 frag (v2f_ao i) : SV_Target
  57. {
  58. #define SAMPLE_COUNT 8
  59. const float3 RAND_SAMPLES[SAMPLE_COUNT] = {
  60. float3(0.01305719,0.5872321,-0.119337),
  61. float3(0.3230782,0.02207272,-0.4188725),
  62. float3(-0.310725,-0.191367,0.05613686),
  63. float3(-0.4796457,0.09398766,-0.5802653),
  64. float3(0.1399992,-0.3357702,0.5596789),
  65. float3(-0.2484578,0.2555322,0.3489439),
  66. float3(0.1871898,-0.702764,-0.2317479),
  67. float3(0.8849149,0.2842076,0.368524),
  68. };
  69. return frag_ao (i, SAMPLE_COUNT, RAND_SAMPLES);
  70. }
  71. ENDCG
  72. }
  73. // ---- SSAO pass, 14 samples
  74. Pass {
  75. CGPROGRAM
  76. #pragma vertex vert_ao
  77. #pragma fragment frag
  78. #pragma target 3.0
  79. half4 frag (v2f_ao i) : SV_Target
  80. {
  81. #define SAMPLE_COUNT 14
  82. const float3 RAND_SAMPLES[SAMPLE_COUNT] = {
  83. float3(0.4010039,0.8899381,-0.01751772),
  84. float3(0.1617837,0.1338552,-0.3530486),
  85. float3(-0.2305296,-0.1900085,0.5025396),
  86. float3(-0.6256684,0.1241661,0.1163932),
  87. float3(0.3820786,-0.3241398,0.4112825),
  88. float3(-0.08829653,0.1649759,0.1395879),
  89. float3(0.1891677,-0.1283755,-0.09873557),
  90. float3(0.1986142,0.1767239,0.4380491),
  91. float3(-0.3294966,0.02684341,-0.4021836),
  92. float3(-0.01956503,-0.3108062,-0.410663),
  93. float3(-0.3215499,0.6832048,-0.3433446),
  94. float3(0.7026125,0.1648249,0.02250625),
  95. float3(0.03704464,-0.939131,0.1358765),
  96. float3(-0.6984446,-0.6003422,-0.04016943),
  97. };
  98. return frag_ao (i, SAMPLE_COUNT, RAND_SAMPLES);
  99. }
  100. ENDCG
  101. }
  102. // ---- SSAO pass, 26 samples
  103. Pass {
  104. CGPROGRAM
  105. #pragma vertex vert_ao
  106. #pragma fragment frag
  107. #pragma target 3.0
  108. half4 frag (v2f_ao i) : SV_Target
  109. {
  110. #define SAMPLE_COUNT 26
  111. const float3 RAND_SAMPLES[SAMPLE_COUNT] = {
  112. float3(0.2196607,0.9032637,0.2254677),
  113. float3(0.05916681,0.2201506,-0.1430302),
  114. float3(-0.4152246,0.1320857,0.7036734),
  115. float3(-0.3790807,0.1454145,0.100605),
  116. float3(0.3149606,-0.1294581,0.7044517),
  117. float3(-0.1108412,0.2162839,0.1336278),
  118. float3(0.658012,-0.4395972,-0.2919373),
  119. float3(0.5377914,0.3112189,0.426864),
  120. float3(-0.2752537,0.07625949,-0.1273409),
  121. float3(-0.1915639,-0.4973421,-0.3129629),
  122. float3(-0.2634767,0.5277923,-0.1107446),
  123. float3(0.8242752,0.02434147,0.06049098),
  124. float3(0.06262707,-0.2128643,-0.03671562),
  125. float3(-0.1795662,-0.3543862,0.07924347),
  126. float3(0.06039629,0.24629,0.4501176),
  127. float3(-0.7786345,-0.3814852,-0.2391262),
  128. float3(0.2792919,0.2487278,-0.05185341),
  129. float3(0.1841383,0.1696993,-0.8936281),
  130. float3(-0.3479781,0.4725766,-0.719685),
  131. float3(-0.1365018,-0.2513416,0.470937),
  132. float3(0.1280388,-0.563242,0.3419276),
  133. float3(-0.4800232,-0.1899473,0.2398808),
  134. float3(0.6389147,0.1191014,-0.5271206),
  135. float3(0.1932822,-0.3692099,-0.6060588),
  136. float3(-0.3465451,-0.1654651,-0.6746758),
  137. float3(0.2448421,-0.1610962,0.1289366),
  138. };
  139. return frag_ao (i, SAMPLE_COUNT, RAND_SAMPLES);
  140. }
  141. ENDCG
  142. }
  143. // ---- Blur pass
  144. Pass {
  145. CGPROGRAM
  146. #pragma vertex vert
  147. #pragma fragment frag
  148. #pragma target 3.0
  149. #include "UnityCG.cginc"
  150. struct v2f {
  151. float4 pos : SV_POSITION;
  152. float2 uv : TEXCOORD0;
  153. };
  154. float4 _MainTex_ST;
  155. v2f vert (appdata_img v)
  156. {
  157. v2f o;
  158. o.pos = UnityObjectToClipPos (v.vertex);
  159. o.uv = TRANSFORM_TEX (v.texcoord, _CameraDepthNormalsTexture);
  160. return o;
  161. }
  162. sampler2D _SSAO;
  163. float3 _TexelOffsetScale;
  164. inline half CheckSame (half4 n, half4 nn)
  165. {
  166. // difference in normals
  167. half2 diff = abs(n.xy - nn.xy);
  168. half sn = (diff.x + diff.y) < 0.1;
  169. // difference in depth
  170. float z = DecodeFloatRG (n.zw);
  171. float zz = DecodeFloatRG (nn.zw);
  172. float zdiff = abs(z-zz) * _ProjectionParams.z;
  173. half sz = zdiff < 0.2;
  174. return sn * sz;
  175. }
  176. half4 frag( v2f i ) : SV_Target
  177. {
  178. #define NUM_BLUR_SAMPLES 4
  179. float2 o = _TexelOffsetScale.xy;
  180. half sum = tex2D(_SSAO, i.uv).r * (NUM_BLUR_SAMPLES + 1);
  181. half denom = NUM_BLUR_SAMPLES + 1;
  182. half4 geom = tex2D (_CameraDepthNormalsTexture, i.uv);
  183. for (int s = 0; s < NUM_BLUR_SAMPLES; ++s)
  184. {
  185. float2 nuv = i.uv + o * (s+1);
  186. half4 ngeom = tex2D (_CameraDepthNormalsTexture, nuv.xy);
  187. half coef = (NUM_BLUR_SAMPLES - s) * CheckSame (geom, ngeom);
  188. sum += tex2D (_SSAO, nuv.xy).r * coef;
  189. denom += coef;
  190. }
  191. for (int s = 0; s < NUM_BLUR_SAMPLES; ++s)
  192. {
  193. float2 nuv = i.uv - o * (s+1);
  194. half4 ngeom = tex2D (_CameraDepthNormalsTexture, nuv.xy);
  195. half coef = (NUM_BLUR_SAMPLES - s) * CheckSame (geom, ngeom);
  196. sum += tex2D (_SSAO, nuv.xy).r * coef;
  197. denom += coef;
  198. }
  199. return sum / denom;
  200. }
  201. ENDCG
  202. }
  203. // ---- Composite pass
  204. Pass {
  205. CGPROGRAM
  206. #pragma vertex vert
  207. #pragma fragment frag
  208. #include "UnityCG.cginc"
  209. struct v2f {
  210. float4 pos : SV_POSITION;
  211. float2 uv[2] : TEXCOORD0;
  212. };
  213. v2f vert (appdata_img v)
  214. {
  215. v2f o;
  216. o.pos = UnityObjectToClipPos (v.vertex);
  217. o.uv[0] = MultiplyUV (UNITY_MATRIX_TEXTURE0, v.texcoord);
  218. o.uv[1] = MultiplyUV (UNITY_MATRIX_TEXTURE1, v.texcoord);
  219. return o;
  220. }
  221. sampler2D _MainTex;
  222. sampler2D _SSAO;
  223. half4 frag( v2f i ) : SV_Target
  224. {
  225. half4 c = tex2D (_MainTex, i.uv[0]);
  226. half ao = tex2D (_SSAO, i.uv[1]).r;
  227. ao = pow (ao, _Params.w);
  228. c.rgb *= ao;
  229. return c;
  230. }
  231. ENDCG
  232. }
  233. }
  234. Fallback off
  235. }