Advertisement
Guest User

mxao_resize_pass

a guest
Jul 20th, 2019
460
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 25.79 KB | None | 0 0
  1. /*=============================================================================
  2.  
  3. ReShade 4 effect file
  4. github.com/martymcmodding
  5.  
  6. Support me:
  7. paypal.me/mcflypg
  8. patreon.com/mcflypg
  9.  
  10. Ambient Obscurance with Indirect Lighting "MXAO"
  11. by Marty McFly / P.Gilcher
  12. part of qUINT shader library for ReShade 3
  13.  
  14. CC BY-NC-ND 3.0 licensed.
  15.  
  16. =============================================================================*/
  17.  
  18. /*=============================================================================
  19. Preprocessor settings
  20. =============================================================================*/
  21.  
  22. #ifndef MXAO_MIPLEVEL_AO
  23. #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
  24. #endif
  25.  
  26. #ifndef MXAO_MIPLEVEL_IL
  27. #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.
  28. #endif
  29.  
  30. #ifndef MXAO_ENABLE_IL
  31. #define MXAO_ENABLE_IL 0 //[0 or 1] Enables Indirect Lighting calculation. Will cause a major fps hit.
  32. #endif
  33.  
  34. #ifndef MXAO_SMOOTHNORMALS
  35. #define MXAO_SMOOTHNORMALS 0 //[0 or 1] This feature makes low poly surfaces smoother, especially useful on older games.
  36. #endif
  37.  
  38. #ifndef MXAO_TWO_LAYER
  39. #define MXAO_TWO_LAYER 0 //[0 or 1] Splits MXAO into two separate layers that allow for both large and fine AO.
  40. #endif
  41.  
  42. #ifndef MXAO_HQ
  43. #define MXAO_HQ 0 //[0 or 1] Enables a different, more physically accurate but slower SSAO mode. Based on Ground Truth Ambient Occlusion by Activision. No IL yet.
  44. #endif
  45.  
  46. /*=============================================================================
  47. UI Uniforms
  48. =============================================================================*/
  49.  
  50. uniform int MXAO_GLOBAL_SAMPLE_QUALITY_PRESET <
  51. ui_type = "combo";
  52. ui_label = "Sample Quality";
  53. ui_items = "Very Low (4 samples)\0Low (8 samples)\0Medium (16 samples)\0High (24 samples)\0Very High (32 samples)\0Ultra (64 samples)\0Maximum (255 samples)\0Auto (variable)\0";
  54. ui_tooltip = "Global quality control, main performance knob. Higher radii might require higher quality.";
  55. ui_category = "Global";
  56. > = 2;
  57.  
  58. uniform float MXAO_SAMPLE_RADIUS <
  59. ui_type = "drag";
  60. ui_min = 0.5; ui_max = 100.0;
  61. ui_label = "Sample Radius";
  62. ui_tooltip = "Sample radius of MXAO, higher means more large-scale occlusion with less fine-scale details.";
  63. ui_category = "Global";
  64. > = 2.5;
  65.  
  66. #if (MXAO_HQ==0)
  67. uniform float MXAO_SAMPLE_NORMAL_BIAS <
  68. ui_type = "drag";
  69. ui_min = 0.0; ui_max = 0.8;
  70. ui_label = "Normal Bias";
  71. ui_tooltip = "Occlusion Cone bias to reduce self-occlusion of surfaces that have a low angle to each other.";
  72. ui_category = "Global";
  73. > = 0.2;
  74. #else
  75. #define MXAO_SAMPLE_NORMAL_BIAS 0 //don't break PS which needs this, cleaner this way
  76. #endif
  77.  
  78. uniform float MXAO_GLOBAL_RENDER_SCALE <
  79. ui_type = "drag";
  80. ui_label = "Render Size Scale";
  81. ui_min = 0.50; ui_max = 1.00;
  82. 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...";
  83. ui_category = "Global";
  84. > = 1.0;
  85.  
  86. uniform float MXAO_SSAO_AMOUNT <
  87. ui_type = "drag";
  88. ui_min = 0.00; ui_max = 4.00;
  89. ui_label = "Ambient Occlusion Amount";
  90. ui_tooltip = "Intensity of AO effect. Can cause pitch black clipping if set too high.";
  91. ui_category = "Ambient Occlusion";
  92. > = 1.00;
  93.  
  94. #if(MXAO_ENABLE_IL != 0)
  95. uniform float MXAO_SSIL_AMOUNT <
  96. ui_type = "drag";
  97. ui_min = 0.00; ui_max = 12.00;
  98. ui_label = "Indirect Lighting Amount";
  99. ui_tooltip = "Intensity of IL effect. Can cause overexposured white spots if set too high.";
  100. ui_category = "Indirect Lighting";
  101. > = 4.00;
  102.  
  103. uniform float MXAO_SSIL_SATURATION <
  104. ui_type = "drag";
  105. ui_min = 0.00; ui_max = 3.00;
  106. ui_label = "Indirect Lighting Saturation";
  107. ui_tooltip = "Controls color saturation of IL effect.";
  108. ui_category = "Indirect Lighting";
  109. > = 1.00;
  110. #endif
  111.  
  112. #if (MXAO_TWO_LAYER != 0)
  113. uniform float MXAO_SAMPLE_RADIUS_SECONDARY <
  114. ui_type = "drag";
  115. ui_min = 0.1; ui_max = 1.00;
  116. ui_label = "Fine AO Scale";
  117. 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.";
  118. ui_category = "Double Layer";
  119. > = 0.2;
  120.  
  121. uniform float MXAO_AMOUNT_FINE <
  122. ui_type = "drag";
  123. ui_min = 0.00; ui_max = 1.00;
  124. ui_label = "Fine AO intensity multiplier";
  125. ui_tooltip = "Intensity of small scale AO / IL.";
  126. ui_category = "Double Layer";
  127. > = 1.0;
  128.  
  129. uniform float MXAO_AMOUNT_COARSE <
  130. ui_type = "drag";
  131. ui_min = 0.00; ui_max = 1.00;
  132. ui_label = "Coarse AO intensity multiplier";
  133. ui_tooltip = "Intensity of large scale AO / IL.";
  134. ui_category = "Double Layer";
  135. > = 1.0;
  136. #endif
  137.  
  138. uniform int MXAO_BLEND_TYPE <
  139. ui_type = "slider";
  140. ui_min = 0; ui_max = 3;
  141. ui_label = "Blending Mode";
  142. ui_tooltip = "Different blending modes for merging AO/IL with original color.\0Blending mode 0 matches formula of MXAO 2.0 and older.";
  143. ui_category = "Blending";
  144. > = 0;
  145.  
  146. uniform float MXAO_FADE_DEPTH_START <
  147. ui_type = "drag";
  148. ui_label = "Fade Out Start";
  149. ui_min = 0.00; ui_max = 1.00;
  150. ui_tooltip = "Distance where MXAO starts to fade out. 0.0 = camera, 1.0 = sky. Must be less than Fade Out End.";
  151. ui_category = "Blending";
  152. > = 0.05;
  153.  
  154. uniform float MXAO_FADE_DEPTH_END <
  155. ui_type = "drag";
  156. ui_label = "Fade Out End";
  157. ui_min = 0.00; ui_max = 1.00;
  158. ui_tooltip = "Distance where MXAO completely fades out. 0.0 = camera, 1.0 = sky. Must be greater than Fade Out Start.";
  159. ui_category = "Blending";
  160. > = 0.4;
  161.  
  162. uniform int MXAO_DEBUG_VIEW_ENABLE <
  163. ui_type = "combo";
  164. ui_label = "Enable Debug View";
  165. ui_items = "None\0AO/IL channel\0Normal vectors\0";
  166. ui_tooltip = "Different debug outputs";
  167. ui_category = "Debug";
  168. > = 0;
  169.  
  170. /*=============================================================================
  171. Textures, Samplers, Globals
  172. =============================================================================*/
  173.  
  174. #include "qUINT_common.fxh"
  175.  
  176. texture2D MXAO_ColorTex { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA8; MipLevels = 3+MXAO_MIPLEVEL_IL;};
  177. texture2D MXAO_DepthTex { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = R16F; MipLevels = 3+MXAO_MIPLEVEL_AO;};
  178. texture2D MXAO_NormalTex { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA8; MipLevels = 3+MXAO_MIPLEVEL_IL;};
  179. texture2D texResized { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; };
  180. texture2D texResized2 { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; };
  181.  
  182. sampler2D sMXAO_ColorTex { Texture = MXAO_ColorTex; };
  183. sampler2D sMXAO_DepthTex { Texture = MXAO_DepthTex; };
  184. sampler2D sMXAO_NormalTex { Texture = MXAO_NormalTex; };
  185. sampler2D sResized { Texture = texResized; };
  186. sampler2D sResized2 { Texture = texResized2; };
  187.  
  188. #if(MXAO_ENABLE_IL != 0)
  189. #define BLUR_COMP_SWIZZLE xyzw
  190. #else
  191. #define BLUR_COMP_SWIZZLE w
  192. #endif
  193.  
  194. /*=============================================================================
  195. Vertex Shader
  196. =============================================================================*/
  197.  
  198. struct MXAO_VSOUT
  199. {
  200. float4 vpos : SV_Position;
  201. float4 uv : TEXCOORD0;
  202. nointerpolation float samples : TEXCOORD1;
  203. nointerpolation float3 uvtoviewADD : TEXCOORD4;
  204. nointerpolation float3 uvtoviewMUL : TEXCOORD5;
  205. };
  206.  
  207. struct BlurData
  208. {
  209. float4 key;
  210. float4 mask;
  211. };
  212.  
  213. MXAO_VSOUT VS_MXAO(in uint id : SV_VertexID)
  214. {
  215. MXAO_VSOUT MXAO;
  216.  
  217. MXAO.uv.x = (id == 2) ? 2.0 : 0.0;
  218. MXAO.uv.y = (id == 1) ? 2.0 : 0.0;
  219. MXAO.uv.zw = MXAO.uv.xy / MXAO_GLOBAL_RENDER_SCALE;
  220. MXAO.vpos = float4(MXAO.uv.xy * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
  221.  
  222. static const int samples_per_preset[8] = {4, 8, 16, 24, 32, 64, 255, 8 /*overridden*/};
  223. MXAO.samples = samples_per_preset[MXAO_GLOBAL_SAMPLE_QUALITY_PRESET];
  224.  
  225. MXAO.uvtoviewADD = float3(-1.0,-1.0,1.0);
  226. MXAO.uvtoviewMUL = float3(2.0,2.0,0.0);
  227.  
  228. #if 0
  229. static const float FOV = 75; //vertical FoV
  230. MXAO.uvtoviewADD = float3(-tan(radians(FOV * 0.5)).xx,1.0) * qUINT::ASPECT_RATIO.yxx;
  231. MXAO.uvtoviewMUL = float3(-2.0 * MXAO.uvtoviewADD.xy,0.0);
  232. #endif
  233.  
  234. return MXAO;
  235. }
  236.  
  237. /*=============================================================================
  238. Functions
  239. =============================================================================*/
  240.  
  241. float3 get_position_from_uv(in float2 uv, in MXAO_VSOUT MXAO)
  242. {
  243. return (uv.xyx * MXAO.uvtoviewMUL + MXAO.uvtoviewADD) * qUINT::linear_depth(uv) * RESHADE_DEPTH_LINEARIZATION_FAR_PLANE;
  244. }
  245.  
  246. float3 get_position_from_uv_mipmapped(in float2 uv, in MXAO_VSOUT MXAO, in int miplevel)
  247. {
  248. return (uv.xyx * MXAO.uvtoviewMUL + MXAO.uvtoviewADD) * tex2Dlod(sMXAO_DepthTex, float4(uv.xyx, miplevel)).x;
  249. }
  250.  
  251. void spatial_blur_data(inout BlurData o, in sampler inputsampler, in float inputscale, in float4 uv)
  252. {
  253. o.key = tex2Dlod(inputsampler, uv * inputscale);
  254. o.mask = tex2Dlod(sMXAO_NormalTex, uv);
  255. o.mask.xyz = o.mask.xyz * 2 - 1;
  256. }
  257.  
  258. float compute_spatial_tap_weight(in BlurData center, in BlurData tap)
  259. {
  260. float depth_term = saturate(1 - abs(tap.mask.w - center.mask.w));
  261. float normal_term = saturate(dot(tap.mask.xyz, center.mask.xyz) * 16 - 15);
  262. return depth_term * normal_term;
  263. }
  264.  
  265. float4 blur_filter(in MXAO_VSOUT MXAO, in sampler inputsampler, in float inputscale, in float radius, in int blursteps)
  266. {
  267. float4 blur_uv = float4(MXAO.uv.xy, 0, 0);
  268.  
  269. BlurData center, tap;
  270. spatial_blur_data(center, inputsampler, inputscale, blur_uv);
  271.  
  272. float4 blursum = center.key;
  273. float4 blursum_noweight = center.key;
  274. float blurweight = 1;
  275.  
  276. static const float2 offsets[8] =
  277. {
  278. float2(1.5,0.5),float2(-1.5,-0.5),float2(-0.5,1.5),float2(0.5,-1.5),
  279. float2(1.5,2.5),float2(-1.5,-2.5),float2(-2.5,1.5),float2(2.5,-1.5)
  280. };
  281.  
  282. float2 blur_offsetscale = qUINT::PIXEL_SIZE / inputscale * radius;
  283.  
  284. [unroll]
  285. for(int i = 0; i < blursteps; i++)
  286. {
  287. blur_uv.xy = MXAO.uv.xy + offsets[i] * blur_offsetscale;
  288. spatial_blur_data(tap, inputsampler, inputscale, blur_uv);
  289.  
  290. float tap_weight = compute_spatial_tap_weight(center, tap);
  291.  
  292. blurweight += tap_weight;
  293. blursum.BLUR_COMP_SWIZZLE += tap.key.BLUR_COMP_SWIZZLE * tap_weight;
  294. blursum_noweight.BLUR_COMP_SWIZZLE += tap.key.BLUR_COMP_SWIZZLE;
  295. }
  296.  
  297. blursum.BLUR_COMP_SWIZZLE /= blurweight;
  298. blursum_noweight.BLUR_COMP_SWIZZLE /= 1 + blursteps;
  299.  
  300. return lerp(blursum.BLUR_COMP_SWIZZLE, blursum_noweight.BLUR_COMP_SWIZZLE, blurweight < 2);
  301. }
  302.  
  303. void sample_parameter_setup(in MXAO_VSOUT MXAO, in float scaled_depth, in float layer_id, out float scaled_radius, out float falloff_factor)
  304. {
  305. scaled_radius = 0.25 * MXAO_SAMPLE_RADIUS / (MXAO.samples * (scaled_depth + 2.0));
  306. falloff_factor = -1.0/(MXAO_SAMPLE_RADIUS * MXAO_SAMPLE_RADIUS);
  307.  
  308. #if(MXAO_TWO_LAYER != 0)
  309. scaled_radius *= lerp(1.0, MXAO_SAMPLE_RADIUS_SECONDARY + 1e-6, layer_id);
  310. falloff_factor *= lerp(1.0, 1.0 / (MXAO_SAMPLE_RADIUS_SECONDARY * MXAO_SAMPLE_RADIUS_SECONDARY + 1e-6), layer_id);
  311. #endif
  312. }
  313.  
  314. void smooth_normals(inout float3 normal, in float3 position, in MXAO_VSOUT MXAO)
  315. {
  316. float2 scaled_radius = 0.018 / position.z * qUINT::ASPECT_RATIO;
  317. float3 neighbour_normal[4] = {normal, normal, normal, normal};
  318.  
  319. [unroll]
  320. for(int i = 0; i < 4; i++)
  321. {
  322. float2 direction;
  323. sincos(6.28318548 * 0.25 * i, direction.y, direction.x);
  324.  
  325. [unroll]
  326. for(int direction_step = 1; direction_step <= 5; direction_step++)
  327. {
  328. float search_radius = exp2(direction_step);
  329. float2 sample_uv = MXAO.uv.zw + direction * search_radius * scaled_radius;
  330.  
  331. float3 temp_normal = tex2Dlod(sMXAO_NormalTex, float4(sample_uv, 0, 0)).xyz * 2.0 - 1.0;
  332. float3 temp_position = get_position_from_uv_mipmapped(sample_uv, MXAO, 0);
  333.  
  334. float3 position_delta = temp_position - position;
  335. float distance_weight = saturate(1.0 - dot(position_delta, position_delta) * 20.0 / search_radius);
  336. float normal_angle = dot(normal, temp_normal);
  337. float angle_weight = smoothstep(0.3, 0.98, normal_angle) * smoothstep(1.0, 0.98, normal_angle); //only take normals into account that are NOT equal to the current normal.
  338.  
  339. float total_weight = saturate(3.0 * distance_weight * angle_weight / search_radius);
  340.  
  341. neighbour_normal[i] = lerp(neighbour_normal[i], temp_normal, total_weight);
  342. }
  343. }
  344.  
  345. normal = normalize(neighbour_normal[0] + neighbour_normal[1] + neighbour_normal[2] + neighbour_normal[3]);
  346. }
  347.  
  348. /*=============================================================================
  349. Pixel Shaders
  350. =============================================================================*/
  351.  
  352. void PS_InputBufferSetup(in MXAO_VSOUT MXAO, out float4 color : SV_Target0, out float4 depth : SV_Target1, out float4 normal : SV_Target2)
  353. {
  354. float3 single_pixel_offset = float3(qUINT::PIXEL_SIZE.xy, 0);
  355.  
  356. float3 position = get_position_from_uv(MXAO.uv.xy, MXAO);
  357. float3 position_delta_x1 = - position + get_position_from_uv(MXAO.uv.xy + single_pixel_offset.xz, MXAO);
  358. float3 position_delta_x2 = position - get_position_from_uv(MXAO.uv.xy - single_pixel_offset.xz, MXAO);
  359. float3 position_delta_y1 = - position + get_position_from_uv(MXAO.uv.xy + single_pixel_offset.zy, MXAO);
  360. float3 position_delta_y2 = position - get_position_from_uv(MXAO.uv.xy - single_pixel_offset.zy, MXAO);
  361.  
  362. position_delta_x1 = lerp(position_delta_x1, position_delta_x2, abs(position_delta_x1.z) > abs(position_delta_x2.z));
  363. position_delta_y1 = lerp(position_delta_y1, position_delta_y2, abs(position_delta_y1.z) > abs(position_delta_y2.z));
  364.  
  365. float deltaz = abs(position_delta_x1.z * position_delta_x1.z - position_delta_x2.z * position_delta_x2.z)
  366. + abs(position_delta_y1.z * position_delta_y1.z - position_delta_y2.z * position_delta_y2.z);
  367.  
  368. normal = float4(normalize(cross(position_delta_y1, position_delta_x1)) * 0.5 + 0.5, deltaz);
  369. color = tex2D(qUINT::sBackBufferTex, MXAO.uv.xy);
  370. depth = qUINT::linear_depth(MXAO.uv.xy) * RESHADE_DEPTH_LINEARIZATION_FAR_PLANE;
  371. }
  372.  
  373. void PS_StencilSetup(in MXAO_VSOUT MXAO, out float4 color : SV_Target0)
  374. {
  375. if( qUINT::linear_depth(MXAO.uv.zw) >= MXAO_FADE_DEPTH_END
  376. || 0.25 * 0.5 * MXAO_SAMPLE_RADIUS / (tex2D(sMXAO_DepthTex, MXAO.uv.zw).x + 2.0) * BUFFER_HEIGHT < 1.0
  377. || MXAO.uv.z > 1.0
  378. || MXAO.uv.w > 1.0
  379. ) discard;
  380.  
  381. color = 1.0;
  382. }
  383.  
  384. void PS_AmbientObscurance(in MXAO_VSOUT MXAO, out float4 color : SV_Target0)
  385. {
  386. float3 position = get_position_from_uv_mipmapped(MXAO.uv.zw, MXAO, 0);
  387. float3 normal = tex2D(sMXAO_NormalTex, MXAO.uv.zw).xyz * 2.0 - 1.0;
  388.  
  389. float sample_jitter = dot(floor(MXAO.vpos.xy % 4 + 0.1), float2(0.0625, 0.25)) + 0.0625;
  390.  
  391. float layer_id = (MXAO.vpos.x + MXAO.vpos.y) % 2.0;
  392.  
  393. #if(MXAO_SMOOTHNORMALS != 0)
  394. smooth_normals(normal, position, MXAO);
  395. #endif
  396. float linear_depth = position.z / RESHADE_DEPTH_LINEARIZATION_FAR_PLANE;
  397. position += normal * linear_depth;
  398.  
  399. if(MXAO_GLOBAL_SAMPLE_QUALITY_PRESET == 7) MXAO.samples = 2 + floor(0.05 * MXAO_SAMPLE_RADIUS / linear_depth);
  400.  
  401. float scaled_radius;
  402. float falloff_factor;
  403. sample_parameter_setup(MXAO, position.z, layer_id, scaled_radius, falloff_factor);
  404.  
  405. float2 sample_uv, sample_direction;
  406. sincos(2.3999632 * 16 * sample_jitter, sample_direction.x, sample_direction.y); //2.3999632 * 16
  407. sample_direction *= scaled_radius;
  408.  
  409. color = 0.0;
  410.  
  411. [loop]
  412. for(int i = 0; i < MXAO.samples; i++)
  413. {
  414. sample_uv = MXAO.uv.zw + sample_direction.xy * qUINT::ASPECT_RATIO * (i + sample_jitter);
  415. sample_direction.xy = mul(sample_direction.xy, float2x2(0.76465, -0.64444, 0.64444, 0.76465)); //cos/sin 2.3999632 * 16
  416.  
  417. float sample_mip = saturate(scaled_radius * i * 20.0) * 3.0;
  418.  
  419. float3 occlusion_vector = -position + get_position_from_uv_mipmapped(sample_uv, MXAO, sample_mip + MXAO_MIPLEVEL_AO);
  420. float occlusion_distance_squared = dot(occlusion_vector, occlusion_vector);
  421. float occlusion_normal_angle = dot(occlusion_vector, normal) * rsqrt(occlusion_distance_squared);
  422.  
  423. float sample_occlusion = saturate(1.0 + falloff_factor * occlusion_distance_squared) * saturate(occlusion_normal_angle - MXAO_SAMPLE_NORMAL_BIAS);
  424. #if(MXAO_ENABLE_IL != 0)
  425. [branch]
  426. if(sample_occlusion > 0.1)
  427. {
  428. float3 sample_indirect_lighting = tex2Dlod(sMXAO_ColorTex, float4(sample_uv, 0, sample_mip + MXAO_MIPLEVEL_IL)).xyz;
  429. float3 sample_normal = tex2Dlod(sMXAO_NormalTex, float4(sample_uv, 0, sample_mip + MXAO_MIPLEVEL_IL)).xyz * 2.0 - 1.0;
  430. sample_indirect_lighting *= saturate(dot(-sample_normal, occlusion_vector) * rsqrt(occlusion_distance_squared) * 4.0) * saturate(1.0 + falloff_factor * occlusion_distance_squared * 0.25);
  431. color += float4(sample_indirect_lighting, sample_occlusion);
  432. }
  433. #else
  434. color.w += sample_occlusion;
  435. #endif
  436. }
  437.  
  438. color = saturate(color / ((1.0 - MXAO_SAMPLE_NORMAL_BIAS) * MXAO.samples) * 2.0);
  439. color = color.BLUR_COMP_SWIZZLE;
  440.  
  441. #if(MXAO_TWO_LAYER != 0)
  442. color *= lerp(MXAO_AMOUNT_COARSE, MXAO_AMOUNT_FINE, layer_id);
  443. #endif
  444. }
  445.  
  446. void PS_AmbientObscuranceHQ(in MXAO_VSOUT MXAO, out float4 color : SV_Target0)
  447. {
  448. float3 position = get_position_from_uv_mipmapped(MXAO.uv.zw, MXAO, 0);
  449. float3 normal = tex2D(sMXAO_NormalTex, MXAO.uv.zw).xyz * 2.0 - 1.0;
  450.  
  451. #if(MXAO_SMOOTHNORMALS != 0)
  452. smooth_normals(normal, position, MXAO);
  453. #endif
  454.  
  455. float3 viewdir = normalize(-position);
  456.  
  457. int directions = 2 + floor(MXAO.samples / 32) * 2;
  458. int stepshalf = MXAO.samples / (directions * 2);
  459.  
  460. float angle_correct = 1 - viewdir.z * viewdir.z;
  461. float scaled_radius = MXAO_SAMPLE_RADIUS / position.z / stepshalf * RESHADE_DEPTH_LINEARIZATION_FAR_PLANE;
  462. float falloff_factor = 0.25 * rcp(MXAO_SAMPLE_RADIUS * MXAO_SAMPLE_RADIUS);
  463.  
  464. float sample_jitter = dot(floor(MXAO.vpos.xy % 4 + 0.1), float2(0.0625, 0.25)) + 0.0625;
  465.  
  466. float dir_phi = 3.14159265 / directions;
  467. float2 sample_direction; sincos(dir_phi * sample_jitter * 6, sample_direction.y, sample_direction.x);
  468. float2x2 rot_dir = float2x2(cos(dir_phi),-sin(dir_phi),
  469. sin(dir_phi),cos(dir_phi));
  470.  
  471. color = 0;
  472.  
  473. [loop]
  474. for(float i = 0; i < directions; i++)
  475. {
  476. sample_direction = mul(sample_direction, rot_dir);
  477. float2 start = sample_direction * sample_jitter;
  478.  
  479. float3 sliceDir = float3(sample_direction, 0);
  480. float2 h = -1.0;
  481.  
  482. [loop]
  483. for(int j = 0; j < stepshalf; j++)
  484. {
  485. float4 sample_uv = MXAO.uv.zwzw + scaled_radius * qUINT::PIXEL_SIZE.xyxy * start.xyxy * float4(1,1,-1,-1);
  486. float sample_mip = saturate(scaled_radius * j * 0.01) * 3.0;
  487.  
  488. float3 occlusion_vector[2];
  489. occlusion_vector[0] = -position + get_position_from_uv_mipmapped(sample_uv.xy, MXAO, sample_mip + MXAO_MIPLEVEL_AO);
  490. occlusion_vector[1] = -position + get_position_from_uv_mipmapped(sample_uv.zw, MXAO, sample_mip + MXAO_MIPLEVEL_AO);
  491.  
  492. float2 occlusion_distance_squared = float2(dot(occlusion_vector[0], occlusion_vector[0]),
  493. dot(occlusion_vector[1], occlusion_vector[1]));
  494.  
  495. float2 inv_distance = rsqrt(occlusion_distance_squared);
  496.  
  497. float2 sample_h = float2(dot(occlusion_vector[0], viewdir),
  498. dot(occlusion_vector[1], viewdir)) * inv_distance;
  499.  
  500. sample_h = lerp(sample_h, h, saturate( occlusion_distance_squared * falloff_factor));
  501.  
  502. h.xy = (sample_h > h) ? sample_h : lerp(sample_h, h, 0.75);
  503. start += sample_direction;
  504. }
  505.  
  506. float3 normal_slice_plane = normalize(cross(sliceDir, viewdir));
  507. float3 tangent = cross(viewdir, normal_slice_plane);
  508. float3 proj_normal = normal - normal_slice_plane * dot(normal, normal_slice_plane);
  509.  
  510. float proj_length = length(proj_normal);
  511. float cos_gamma = clamp(dot(proj_normal, viewdir) * rcp(proj_length), -1.0, 1.0);
  512. float gamma = -sign(dot(proj_normal, tangent)) * acos(cos_gamma);
  513.  
  514. h = acos(min(h, 1));
  515.  
  516. h.x = gamma + max(-h.x - gamma, -1.5707963);
  517. h.y = gamma + min( h.y - gamma, 1.5707963);
  518.  
  519. h *= 2;
  520.  
  521. float2 sample_occlusion = cos_gamma + h * sin(gamma) - cos(h - gamma);
  522. color.w += proj_length * dot(sample_occlusion, 0.25);
  523. }
  524.  
  525. color /= directions;
  526. color.w = 1 - color.w;
  527. color = color.BLUR_COMP_SWIZZLE;
  528. }
  529.  
  530. void PS_SpatialFilter1(in MXAO_VSOUT MXAO, out float4 color : SV_Target0)
  531. {
  532. color = blur_filter(MXAO, qUINT::sCommonTex0, MXAO_GLOBAL_RENDER_SCALE, 0.75, 4);
  533. }
  534.  
  535. void PS_SpatialFilter2(MXAO_VSOUT MXAO, out float4 color : SV_Target0)
  536. {
  537. color = blur_filter(MXAO, qUINT::sCommonTex1, 1, 1.0 / MXAO_GLOBAL_RENDER_SCALE, 8);
  538. }
  539.  
  540. void PS_ResizeDepth(in MXAO_VSOUT MXAO, out float4 color : SV_Target0)
  541. {
  542. color = tex2D(sResized, MXAO.uv.xy);
  543. }
  544.  
  545. void PS_OutputPass(MXAO_VSOUT MXAO, out float4 color : SV_Target0)
  546. {
  547. float4 ssil_ssao = tex2D(sResized2, MXAO.uv.xy);
  548.  
  549. color = tex2D(sMXAO_ColorTex, MXAO.uv.xy);
  550.  
  551. static const float3 lumcoeff = float3(0.2126, 0.7152, 0.0722);
  552. float scenedepth = qUINT::linear_depth(MXAO.uv.xy);
  553. float colorgray = dot(color.rgb, lumcoeff);
  554. float blendfact = 1.0 - colorgray;
  555.  
  556. #if(MXAO_ENABLE_IL != 0)
  557. ssil_ssao.xyz = lerp(dot(ssil_ssao.xyz, lumcoeff), ssil_ssao.xyz, MXAO_SSIL_SATURATION) * MXAO_SSIL_AMOUNT * 2.0;
  558. #else
  559. ssil_ssao.xyz = 0.0;
  560. #endif
  561.  
  562. ssil_ssao = saturate(ssil_ssao); //compiler..
  563. #if(MXAO_HQ == 0)
  564. ssil_ssao.w = 1.0 - pow(1.0 - ssil_ssao.w, MXAO_SSAO_AMOUNT * 2.0);
  565. #else
  566. ssil_ssao.w = 1.0 - pow(1.0 - ssil_ssao.w, MXAO_SSAO_AMOUNT);
  567. #endif
  568. ssil_ssao *= 1.0 - smoothstep(MXAO_FADE_DEPTH_START, MXAO_FADE_DEPTH_END, scenedepth * float4(2.0, 2.0, 2.0, 1.0));
  569.  
  570. if(MXAO_BLEND_TYPE == 0)
  571. {
  572. color.rgb -= (ssil_ssao.www - ssil_ssao.xyz) * blendfact * color.rgb;
  573. }
  574. else if(MXAO_BLEND_TYPE == 1)
  575. {
  576. color.rgb = color.rgb * saturate(1.0 - ssil_ssao.www * blendfact * 1.2) + ssil_ssao.xyz * blendfact * colorgray * 2.0;
  577. }
  578. else if(MXAO_BLEND_TYPE == 2)
  579. {
  580. float colordiff = saturate(2.0 * distance(normalize(color.rgb + 1e-6),normalize(ssil_ssao.rgb + 1e-6)));
  581. color.rgb = color.rgb + ssil_ssao.rgb * lerp(color.rgb, dot(color.rgb, 0.3333), colordiff) * blendfact * blendfact * 4.0;
  582. color.rgb = color.rgb * (1.0 - ssil_ssao.www * (1.0 - dot(color.rgb, lumcoeff)));
  583. }
  584. else if(MXAO_BLEND_TYPE == 3)
  585. {
  586. color.rgb *= color.rgb;
  587. color.rgb -= (ssil_ssao.www - ssil_ssao.xyz) * color.rgb;
  588. color.rgb = sqrt(color.rgb);
  589. }
  590.  
  591. if(MXAO_DEBUG_VIEW_ENABLE == 1)
  592. {
  593. color.rgb = max(0.0, 1.0 - ssil_ssao.www + ssil_ssao.xyz);
  594. color.rgb *= (MXAO_ENABLE_IL != 0) ? 0.5 : 1.0;
  595. }
  596. else if(MXAO_DEBUG_VIEW_ENABLE == 2)
  597. {
  598. color.rgb = tex2D(sMXAO_NormalTex, MXAO.uv.xy).xyz;
  599. color.b = 1-color.b; //looks nicer
  600. }
  601.  
  602. color.a = 1.0;
  603. }
  604.  
  605. /*=============================================================================
  606. Techniques
  607. =============================================================================*/
  608.  
  609. technique MXAO
  610. < ui_tooltip = " >> qUINT::MXAO <<\n\n"
  611. "MXAO is a screen-space ambient occlusion shader.\n"
  612. "It adds diffuse shading to object corners to give more depth\n"
  613. "and detail to the scene. Check out the preprocessor options to\n"
  614. "get access to more functionality.\n"
  615. "\nMake sure to move MXAO to the very top of your shader list for\n"
  616. "maximum compatibility with other shaders.\n"
  617. "\nMXAO is written by Marty McFly / Pascal Gilcher"; >
  618. {
  619. pass
  620. {
  621. VertexShader = VS_MXAO;
  622. PixelShader = PS_InputBufferSetup;
  623. RenderTarget0 = MXAO_ColorTex;
  624. RenderTarget1 = MXAO_DepthTex;
  625. RenderTarget2 = MXAO_NormalTex;
  626. }
  627. pass
  628. {
  629. VertexShader = VS_MXAO;
  630. PixelShader = PS_StencilSetup;
  631. /*Render Target is Backbuffer*/
  632. ClearRenderTargets = true;
  633. StencilEnable = true;
  634. StencilPass = REPLACE;
  635. StencilRef = 1;
  636. }
  637. #if(MXAO_HQ != 0)
  638. pass
  639. {
  640. VertexShader = VS_MXAO;
  641. PixelShader = PS_AmbientObscuranceHQ;
  642. RenderTarget = qUINT::CommonTex0;
  643. ClearRenderTargets = true;
  644. StencilEnable = true;
  645. StencilPass = KEEP;
  646. StencilFunc = EQUAL;
  647. StencilRef = 1;
  648. }
  649. #else
  650. pass
  651. {
  652. VertexShader = VS_MXAO;
  653. PixelShader = PS_AmbientObscurance;
  654. RenderTarget = qUINT::CommonTex0;
  655. ClearRenderTargets = true;
  656. StencilEnable = true;
  657. StencilPass = KEEP;
  658. StencilFunc = EQUAL;
  659. StencilRef = 1;
  660. }
  661. #endif
  662. pass
  663. {
  664. VertexShader = VS_MXAO;
  665. PixelShader = PS_SpatialFilter1;
  666. RenderTarget = qUINT::CommonTex1;
  667. }
  668. pass
  669. {
  670. VertexShader = VS_MXAO;
  671. PixelShader = PS_SpatialFilter2;
  672. RenderTarget = texResized;
  673. }
  674. pass
  675. {
  676. VertexShader = PostProcessVS;
  677. PixelShader = PS_ResizeDepth;
  678. RenderTarget = texResized2;
  679. }
  680. pass
  681. {
  682. VertexShader = PostProcessVS;
  683. PixelShader = PS_OutputPass;
  684. }
  685. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement