Advertisement
Guest User

MXAO 2.1.015

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