EnviroBilateralBlur.shader 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810
  1. // Copyright(c) 2016, Michal Skalsky
  2. // All rights reserved.
  3. //
  4. // Redistribution and use in source and binary forms, with or without modification,
  5. // are permitted provided that the following conditions are met:
  6. //
  7. // 1. Redistributions of source code must retain the above copyright notice,
  8. // this list of conditions and the following disclaimer.
  9. //
  10. // 2. Redistributions in binary form must reproduce the above copyright notice,
  11. // this list of conditions and the following disclaimer in the documentation
  12. // and/or other materials provided with the distribution.
  13. //
  14. // 3. Neither the name of the copyright holder nor the names of its contributors
  15. // may be used to endorse or promote products derived from this software without
  16. // specific prior written permission.
  17. //
  18. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
  19. // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  20. // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.IN NO EVENT
  21. // SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  22. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
  23. // OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  24. // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
  25. // TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  26. // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27. Shader "Hidden/EnviroBlur"
  28. {
  29. Properties
  30. {
  31. //_MainTex("Texture", any) = "" {}
  32. }
  33. SubShader
  34. {
  35. // No culling or depth
  36. Cull Off ZWrite Off ZTest Always
  37. CGINCLUDE
  38. //--------------------------------------------------------------------------------------------
  39. // Downsample, bilateral blur and upsample config
  40. //--------------------------------------------------------------------------------------------
  41. // method used to downsample depth buffer: 0 = min; 1 = max; 2 = min/max in chessboard pattern
  42. #define DOWNSAMPLE_DEPTH_MODE 2
  43. #define UPSAMPLE_DEPTH_THRESHOLD 1.5f
  44. #define BLUR_DEPTH_FACTOR 0.5
  45. #define GAUSS_BLUR_DEVIATION 1.5
  46. #define FULL_RES_BLUR_KERNEL_SIZE 7
  47. #define HALF_RES_BLUR_KERNEL_SIZE 5
  48. #define QUARTER_RES_BLUR_KERNEL_SIZE 6
  49. //--------------------------------------------------------------------------------------------
  50. #define PI 3.1415927f
  51. #include "UnityCG.cginc"
  52. #if defined(UNITY_STEREO_INSTANCING_ENABLED) || defined(UNITY_STEREO_MULTIVIEW_ENABLED)
  53. UNITY_DECLARE_TEX2DARRAY(_CameraDepthTexture);
  54. UNITY_DECLARE_TEX2DARRAY(_HalfResDepthBuffer);
  55. UNITY_DECLARE_TEX2DARRAY(_QuarterResDepthBuffer);
  56. UNITY_DECLARE_TEX2DARRAY(_HalfResColor);
  57. UNITY_DECLARE_TEX2DARRAY(_QuarterResColor);
  58. UNITY_DECLARE_TEX2DARRAY(_MainTex);
  59. #else
  60. UNITY_DECLARE_TEX2D(_CameraDepthTexture);
  61. UNITY_DECLARE_TEX2D(_HalfResDepthBuffer);
  62. UNITY_DECLARE_TEX2D(_QuarterResDepthBuffer);
  63. UNITY_DECLARE_TEX2D(_HalfResColor);
  64. UNITY_DECLARE_TEX2D(_QuarterResColor);
  65. UNITY_DECLARE_TEX2D(_MainTex);
  66. #endif
  67. float4 _MainTex_TexelSize;
  68. float4 _CameraDepthTexture_TexelSize;
  69. float4 _HalfResDepthBuffer_TexelSize;
  70. float4 _QuarterResDepthBuffer_TexelSize;
  71. struct appdata
  72. {
  73. float4 vertex : POSITION;
  74. float2 uv : TEXCOORD0;
  75. UNITY_VERTEX_INPUT_INSTANCE_ID
  76. };
  77. struct v2f
  78. {
  79. float2 uv : TEXCOORD0;
  80. float4 vertex : SV_POSITION;
  81. UNITY_VERTEX_OUTPUT_STEREO
  82. };
  83. struct v2fDownsample
  84. {
  85. #if SHADER_TARGET > 40
  86. float2 uv : TEXCOORD0;
  87. #else
  88. float2 uv00 : TEXCOORD0;
  89. float2 uv01 : TEXCOORD1;
  90. float2 uv10 : TEXCOORD2;
  91. float2 uv11 : TEXCOORD3;
  92. #endif
  93. float4 vertex : SV_POSITION;
  94. UNITY_VERTEX_OUTPUT_STEREO
  95. };
  96. struct v2fUpsample
  97. {
  98. float2 uv : TEXCOORD0;
  99. float2 uv00 : TEXCOORD1;
  100. float2 uv01 : TEXCOORD2;
  101. float2 uv10 : TEXCOORD3;
  102. float2 uv11 : TEXCOORD4;
  103. float4 vertex : SV_POSITION;
  104. UNITY_VERTEX_OUTPUT_STEREO
  105. };
  106. v2f vert(appdata v)
  107. {
  108. v2f o;
  109. UNITY_SETUP_INSTANCE_ID(v);
  110. UNITY_INITIALIZE_OUTPUT(v2f, o);
  111. UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
  112. #if defined(ENVIROURP)
  113. o.vertex = float4(v.vertex.xyz,1.0);
  114. #if UNITY_UV_STARTS_AT_TOP
  115. o.vertex.y *= -1;
  116. #endif
  117. #else
  118. o.vertex = UnityObjectToClipPos(v.vertex);
  119. #endif
  120. o.uv = v.uv;
  121. return o;
  122. }
  123. //-----------------------------------------------------------------------------------------
  124. // vertDownsampleDepth
  125. //-----------------------------------------------------------------------------------------
  126. v2fDownsample vertDownsampleDepth(appdata v, float2 texelSize)
  127. {
  128. v2fDownsample o;
  129. UNITY_SETUP_INSTANCE_ID(v);
  130. UNITY_INITIALIZE_OUTPUT(v2fDownsample, o);
  131. UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
  132. #if defined(ENVIROURP)
  133. o.vertex = float4(v.vertex.xyz,1.0);
  134. #if UNITY_UV_STARTS_AT_TOP
  135. o.vertex.y *= -1;
  136. #endif
  137. #else
  138. o.vertex = UnityObjectToClipPos(v.vertex);
  139. #endif
  140. #if SHADER_TARGET > 40
  141. o.uv = v.uv;
  142. #else
  143. o.uv00 = v.uv - 0.5 * texelSize.xy;
  144. o.uv10 = o.uv00 + float2(texelSize.x, 0);
  145. o.uv01 = o.uv00 + float2(0, texelSize.y);
  146. o.uv11 = o.uv00 + texelSize.xy;
  147. #endif
  148. return o;
  149. }
  150. //-----------------------------------------------------------------------------------------
  151. // vertUpsample
  152. //-----------------------------------------------------------------------------------------
  153. v2fUpsample vertUpsample(appdata v, float2 texelSize)
  154. {
  155. v2fUpsample o;
  156. UNITY_SETUP_INSTANCE_ID(v);
  157. UNITY_INITIALIZE_OUTPUT(v2fUpsample, o);
  158. UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
  159. #if defined(ENVIROURP)
  160. o.vertex = float4(v.vertex.xyz,1.0);
  161. #if UNITY_UV_STARTS_AT_TOP
  162. o.vertex.y *= -1;
  163. #endif
  164. #else
  165. o.vertex = UnityObjectToClipPos(v.vertex);
  166. #endif
  167. o.uv = v.uv;
  168. o.uv00 = v.uv - 0.5 * texelSize.xy;
  169. o.uv10 = o.uv00 + float2(texelSize.x, 0);
  170. o.uv01 = o.uv00 + float2(0, texelSize.y);
  171. o.uv11 = o.uv00 + texelSize.xy;
  172. return o;
  173. }
  174. #if defined(UNITY_STEREO_INSTANCING_ENABLED) || defined(UNITY_STEREO_MULTIVIEW_ENABLED)
  175. float4 SampleTexture(Texture2DArray tex, SamplerState samplerState, float2 uv)
  176. {
  177. //return UNITY_SAMPLE_TEX2DARRAY(tex, float3((uv).xy, (float)unity_StereoEyeIndex));
  178. //return UNITY_SAMPLE_TEX2DARRAY_SAMPLER(tex,samplerState,uv);
  179. return tex.Sample(samplerState, float3((uv).xy, (float)unity_StereoEyeIndex));
  180. }
  181. //-----------------------------------------------------------------------------------------
  182. // BilateralUpsample
  183. //-----------------------------------------------------------------------------------------
  184. float4 BilateralUpsample(v2fUpsample input, Texture2DArray hiDepth, Texture2DArray loDepth, Texture2DArray loColor, SamplerState linearSampler, SamplerState pointSampler)
  185. {
  186. const float threshold = UPSAMPLE_DEPTH_THRESHOLD;
  187. // float4 highResDepth = LinearEyeDepth(hiDepth.Sample(pointSampler, input.uv)).xxxx;
  188. float4 highResDepth = LinearEyeDepth(SampleTexture(hiDepth, pointSampler, input.uv)).xxxx;
  189. float4 lowResDepth;
  190. lowResDepth[0] = LinearEyeDepth(SampleTexture(loDepth, pointSampler, input.uv00));
  191. lowResDepth[1] = LinearEyeDepth(SampleTexture(loDepth, pointSampler, input.uv10));
  192. lowResDepth[2] = LinearEyeDepth(SampleTexture(loDepth, pointSampler, input.uv01));
  193. lowResDepth[3] = LinearEyeDepth(SampleTexture(loDepth, pointSampler, input.uv11));
  194. float4 depthDiff = abs(lowResDepth - highResDepth);
  195. float accumDiff = dot(depthDiff, float4(1, 1, 1, 1));
  196. [branch]
  197. if (accumDiff < threshold) // small error, not an edge -> use bilinear filter
  198. {
  199. return SampleTexture(loColor,linearSampler,input.uv);
  200. }
  201. // find nearest sample
  202. float minDepthDiff = depthDiff[0];
  203. float2 nearestUv = input.uv00;
  204. if (depthDiff[1] < minDepthDiff)
  205. {
  206. nearestUv = input.uv10;
  207. minDepthDiff = depthDiff[1];
  208. }
  209. if (depthDiff[2] < minDepthDiff)
  210. {
  211. nearestUv = input.uv01;
  212. minDepthDiff = depthDiff[2];
  213. }
  214. if (depthDiff[3] < minDepthDiff)
  215. {
  216. nearestUv = input.uv11;
  217. minDepthDiff = depthDiff[3];
  218. }
  219. return SampleTexture(loColor,pointSampler,nearestUv);
  220. }
  221. //-----------------------------------------------------------------------------------------
  222. // DownsampleDepth
  223. //-----------------------------------------------------------------------------------------
  224. float DownsampleDepth(v2fDownsample input, Texture2DArray depthTexture, SamplerState depthSampler)
  225. {
  226. #if SHADER_TARGET > 40
  227. float4 depth = depthTexture.Gather(depthSampler, input.uv);
  228. #else
  229. float4 depth;
  230. depth.x = SampleTexture(depthTexture,depthSampler,input.uv00).x;
  231. depth.y = SampleTexture(depthTexture,depthSampler,input.uv01).x;
  232. depth.z = SampleTexture(depthTexture,depthSampler,input.uv10).x;
  233. depth.w = SampleTexture(depthTexture,depthSampler,input.uv11).x;
  234. #endif
  235. #if DOWNSAMPLE_DEPTH_MODE == 0 // min depth
  236. return min(min(depth.x, depth.y), min(depth.z, depth.w));
  237. #elif DOWNSAMPLE_DEPTH_MODE == 1 // max depth
  238. return max(max(depth.x, depth.y), max(depth.z, depth.w));
  239. #elif DOWNSAMPLE_DEPTH_MODE == 2 // min/max depth in chessboard pattern
  240. float minDepth = min(min(depth.x, depth.y), min(depth.z, depth.w));
  241. float maxDepth = max(max(depth.x, depth.y), max(depth.z, depth.w));
  242. // chessboard pattern
  243. int2 position = input.vertex.xy % 2;
  244. int index = position.x + position.y;
  245. return index == 1 ? minDepth : maxDepth;
  246. #endif
  247. }
  248. //-----------------------------------------------------------------------------------------
  249. // GaussianWeight
  250. //-----------------------------------------------------------------------------------------
  251. float GaussianWeight(float offset, float deviation)
  252. {
  253. float weight = 1.0f / sqrt(2.0f * PI * deviation * deviation);
  254. weight *= exp(-(offset * offset) / (2.0f * deviation * deviation));
  255. return weight;
  256. }
  257. //-----------------------------------------------------------------------------------------
  258. // BilateralBlur
  259. //-----------------------------------------------------------------------------------------
  260. float4 BilateralBlur(v2f input, int2 direction, Texture2DArray depth, SamplerState depthSampler, const int kernelRadius, float2 pixelSize)
  261. {
  262. //const float deviation = kernelRadius / 2.5;
  263. const float deviation = kernelRadius / GAUSS_BLUR_DEVIATION; // make it really strong
  264. float2 uv = input.uv;
  265. float4 centerColor = SampleTexture(_MainTex,sampler_MainTex,uv);
  266. float3 color = centerColor.xyz;
  267. //return float4(color, 1);
  268. float centerDepth = LinearEyeDepth(SampleTexture(depth,depthSampler,uv));
  269. float weightSum = 0;
  270. // gaussian weight is computed from constants only -> will be computed in compile time
  271. float weight = GaussianWeight(0, deviation);
  272. color *= weight;
  273. weightSum += weight;
  274. [unroll] for (int i = -kernelRadius; i < 0; i += 1)
  275. {
  276. float2 offset = (direction * i);
  277. float3 sampleColor = SampleTexture(_MainTex,sampler_MainTex,input.uv + offset * _MainTex_TexelSize.xy).rgb;
  278. float sampleDepth = LinearEyeDepth(SampleTexture(depth,depthSampler, input.uv + offset * _MainTex_TexelSize.xy));
  279. float depthDiff = abs(centerDepth - sampleDepth);
  280. float dFactor = depthDiff * BLUR_DEPTH_FACTOR;
  281. float w = exp(-(dFactor * dFactor));
  282. // gaussian weight is computed from constants only -> will be computed in compile time
  283. weight = GaussianWeight(i, deviation) * w;
  284. color += weight * sampleColor;
  285. weightSum += weight;
  286. }
  287. [unroll] for (int k = 1; k <= kernelRadius; k += 1)
  288. {
  289. float2 offset = (direction * k);
  290. float3 sampleColor = SampleTexture(_MainTex,sampler_MainTex,input.uv + offset * _MainTex_TexelSize.xy).rgb;
  291. float sampleDepth = LinearEyeDepth(SampleTexture(depth,depthSampler, input.uv + offset * _MainTex_TexelSize.xy));
  292. float depthDiff = abs(centerDepth - sampleDepth);
  293. float dFactor = depthDiff * BLUR_DEPTH_FACTOR;
  294. float w = exp(-(dFactor * dFactor));
  295. // gaussian weight is computed from constants only -> will be computed in compile time
  296. weight = GaussianWeight(k, deviation) * w;
  297. color += weight * sampleColor;
  298. weightSum += weight;
  299. }
  300. color /= weightSum;
  301. return float4(color, centerColor.w);
  302. }
  303. #else
  304. float4 SampleTexture(Texture2D tex, SamplerState samplerState, float2 uv)
  305. {
  306. return tex.Sample(samplerState,uv);
  307. }
  308. float4 SampleTexture(Texture2D tex, SamplerState samplerState, float2 uv, float2 offset)
  309. {
  310. return tex.Sample(samplerState,uv,offset);
  311. }
  312. //-----------------------------------------------------------------------------------------
  313. // BilateralUpsample
  314. //-----------------------------------------------------------------------------------------
  315. float4 BilateralUpsample(v2fUpsample input, Texture2D hiDepth, Texture2D loDepth, Texture2D loColor, SamplerState linearSampler, SamplerState pointSampler)
  316. {
  317. const float threshold = UPSAMPLE_DEPTH_THRESHOLD;
  318. // float4 highResDepth = LinearEyeDepth(hiDepth.Sample(pointSampler, input.uv)).xxxx;
  319. float4 highResDepth = LinearEyeDepth(SampleTexture(hiDepth, pointSampler, input.uv)).xxxx;
  320. float4 lowResDepth;
  321. lowResDepth[0] = LinearEyeDepth(SampleTexture(loDepth, pointSampler, input.uv00));
  322. lowResDepth[1] = LinearEyeDepth(SampleTexture(loDepth, pointSampler, input.uv10));
  323. lowResDepth[2] = LinearEyeDepth(SampleTexture(loDepth, pointSampler, input.uv01));
  324. lowResDepth[3] = LinearEyeDepth(SampleTexture(loDepth, pointSampler, input.uv11));
  325. float4 depthDiff = abs(lowResDepth - highResDepth);
  326. float accumDiff = dot(depthDiff, float4(1, 1, 1, 1));
  327. [branch]
  328. if (accumDiff < threshold) // small error, not an edge -> use bilinear filter
  329. {
  330. return SampleTexture(loColor,linearSampler,input.uv);
  331. }
  332. // find nearest sample
  333. float minDepthDiff = depthDiff[0];
  334. float2 nearestUv = input.uv00;
  335. if (depthDiff[1] < minDepthDiff)
  336. {
  337. nearestUv = input.uv10;
  338. minDepthDiff = depthDiff[1];
  339. }
  340. if (depthDiff[2] < minDepthDiff)
  341. {
  342. nearestUv = input.uv01;
  343. minDepthDiff = depthDiff[2];
  344. }
  345. if (depthDiff[3] < minDepthDiff)
  346. {
  347. nearestUv = input.uv11;
  348. minDepthDiff = depthDiff[3];
  349. }
  350. return SampleTexture(loColor,pointSampler,nearestUv);
  351. }
  352. //-----------------------------------------------------------------------------------------
  353. // DownsampleDepth
  354. //-----------------------------------------------------------------------------------------
  355. float DownsampleDepth(v2fDownsample input, Texture2D depthTexture, SamplerState depthSampler)
  356. {
  357. #if SHADER_TARGET > 40
  358. float4 depth = depthTexture.Gather(depthSampler, input.uv);
  359. #else
  360. float4 depth;
  361. depth.x = SampleTexture(depthTexture,depthSampler,input.uv00).x;
  362. depth.y = SampleTexture(depthTexture,depthSampler,input.uv01).x;
  363. depth.z = SampleTexture(depthTexture,depthSampler,input.uv10).x;
  364. depth.w = SampleTexture(depthTexture,depthSampler,input.uv11).x;
  365. #endif
  366. #if DOWNSAMPLE_DEPTH_MODE == 0 // min depth
  367. return min(min(depth.x, depth.y), min(depth.z, depth.w));
  368. #elif DOWNSAMPLE_DEPTH_MODE == 1 // max depth
  369. return max(max(depth.x, depth.y), max(depth.z, depth.w));
  370. #elif DOWNSAMPLE_DEPTH_MODE == 2 // min/max depth in chessboard pattern
  371. float minDepth = min(min(depth.x, depth.y), min(depth.z, depth.w));
  372. float maxDepth = max(max(depth.x, depth.y), max(depth.z, depth.w));
  373. // chessboard pattern
  374. int2 position = input.vertex.xy % 2;
  375. int index = position.x + position.y;
  376. return index == 1 ? minDepth : maxDepth;
  377. #endif
  378. }
  379. //-----------------------------------------------------------------------------------------
  380. // GaussianWeight
  381. //-----------------------------------------------------------------------------------------
  382. float GaussianWeight(float offset, float deviation)
  383. {
  384. float weight = 1.0f / sqrt(2.0f * PI * deviation * deviation);
  385. weight *= exp(-(offset * offset) / (2.0f * deviation * deviation));
  386. return weight;
  387. }
  388. //-----------------------------------------------------------------------------------------
  389. // BilateralBlur
  390. //-----------------------------------------------------------------------------------------
  391. float4 BilateralBlur(v2f input, int2 direction, Texture2D depth, SamplerState depthSampler, const int kernelRadius, float2 pixelSize)
  392. {
  393. //const float deviation = kernelRadius / 2.5;
  394. const float deviation = kernelRadius / GAUSS_BLUR_DEVIATION; // make it really strong
  395. float2 uv = input.uv;
  396. float4 centerColor = SampleTexture(_MainTex,sampler_MainTex,uv);
  397. float3 color = centerColor.xyz;
  398. //return float4(color, 1);
  399. float centerDepth = LinearEyeDepth(SampleTexture(depth,depthSampler,uv));
  400. float weightSum = 0;
  401. // gaussian weight is computed from constants only -> will be computed in compile time
  402. float weight = GaussianWeight(0, deviation);
  403. color *= weight;
  404. weightSum += weight;
  405. [unroll] for (int i = -kernelRadius; i < 0; i += 1)
  406. {
  407. float2 offset = (direction * i);
  408. float3 sampleColor = SampleTexture(_MainTex,sampler_MainTex,input.uv,offset).rgb;
  409. float sampleDepth = LinearEyeDepth(SampleTexture(depth,depthSampler, input.uv, offset).x);
  410. float depthDiff = abs(centerDepth - sampleDepth);
  411. float dFactor = depthDiff * BLUR_DEPTH_FACTOR;
  412. float w = exp(-(dFactor * dFactor));
  413. // gaussian weight is computed from constants only -> will be computed in compile time
  414. weight = GaussianWeight(i, deviation) * w;
  415. color += weight * sampleColor;
  416. weightSum += weight;
  417. }
  418. [unroll] for (int k = 1; k <= kernelRadius; k += 1)
  419. {
  420. float2 offset = (direction * k);
  421. float3 sampleColor = SampleTexture(_MainTex,sampler_MainTex,input.uv,offset).rgb;
  422. float sampleDepth = LinearEyeDepth(SampleTexture(depth,depthSampler,input.uv,offset).x);
  423. float depthDiff = abs(centerDepth - sampleDepth);
  424. float dFactor = depthDiff * BLUR_DEPTH_FACTOR;
  425. float w = exp(-(dFactor * dFactor));
  426. // gaussian weight is computed from constants only -> will be computed in compile time
  427. weight = GaussianWeight(k, deviation) * w;
  428. color += weight * sampleColor;
  429. weightSum += weight;
  430. }
  431. color /= weightSum;
  432. return float4(color, centerColor.w);
  433. }
  434. #endif
  435. ENDCG
  436. // pass 0 - horizontal blur (hires)
  437. Pass
  438. {
  439. CGPROGRAM
  440. #pragma vertex vert
  441. #pragma fragment horizontalFrag
  442. #pragma target 3.5
  443. #pragma exclude_renderers gles
  444. #pragma multi_compile __ ENVIROURP
  445. fixed4 horizontalFrag(v2f input) : SV_Target
  446. {
  447. UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
  448. return BilateralBlur(input, int2(1, 0), _CameraDepthTexture, sampler_CameraDepthTexture, FULL_RES_BLUR_KERNEL_SIZE, _CameraDepthTexture_TexelSize.xy);
  449. //return SampleTexture(_MainTex,sampler_MainTex,input.uv);
  450. }
  451. ENDCG
  452. }
  453. // pass 1 - vertical blur (hires)
  454. Pass
  455. {
  456. CGPROGRAM
  457. #pragma vertex vert
  458. #pragma fragment verticalFrag
  459. #pragma target 3.5
  460. #pragma exclude_renderers gles
  461. #pragma multi_compile __ ENVIROURP
  462. fixed4 verticalFrag(v2f input) : SV_Target
  463. {
  464. UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
  465. return BilateralBlur(input, int2(0, 1), _CameraDepthTexture, sampler_CameraDepthTexture, FULL_RES_BLUR_KERNEL_SIZE, _CameraDepthTexture_TexelSize);
  466. }
  467. ENDCG
  468. }
  469. // pass 2 - horizontal blur (lores)
  470. Pass
  471. {
  472. CGPROGRAM
  473. #pragma vertex vert
  474. #pragma fragment horizontalFrag
  475. #pragma target 3.5
  476. #pragma exclude_renderers gles
  477. #pragma multi_compile __ ENVIROURP
  478. fixed4 horizontalFrag(v2f input) : SV_Target
  479. {
  480. UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
  481. return BilateralBlur(input, int2(1, 0), _HalfResDepthBuffer, sampler_HalfResDepthBuffer, HALF_RES_BLUR_KERNEL_SIZE, _HalfResDepthBuffer_TexelSize);
  482. }
  483. ENDCG
  484. }
  485. // pass 3 - vertical blur (lores)
  486. Pass
  487. {
  488. CGPROGRAM
  489. #pragma vertex vert
  490. #pragma fragment verticalFrag
  491. #pragma target 3.5
  492. #pragma exclude_renderers gles
  493. #pragma multi_compile __ ENVIROURP
  494. fixed4 verticalFrag(v2f input) : SV_Target
  495. {
  496. UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
  497. return BilateralBlur(input, int2(0, 1), _HalfResDepthBuffer, sampler_HalfResDepthBuffer, HALF_RES_BLUR_KERNEL_SIZE, _HalfResDepthBuffer_TexelSize);
  498. }
  499. ENDCG
  500. }
  501. // pass 4 - downsample depth to half
  502. Pass
  503. {
  504. CGPROGRAM
  505. #pragma vertex vertHalfDepth
  506. #pragma fragment frag
  507. // #pragma target gl4.1
  508. #pragma target 3.5
  509. #pragma exclude_renderers gles
  510. #pragma multi_compile __ ENVIROURP
  511. v2fDownsample vertHalfDepth(appdata v)
  512. {
  513. return vertDownsampleDepth(v, _CameraDepthTexture_TexelSize);
  514. }
  515. float4 frag(v2fDownsample input) : SV_Target
  516. {
  517. UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
  518. float depth = DownsampleDepth(input, _CameraDepthTexture, sampler_CameraDepthTexture);
  519. return float4(depth,depth,depth,depth);
  520. }
  521. ENDCG
  522. }
  523. // pass 5 - bilateral upsample
  524. Pass
  525. {
  526. Blend One Zero
  527. CGPROGRAM
  528. #pragma vertex vertUpsampleToFull
  529. #pragma fragment frag
  530. #pragma target 3.5
  531. #pragma exclude_renderers gles
  532. #pragma multi_compile __ ENVIROURP
  533. v2fUpsample vertUpsampleToFull(appdata v)
  534. {
  535. return vertUpsample(v, _HalfResDepthBuffer_TexelSize);
  536. }
  537. float4 frag(v2fUpsample input) : SV_Target
  538. {
  539. UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
  540. return BilateralUpsample(input, _CameraDepthTexture, _HalfResDepthBuffer, _HalfResColor, sampler_HalfResColor, sampler_HalfResDepthBuffer);
  541. }
  542. ENDCG
  543. }
  544. // pass 6 - downsample depth to quarter
  545. Pass
  546. {
  547. CGPROGRAM
  548. #pragma vertex vertQuarterDepth
  549. #pragma fragment frag
  550. //#pragma target gl4.1
  551. #pragma target 3.5
  552. #pragma exclude_renderers gles
  553. #pragma multi_compile __ ENVIROURP
  554. v2fDownsample vertQuarterDepth(appdata v)
  555. {
  556. return vertDownsampleDepth(v, _HalfResDepthBuffer_TexelSize);
  557. }
  558. float4 frag(v2fDownsample input) : SV_Target
  559. {
  560. UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
  561. float depth = DownsampleDepth(input, _HalfResDepthBuffer, sampler_HalfResDepthBuffer);
  562. return float4(depth,depth,depth,depth);
  563. }
  564. ENDCG
  565. }
  566. // pass 7 - bilateral upsample quarter to full
  567. Pass
  568. {
  569. Blend One Zero
  570. CGPROGRAM
  571. #pragma vertex vertUpsampleToFull
  572. #pragma fragment frag
  573. #pragma target 3.5
  574. #pragma exclude_renderers gles
  575. #pragma multi_compile __ ENVIROURP
  576. v2fUpsample vertUpsampleToFull(appdata v)
  577. {
  578. return vertUpsample(v, _QuarterResDepthBuffer_TexelSize);
  579. }
  580. float4 frag(v2fUpsample input) : SV_Target
  581. {
  582. UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
  583. return BilateralUpsample(input, _CameraDepthTexture, _QuarterResDepthBuffer, _QuarterResColor, sampler_QuarterResColor, sampler_QuarterResDepthBuffer);
  584. }
  585. ENDCG
  586. }
  587. // pass 8 - horizontal blur (quarter res)
  588. Pass
  589. {
  590. CGPROGRAM
  591. #pragma vertex vert
  592. #pragma fragment horizontalFrag
  593. #pragma target 3.5
  594. #pragma exclude_renderers gles
  595. #pragma multi_compile __ ENVIROURP
  596. fixed4 horizontalFrag(v2f input) : SV_Target
  597. {
  598. UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
  599. return BilateralBlur(input, int2(1, 0), _QuarterResDepthBuffer, sampler_QuarterResDepthBuffer, QUARTER_RES_BLUR_KERNEL_SIZE, _QuarterResDepthBuffer_TexelSize.xy);
  600. }
  601. ENDCG
  602. }
  603. // pass 9 - vertical blur (quarter res)
  604. Pass
  605. {
  606. CGPROGRAM
  607. #pragma vertex vert
  608. #pragma fragment verticalFrag
  609. #pragma target 3.5
  610. #pragma exclude_renderers gles
  611. #pragma multi_compile __ ENVIROURP
  612. fixed4 verticalFrag(v2f input) : SV_Target
  613. {
  614. UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
  615. return BilateralBlur(input, int2(0, 1), _QuarterResDepthBuffer, sampler_QuarterResDepthBuffer, QUARTER_RES_BLUR_KERNEL_SIZE, _QuarterResDepthBuffer_TexelSize.xy);
  616. }
  617. ENDCG
  618. }
  619. // pass 10 - downsample depth to half (fallback for DX10)
  620. Pass
  621. {
  622. CGPROGRAM
  623. #pragma vertex vertHalfDepth
  624. #pragma fragment frag
  625. #pragma target 3.5
  626. #pragma exclude_renderers gles
  627. #pragma multi_compile __ ENVIROURP
  628. v2fDownsample vertHalfDepth(appdata v)
  629. {
  630. return vertDownsampleDepth(v, _CameraDepthTexture_TexelSize);
  631. }
  632. float4 frag(v2fDownsample input) : SV_Target
  633. {
  634. UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
  635. float depth = DownsampleDepth(input, _CameraDepthTexture, sampler_CameraDepthTexture);
  636. return float4(depth,depth,depth,depth);
  637. }
  638. ENDCG
  639. }
  640. // pass 11 - downsample depth to quarter (fallback for DX10)
  641. Pass
  642. {
  643. CGPROGRAM
  644. #pragma vertex vertQuarterDepth
  645. #pragma fragment frag
  646. #pragma target 3.5
  647. #pragma exclude_renderers gles
  648. #pragma multi_compile __ ENVIROURP
  649. v2fDownsample vertQuarterDepth(appdata v)
  650. {
  651. return vertDownsampleDepth(v, _HalfResDepthBuffer_TexelSize);
  652. }
  653. float4 frag(v2fDownsample input) : SV_Target
  654. {
  655. UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
  656. float depth = DownsampleDepth(input, _HalfResDepthBuffer, sampler_HalfResDepthBuffer);
  657. return float4(depth,depth,depth,depth);
  658. }
  659. ENDCG
  660. }
  661. }
  662. }