Advertisement
Guest User

MXAO 2.0.10 beta2

a guest
Jun 3rd, 2017
268
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 21.03 KB | None | 0 0
  1. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2. // ReShade 3.0 effect file
  3. // visit facebook.com/MartyMcModding for news/updates
  4. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5. // Ambient Obscurance with Indirect Lighting "MXAO" 2.0.11 by Marty McFly
  6. // CC BY-NC-ND 3.0 licensed.
  7. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  8.  
  9. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  10. // Preprocessor Settings
  11. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  12.  
  13. #ifndef MXAO_MIPLEVEL_AO
  14. #define MXAO_MIPLEVEL_AO 0 //[0 to 2] Miplevel of AO texture. 0 = fullscreen, 1 = 1/2 screen width/height, 2 = 1/4 screen width/height and so forth. Best results: IL MipLevel = AO MipLevel + 2
  15. #endif
  16.  
  17. #ifndef MXAO_MIPLEVEL_IL
  18. #define MXAO_MIPLEVEL_IL 2 //[0 to 4] Miplevel of IL texture. 0 = fullscreen, 1 = 1/2 screen width/height, 2 = 1/4 screen width/height and so forth.
  19. #endif
  20.  
  21. #ifndef MXAO_ENABLE_IL
  22. #define MXAO_ENABLE_IL 0 //[0 or 1] Enables Indirect Lighting calculation. Will cause a major fps hit.
  23. #endif
  24.  
  25. #ifndef MXAO_ENABLE_BACKFACE
  26. #define MXAO_ENABLE_BACKFACE 1 //[0 or 1] Enables back face check so surfaces facing away from the source position don't cast light. Will cause a major fps hit.
  27. #endif
  28.  
  29. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  30. // UI variables
  31. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  32.  
  33. uniform float fMXAOAmbientOcclusionAmount <
  34. ui_type = "drag";
  35. ui_min = 0.00; ui_max = 3.00;
  36. ui_label = "Ambient Occlusion Amount";
  37. ui_tooltip = "Linearly increases AO intensity. Can cause pitch black clipping if set too high.";
  38. > = 2.00;
  39.  
  40. uniform float fMXAOIndirectLightingAmount <
  41. ui_type = "drag";
  42. ui_min = 0.00; ui_max = 12.00;
  43. ui_label = "Indirect Lighting Amount";
  44. ui_tooltip = "Linearly increases IL intensity. Can cause overexposured white spots if set too high.\nEnable SSIL in preprocessor section.";
  45. > = 4.00;
  46.  
  47. uniform float fMXAOIndirectLightingSaturation <
  48. ui_type = "drag";
  49. ui_min = 0.00; ui_max = 3.00;
  50. ui_label = "Indirect Lighting Saturation";
  51. ui_tooltip = "Boosts IL saturation for more pronounced effect.\nEnable SSIL in preprocessor section.";
  52. > = 1.00;
  53.  
  54. uniform float fMXAOSampleRadius <
  55. ui_type = "drag";
  56. ui_min = 1.00; ui_max = 8.00;
  57. ui_label = "Sample Radius";
  58. ui_tooltip = "Sample radius of GI, higher means more large-scale occlusion with less fine-scale details.";
  59. > = 2.50;
  60.  
  61. uniform int iMXAOSampleCount <
  62. ui_type = "drag";
  63. ui_min = 8; ui_max = 255;
  64. ui_label = "Sample Count";
  65. ui_tooltip = "Amount of MXAO samples. Higher means more accurate and less noisy AO at the cost of fps.";
  66. > = 24;
  67.  
  68. uniform int iMXAOBayerDitherLevel <
  69. ui_type = "drag";
  70. ui_min = 2; ui_max = 8;
  71. ui_label = "Dither Size";
  72. ui_tooltip = "Factor of 'random' rotation pattern size.\nHigher means less distinctive haloing but noisier AO.\nSet Blur Steps to 0 to see effect better.";
  73. > = 3;
  74.  
  75. uniform float fMXAONormalBias <
  76. ui_type = "drag";
  77. ui_min = 0.0; ui_max = 0.8;
  78. ui_label = "Normal Bias";
  79. ui_tooltip = "Normals bias to reduce self-occlusion of surfaces that have a low angle to each other.";
  80. > = 0.2;
  81.  
  82. uniform bool bMXAOSmoothNormalsEnable <
  83. ui_label = "Enable Smoothed Normals";
  84. ui_tooltip = "Enable smoothed normals. WIP.";
  85. > = false;
  86.  
  87. uniform float fMXAOBlurSharpness <
  88. ui_type = "drag";
  89. ui_min = 0.00; ui_max = 5.00;
  90. ui_label = "Blur Sharpness";
  91. ui_tooltip = "AO sharpness, higher means sharper geometry edges but noisier AO, less means smoother AO but blurry in the distance.";
  92. > = 2.00;
  93.  
  94. uniform int fMXAOBlurSteps <
  95. ui_type = "drag";
  96. ui_min = 0; ui_max = 5;
  97. ui_label = "Blur Steps";
  98. ui_tooltip = "Offset count for AO bilateral blur filter. Higher means smoother but also blurrier AO.";
  99. > = 2;
  100.  
  101. uniform bool bMXAODebugViewEnable <
  102. ui_label = "Enable Debug View";
  103. ui_tooltip = "Enables raw AO/IL output for debugging and tuning purposes.";
  104. > = false;
  105.  
  106. uniform float fMXAOFadeoutStart <
  107. ui_type = "drag";
  108. ui_label = "Distance Fade Start";
  109. ui_min = 0.00; ui_max = 1.00;
  110. ui_tooltip = "Distance where MXAO starts to fade out. 0 = camera distance, 1 = infinite distance (sky).";
  111. > = 0.2;
  112.  
  113. uniform float fMXAOFadeoutEnd <
  114. ui_type = "drag";
  115. ui_label = "Distance Fade End";
  116. ui_min = 0.00; ui_max = 1.00;
  117. ui_tooltip = "Distance where MXAO completely fades out. 0 = camera distance, 1 = infinite distance (sky).";
  118. > = 0.4;
  119.  
  120. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  121. // Include global utility
  122. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  123.  
  124. #include "ReShade.fxh"
  125.  
  126. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  127. // Textures, Samplers
  128. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  129.  
  130. texture2D texColorBypass { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA8; MipLevels = 5+MXAO_MIPLEVEL_IL;};
  131. texture2D texDistance { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = R16F; MipLevels = 5+MXAO_MIPLEVEL_AO;};
  132. texture2D texSurfaceNormal { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA8; MipLevels = 5+MXAO_MIPLEVEL_IL;};
  133. sampler2D SamplerColorBypass { Texture = texColorBypass; };
  134. sampler2D SamplerDistance { Texture = texDistance; };
  135. sampler2D SamplerSurfaceNormal { Texture = texSurfaceNormal; };
  136.  
  137. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  138. // Functions
  139. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  140.  
  141. /* Fetches linearized depth value. depth data ~ distance from camera
  142. and 0 := camera, 1:= "infinite" distance, e.g. sky. */
  143. float GetLinearDepth(float2 coords)
  144. {
  145. return ReShade::GetLinearizedDepth(coords);
  146. }
  147.  
  148. /* Fetches position relative to camera. This is somewhat inaccurate
  149. as it assumes FoV == 90 degrees but yields good enough results.
  150. Axes are multiplied with far plane to better scale the occlusion
  151. falloff and save instruction in AO main pass. Also using a bigger
  152. data range seems to reduce precision artifacts for logarithmic
  153. depth buffer option. */
  154. float3 GetPosition(float2 coords)
  155. {
  156. return float3(coords.xy*2.0-1.0,1.0)*GetLinearDepth(coords.xy)*RESHADE_DEPTH_LINEARIZATION_FAR_PLANE;
  157. }
  158.  
  159. /* Same as above, except linearized and scaled data is already stored
  160. in dedicated texture and we're sampling mipmaps here. */
  161. float3 GetPositionLOD(float2 coords, float mipLevel)
  162. {
  163. return float3(coords.xy*2.0-1.0,1.0)*tex2Dlod(SamplerDistance, float4(coords.xy,0,mipLevel)).x;
  164. }
  165.  
  166. /* Calculates normals based on partial depth buffer derivatives.
  167. Does a similar job to ddx/ddy but this is higher quality and
  168. it also takes care for object borders where usual ddx/ddy produce
  169. inaccurate normals.*/
  170. float3 GetNormalFromDepth(float2 coords)
  171. {
  172. float3 offs = float3(ReShade::PixelSize.xy,0);
  173.  
  174. float3 f = GetPosition(coords.xy);
  175. float3 d_dx1 = - f + GetPosition(coords.xy + offs.xz);
  176. float3 d_dx2 = f - GetPosition(coords.xy - offs.xz);
  177. float3 d_dy1 = - f + GetPosition(coords.xy + offs.zy);
  178. float3 d_dy2 = f - GetPosition(coords.xy - offs.zy);
  179.  
  180. d_dx1 = lerp(d_dx1, d_dx2, abs(d_dx1.z) > abs(d_dx2.z));
  181. d_dy1 = lerp(d_dy1, d_dy2, abs(d_dy1.z) > abs(d_dy2.z));
  182.  
  183. return normalize(cross(d_dy1,d_dx1));
  184. }
  185.  
  186. /* Box blur on normal map texture. Yes, it's as stupid as it sounds
  187. but helps nicely to get rid of too obvious geometry lines in
  188. landscape where a plain normal bias doesn't cut it. After all
  189. we're doing approximations over approximations. */
  190. float3 GetSmoothedNormals(float2 texcoord, float3 ScreenSpaceNormals, float3 ScreenSpacePosition)
  191. {
  192. float4 blurnormal = 0.0;
  193. [loop]
  194. for(float x = -3; x <= 3; x++)
  195. {
  196. [loop]
  197. for(float y = -3; y <= 3; y++)
  198. {
  199. float2 offsetcoord = texcoord.xy + float2(x,y) * ReShade::PixelSize.xy * 3.5;
  200. float3 samplenormal = normalize(tex2Dlod(SamplerSurfaceNormal,float4(offsetcoord,0,2)).xyz * 2.0 - 1.0);
  201. float3 sampleposition = GetPositionLOD(offsetcoord.xy,2);
  202. float weight = saturate(1.0 - distance(ScreenSpacePosition.xyz,sampleposition.xyz)*1.2);
  203. weight *= smoothstep(0.5,1.0,dot(samplenormal,ScreenSpaceNormals));
  204. blurnormal.xyz += samplenormal * weight;
  205. blurnormal.w += weight;
  206. }
  207. }
  208.  
  209. return normalize(blurnormal.xyz / (0.0001 + blurnormal.w) + ScreenSpaceNormals*0.05);
  210. }
  211.  
  212. /* Fetches normal and depth data for bilateral AO blur weight
  213. calculation. As we already have linearized depth as own texture,
  214. we might as well use it and save some instructions, also R16F
  215. is lower than usual R32F original game depth data.*/
  216. float4 GetBlurFactors(float2 coords)
  217. {
  218. return float4(tex2Dlod(SamplerSurfaceNormal, float4(coords.xy,0,0)).xyz*2.0-1.0,tex2Dlod(SamplerDistance, float4(coords.xy,0,0)).x);
  219. }
  220.  
  221. /* Calculates weights for bilateral AO blur. Using only
  222. depth is surely faster but it doesn't really cut it, also
  223. areas with a flat angle to the camera will have high depth
  224. differences, hence blur will cause stripes as seen in many
  225. AO implementations, even HBAO+. Taking view angle into
  226. account greatly helps to reduce these problems. */
  227. float GetBlurWeight(float4 tempKey, float4 centerKey, float surfacealignment)
  228. {
  229. float depthdiff = abs(tempKey.w-centerKey.w);
  230. float normaldiff = 1.0-saturate(dot(normalize(tempKey.xyz),normalize(centerKey.xyz)));
  231.  
  232. float depthweight = saturate(rcp(fMXAOBlurSharpness*depthdiff*5.0*surfacealignment));
  233. float normalweight = saturate(rcp(fMXAOBlurSharpness*normaldiff*10.0));
  234.  
  235. return min(normalweight,depthweight);
  236. }
  237.  
  238. /* Bilateral blur, exploiting bilinear filter
  239. for additional blurring. Intel paper covered
  240. faster gaussian blur with similar offset and
  241. weight development of discrete gaussian, this
  242. here is basically the same, only applied on
  243. box blur. This function only blurs AO and reads
  244. the normals from RGB channel of backbuffer.*/
  245. float4 GetBlurredAO( float2 texcoord, sampler inputsampler, float2 axis, int nSteps)
  246. {
  247. float4 tempsample;
  248. float4 centerkey , tempkey;
  249. float centerweight, tempweight;
  250. float surfacealignment;
  251. float4 blurcoord = 0.0;
  252. float AO = 0.0;
  253.  
  254. tempsample = tex2D(inputsampler,texcoord.xy);
  255. centerkey = float4(tempsample.xyz*2-1,tex2Dlod(SamplerDistance,float4(texcoord.xy,0,0)).x);
  256. centerweight = 0.5;
  257. AO = tempsample.w * 0.5;
  258. surfacealignment = saturate(-dot(centerkey.xyz,normalize(float3(texcoord.xy*2.0-1.0,1.0)*centerkey.w)));
  259.  
  260. [loop]
  261. for(int orientation=-1;orientation<=1; orientation+=2)
  262. {
  263. [loop]
  264. for(float iStep = 1.0; iStep <= nSteps; iStep++)
  265. {
  266. blurcoord.xy = (2.0 * iStep - 0.5) * orientation * axis * ReShade::PixelSize.xy + texcoord.xy;
  267. tempsample = tex2Dlod(inputsampler, blurcoord);
  268. tempkey = float4(tempsample.xyz*2-1,tex2Dlod(SamplerDistance,blurcoord).x);
  269. tempweight = GetBlurWeight(tempkey, centerkey, surfacealignment);
  270. AO += tempsample.w * tempweight;
  271. centerweight += tempweight;
  272. }
  273. }
  274.  
  275. return float4(centerkey.xyz*0.5+0.5, AO / centerweight);
  276. }
  277.  
  278. /* Same as above, except it blurs RGBA and hence
  279. needs to read normals separately. */
  280. float4 GetBlurredAOIL( float2 texcoord, sampler inputsampler, float2 axis, int nSteps)
  281. {
  282. float4 tempsample;
  283. float4 centerkey , tempkey;
  284. float centerweight, tempweight;
  285. float surfacealignment;
  286. float4 blurcoord = 0.0;
  287. float4 AO_IL = 0.0;
  288.  
  289. tempsample = tex2D(inputsampler,texcoord.xy);
  290. centerkey = float4(tex2Dlod(SamplerSurfaceNormal,float4(texcoord.xy,0,0)).xyz*2-1,tex2Dlod(SamplerDistance,float4(texcoord.xy,0,0)).x);
  291. centerweight = 0.5;
  292. AO_IL = tempsample * 0.5;
  293. surfacealignment = saturate(-dot(centerkey.xyz,normalize(float3(texcoord.xy*2.0-1.0,1.0)*centerkey.w)));
  294.  
  295. [loop]
  296. for(int orientation=-1;orientation<=1; orientation+=2)
  297. {
  298. [loop]
  299. for(float iStep = 1.0; iStep <= nSteps; iStep++)
  300. {
  301. blurcoord.xy = (2.0 * iStep - 0.5) * orientation * axis * ReShade::PixelSize.xy + texcoord.xy;
  302. tempsample = tex2Dlod(inputsampler, blurcoord);
  303. tempkey = float4(tex2Dlod(SamplerSurfaceNormal,blurcoord).xyz*2-1,tex2Dlod(SamplerDistance,blurcoord).x);
  304. tempweight = GetBlurWeight(tempkey, centerkey, surfacealignment);
  305. AO_IL += tempsample * tempweight;
  306. centerweight += tempweight;
  307. }
  308. }
  309.  
  310. return float4(AO_IL / centerweight);
  311. }
  312.  
  313. /* Calculates the bayer dither pattern that's used to jitter
  314. the direction of the AO samples per pixel.
  315. Why this instead of precalculated texture? BECAUSE I CAN.
  316. Using this ordered jitter instead of a pseudorandom one
  317. has 3 advantages: it seems to be more cache-aware, the AO
  318. is (given a fitting AO sample distribution pattern) a lot less
  319. noisy (better variance, see Alchemy AO) and bilateral blur
  320. needs a much smaller kernel: from my tests a blur kernel
  321. of 5x5 is fine for most settings, but using a pseudorandom
  322. distribution still has noticeable grain with 12x12++.
  323. Smaller bayer matrix sizes have more obvious directional
  324. AO artifacts but are easier to blur. */
  325. float GetBayerFromCoordLevel(float2 pixelpos, int maxLevel)
  326. {
  327. float finalBayer = 0.0;
  328.  
  329. for(float i = 1-maxLevel; i<= 0; i++)
  330. {
  331. float bayerSize = exp2(i);
  332. float2 bayerCoord = floor(pixelpos * bayerSize) % 2.0;
  333. float bayer = 2.0 * bayerCoord.x - 4.0 * bayerCoord.x * bayerCoord.y + 3.0 * bayerCoord.y;
  334. finalBayer += exp2(2.0*(i+maxLevel))* bayer;
  335. }
  336.  
  337. float finalDivisor = 4.0 * exp2(2.0 * maxLevel)- 4.0;
  338. //raising all values by increment is false but in AO pass it makes sense. Can you see it?
  339. return finalBayer/ finalDivisor + 1.0/exp2(2.0 * maxLevel);
  340. }
  341.  
  342. /* Main AO pass. The samples are taken in an outward spiral,
  343. that way a simple rotation matrix is enough to provide
  344. the sample locations. The rotation angle is fine-tuned,
  345. it yields an optimal (optimal as in "I couldn't find a better one")
  346. sample distribution. Vogel algorithm uses the golden angle,
  347. and samples are more uniformly distributed over the disc but
  348. AO quality suffers a lot of samples are lining up (having the
  349. same sampling direction). Test it yourself: make angle depending
  350. on texcoord.x and you'll see that AO quality is highly depending
  351. on angle. Mara and McGuire solve this in their Alchemy AO approach
  352. by providing a hand-selected rotation for each sample count,
  353. however my angle seems to produce better results and doesn't require
  354. declaring a huge constant array or any CPU side code. */
  355. float4 GetMXAO(float2 texcoord,
  356. float3 normal,
  357. float3 position,
  358. float nSamples,
  359. float2 currentVector,
  360. float mipFactor,
  361. float falloffFactor,
  362. float angleFactor,
  363. float radiusJitter,
  364. float sampleRadius)
  365. {
  366. float4 AO_IL = 0.0;
  367. float2 currentOffset;
  368.  
  369. [loop]
  370. for(int iSample=0; iSample < nSamples; iSample++)
  371. {
  372. currentVector = mul(currentVector.xy, float2x2(0.575,0.81815,-0.81815,0.575));
  373. currentOffset = texcoord.xy + currentVector.xy * float2(1.0,ReShade::AspectRatio) * (iSample + radiusJitter);
  374.  
  375. float mipLevel = 5*saturate(1.41-rcp(mipFactor*iSample+0.01));
  376. float3 occlVec = -position + GetPositionLOD(currentOffset.xy, mipLevel);
  377.  
  378. float fAO = saturate(dot(occlVec,occlVec)*falloffFactor + 1.0) * saturate(dot(occlVec, normal)*angleFactor - fMXAONormalBias);
  379.  
  380. #if(MXAO_ENABLE_IL != 0)
  381. [branch]
  382. if(fAO > 0.1)
  383. {
  384. float3 fIL = tex2Dlod(SamplerColorBypass, float4(currentOffset,0,mipLevel + MXAO_MIPLEVEL_IL)).xyz;
  385. #if(MXAO_ENABLE_BACKFACE != 0)
  386. float3 offsetNormals = tex2Dlod(SamplerSurfaceNormal, float4(currentOffset,0,mipLevel + MXAO_MIPLEVEL_IL)).xyz * 2.0 - 1.0;
  387. fIL = fIL - fIL*saturate(dot(occlVec,offsetNormals)*angleFactor*2.0);
  388. #endif
  389. AO_IL += fAO * float4(fIL,1 - dot(fIL,0.333));
  390. }
  391. #else
  392. AO_IL.w += fAO;
  393. #endif
  394. }
  395. return saturate(AO_IL/(0.5*(1.0-fMXAONormalBias)*nSamples));
  396. }
  397.  
  398. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  399. // Pixel Shaders
  400. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  401.  
  402. /* Setup color, depth and normal data. Alpha channel of normal
  403. texture provides the per pixel jitter for AO sampling. */
  404. void PS_AO_Pre(float4 vpos : SV_Position, float2 texcoord : TEXCOORD, out float4 color : SV_Target0, out float4 depth : SV_Target1, out float4 normal : SV_Target2)
  405. {
  406. color = tex2D(ReShade::BackBuffer, texcoord.xy);
  407. depth = GetLinearDepth(texcoord.xy)*RESHADE_DEPTH_LINEARIZATION_FAR_PLANE;
  408. normal.xyz = GetNormalFromDepth(texcoord.xy).xyz * 0.5 + 0.5;
  409. normal.w = GetBayerFromCoordLevel(vpos.xy,iMXAOBayerDitherLevel);
  410. }
  411.  
  412. void PS_AO_Gen(float4 vpos : SV_Position, float2 texcoord : TEXCOORD, out float4 res : SV_Target0)
  413. {
  414. float4 normalSample = tex2D(SamplerSurfaceNormal, texcoord.xy);
  415.  
  416. float3 ScreenSpaceNormals = normalSample.xyz * 2.0 - 1.0;
  417. float3 ScreenSpacePosition = GetPositionLOD(texcoord.xy, 0);
  418.  
  419. [branch]
  420. if(bMXAOSmoothNormalsEnable)
  421. {
  422. ScreenSpaceNormals = GetSmoothedNormals(texcoord, ScreenSpaceNormals, ScreenSpacePosition);
  423. }
  424.  
  425. ScreenSpacePosition += ScreenSpaceNormals * ScreenSpacePosition.z / RESHADE_DEPTH_LINEARIZATION_FAR_PLANE;;
  426.  
  427. float SampleRadiusScaled = 0.4 * fMXAOSampleRadius / (iMXAOSampleCount * ScreenSpacePosition.z);
  428. float mipFactor = SampleRadiusScaled * 45.0;
  429.  
  430. float2 currentVector;
  431. sincos(2.0*3.14159274*normalSample.w, currentVector.y, currentVector.x);
  432. static const float angleFactor = 2.0 / fMXAOSampleRadius;
  433. static const float falloffFactor = -1.0/(fMXAOSampleRadius*fMXAOSampleRadius);
  434. currentVector *= SampleRadiusScaled;
  435.  
  436. res = GetMXAO(texcoord,
  437. ScreenSpaceNormals,
  438. ScreenSpacePosition,
  439. iMXAOSampleCount,
  440. currentVector,
  441. mipFactor,
  442. falloffFactor,
  443. angleFactor,
  444. normalSample.w,
  445. fMXAOSampleRadius);
  446.  
  447. res = sqrt(res); //AO denoise
  448.  
  449. #if(MXAO_ENABLE_IL == 0)
  450. res.xyz = normalSample.xyz;
  451. #endif
  452. }
  453.  
  454. /* Box blur instead of gaussian seems to produce better
  455. results for low kernel sizes. The offsets and weights
  456. here make use of bilinear sampling, hence sampling
  457. in 1.5 .. 3.5 ... 5.5 pixel offsets.*/
  458. void PS_AO_Blur1(float4 vpos : SV_Position, float2 texcoord : TEXCOORD, out float4 res : SV_Target0)
  459. {
  460. #if(MXAO_ENABLE_IL != 0)
  461. res = GetBlurredAOIL(texcoord.xy, ReShade::BackBuffer, float2(1.0,0.0), fMXAOBlurSteps);
  462. #else
  463. res = GetBlurredAO(texcoord.xy, ReShade::BackBuffer, float2(1.0,0.0), fMXAOBlurSteps);
  464. #endif
  465. }
  466.  
  467. /* Second box blur pass and AO/IL combine. The given formula
  468. yields to actual physical background or anything, it's just
  469. a lot more visually pleasing than most formulas of similar
  470. implementations.*/
  471. void PS_AO_Blur2(float4 vpos : SV_Position, float2 texcoord : TEXCOORD, out float4 res : SV_Target0)
  472. {
  473. #if(MXAO_ENABLE_IL != 0)
  474. float4 MXAO = GetBlurredAOIL(texcoord.xy, ReShade::BackBuffer, float2(0.0,1.0), fMXAOBlurSteps);
  475. #else
  476. float4 MXAO = GetBlurredAO(texcoord.xy, ReShade::BackBuffer, float2(0.0,1.0), fMXAOBlurSteps);
  477. MXAO.xyz = 0;
  478. #endif
  479.  
  480. MXAO *= MXAO; //AO denoise
  481.  
  482. float scenedepth = GetLinearDepth(texcoord.xy);
  483. float4 color = max(0.0,tex2D(SamplerColorBypass, texcoord.xy));
  484. float colorgray = dot(color.xyz,float3(0.299,0.587,0.114));
  485.  
  486. MXAO.xyz = lerp(dot(MXAO.xyz,float3(0.299,0.587,0.114)),MXAO.xyz,fMXAOIndirectLightingSaturation) * fMXAOIndirectLightingAmount * 4;
  487. MXAO.w = 1.0-pow(1.0-MXAO.w, fMXAOAmbientOcclusionAmount*4.0);
  488.  
  489. MXAO = (bMXAODebugViewEnable) ? MXAO : lerp(MXAO, 0.0, pow(colorgray,2.0));
  490.  
  491. MXAO.w = lerp(MXAO.w, 0.0,smoothstep(fMXAOFadeoutStart, fMXAOFadeoutEnd, scenedepth));
  492. MXAO.xyz = lerp(MXAO.xyz,0.0,smoothstep(fMXAOFadeoutStart*0.5, fMXAOFadeoutEnd*0.5, scenedepth));
  493.  
  494. float3 GI = max(0.0,1.0 + MXAO.xyz - MXAO.w);
  495. color.xyz *= GI;
  496.  
  497. if(bMXAODebugViewEnable) //can't move this into ternary as one is preprocessor def and the other is a uniform
  498. {
  499. color.xyz = (MXAO_ENABLE_IL != 0) ? GI*0.5 : GI;
  500. }
  501.  
  502. res = color;
  503. }
  504.  
  505. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  506. // Technique
  507. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  508.  
  509. technique MXAO
  510. {
  511. pass P0
  512. {
  513. VertexShader = PostProcessVS;
  514. PixelShader = PS_AO_Pre;
  515. RenderTarget0 = texColorBypass;
  516. RenderTarget1 = texDistance;
  517. RenderTarget2 = texSurfaceNormal;
  518. }
  519. pass P1
  520. {
  521. VertexShader = PostProcessVS;
  522. PixelShader = PS_AO_Gen;
  523. /*Render Target is Backbuffer*/
  524. }
  525. pass P2_0
  526. {
  527. VertexShader = PostProcessVS;
  528. PixelShader = PS_AO_Blur1;
  529. /*Render Target is Backbuffer*/
  530. }
  531. pass P2_1
  532. {
  533. VertexShader = PostProcessVS;
  534. PixelShader = PS_AO_Blur2;
  535. /*Render Target is Backbuffer*/
  536. }
  537. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement