SHARE
TWEET

Reshade_Modified_quInt_mxao

a guest Jul 21st, 2019 86 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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 = 20.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.  
  180. sampler2D sMXAO_ColorTex    { Texture = MXAO_ColorTex;  };
  181. sampler2D sMXAO_DepthTex    { Texture = MXAO_DepthTex;  };
  182. sampler2D sMXAO_NormalTex   { Texture = MXAO_NormalTex; };
  183.  
  184. #if(MXAO_ENABLE_IL != 0)
  185.  #define BLUR_COMP_SWIZZLE xyzw
  186. #else
  187.  #define BLUR_COMP_SWIZZLE w
  188. #endif
  189.  
  190. /*=============================================================================
  191.     Vertex Shader
  192. =============================================================================*/
  193.  
  194. struct MXAO_VSOUT
  195. {
  196.     float4                  vpos        : SV_Position;
  197.     float4                  uv          : TEXCOORD0;
  198.     nointerpolation float   samples     : TEXCOORD1;
  199.     nointerpolation float3  uvtoviewADD : TEXCOORD4;
  200.     nointerpolation float3  uvtoviewMUL : TEXCOORD5;
  201. };
  202.  
  203. struct BlurData
  204. {
  205.     float4 key;
  206.     float4 mask;
  207. };
  208.  
  209. MXAO_VSOUT VS_MXAO(in uint id : SV_VertexID)
  210. {
  211.     MXAO_VSOUT MXAO;
  212.  
  213.     MXAO.uv.x = (id == 2) ? 2.0 : 0.0;
  214.     MXAO.uv.y = (id == 1) ? 2.0 : 0.0;
  215.     MXAO.uv.zw = MXAO.uv.xy / MXAO_GLOBAL_RENDER_SCALE;
  216.     MXAO.vpos = float4(MXAO.uv.xy * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
  217.  
  218.     static const int samples_per_preset[8] = {4, 8, 16, 24, 32, 64, 255, 8 /*overridden*/};
  219.     MXAO.samples   = samples_per_preset[MXAO_GLOBAL_SAMPLE_QUALITY_PRESET];
  220.    
  221.     MXAO.uvtoviewADD = float3(-1.0,-1.0,1.0);
  222.     MXAO.uvtoviewMUL = float3(2.0,2.0,0.0);
  223.  
  224. #if 0
  225.     static const float FOV = 75; //vertical FoV
  226.     MXAO.uvtoviewADD = float3(-tan(radians(FOV * 0.5)).xx,1.0) * qUINT::ASPECT_RATIO.yxx;
  227.     MXAO.uvtoviewMUL = float3(-2.0 * MXAO.uvtoviewADD.xy,0.0);
  228. #endif
  229.  
  230.     return MXAO;
  231. }
  232.  
  233. /*=============================================================================
  234.     Functions
  235. =============================================================================*/
  236.  
  237. float3 get_position_from_uv(in float2 uv, in MXAO_VSOUT MXAO)
  238. {
  239.     return (uv.xyx * MXAO.uvtoviewMUL + MXAO.uvtoviewADD) * qUINT::linear_depth_resized(uv) * RESHADE_DEPTH_LINEARIZATION_FAR_PLANE;
  240. }
  241.  
  242. float3 get_position_from_uv_mipmapped(in float2 uv, in MXAO_VSOUT MXAO, in int miplevel)
  243. {
  244.     return (uv.xyx * MXAO.uvtoviewMUL + MXAO.uvtoviewADD) * tex2Dlod(sMXAO_DepthTex, float4(uv.xyx, miplevel)).x;
  245. }
  246.  
  247. void spatial_blur_data(inout BlurData o, in sampler inputsampler, in float inputscale, in float4 uv)
  248. {
  249.     o.key = tex2Dlod(inputsampler, uv * inputscale);
  250.     o.mask = tex2Dlod(sMXAO_NormalTex, uv);
  251.     o.mask.xyz = o.mask.xyz * 2 - 1;
  252. }
  253.  
  254. float compute_spatial_tap_weight(in BlurData center, in BlurData tap)
  255. {
  256.     float depth_term = saturate(1 - abs(tap.mask.w - center.mask.w));
  257.     float normal_term = saturate(dot(tap.mask.xyz, center.mask.xyz) * 16 - 15);
  258.     return depth_term * normal_term;
  259. }
  260.  
  261. float4 blur_filter(in MXAO_VSOUT MXAO, in sampler inputsampler, in float inputscale, in float radius, in int blursteps)
  262. {
  263.     float4 blur_uv = float4(MXAO.uv.xy, 0, 0);
  264.  
  265.     BlurData center, tap;
  266.     spatial_blur_data(center, inputsampler, inputscale, blur_uv);
  267.  
  268.     float4 blursum          = center.key;
  269.     float4 blursum_noweight = center.key;
  270.     float blurweight = 1;
  271.  
  272.     static const float2 offsets[8] =
  273.     {
  274.         float2(1.5,0.5),float2(-1.5,-0.5),float2(-0.5,1.5),float2(0.5,-1.5),
  275.         float2(1.5,2.5),float2(-1.5,-2.5),float2(-2.5,1.5),float2(2.5,-1.5)
  276.     };
  277.  
  278.     float2 blur_offsetscale = qUINT::PIXEL_SIZE / inputscale * radius;
  279.  
  280.     [unroll]
  281.     for(int i = 0; i < blursteps; i++)
  282.     {
  283.         blur_uv.xy = MXAO.uv.xy + offsets[i] * blur_offsetscale;
  284.         spatial_blur_data(tap, inputsampler, inputscale, blur_uv);
  285.  
  286.         float tap_weight = compute_spatial_tap_weight(center, tap);
  287.  
  288.         blurweight += tap_weight;
  289.         blursum.BLUR_COMP_SWIZZLE += tap.key.BLUR_COMP_SWIZZLE * tap_weight;
  290.         blursum_noweight.BLUR_COMP_SWIZZLE += tap.key.BLUR_COMP_SWIZZLE;
  291.     }
  292.  
  293.     blursum.BLUR_COMP_SWIZZLE /= blurweight;
  294.     blursum_noweight.BLUR_COMP_SWIZZLE /= 1 + blursteps;
  295.  
  296.     return lerp(blursum.BLUR_COMP_SWIZZLE, blursum_noweight.BLUR_COMP_SWIZZLE, blurweight < 2);
  297. }
  298.  
  299. void sample_parameter_setup(in MXAO_VSOUT MXAO, in float scaled_depth, in float layer_id, out float scaled_radius, out float falloff_factor)
  300. {
  301.     scaled_radius  = 0.25 * MXAO_SAMPLE_RADIUS / (MXAO.samples * (scaled_depth + 2.0));
  302.     falloff_factor = -1.0/(MXAO_SAMPLE_RADIUS * MXAO_SAMPLE_RADIUS);
  303.  
  304.     #if(MXAO_TWO_LAYER != 0)
  305.         scaled_radius  *= lerp(1.0, MXAO_SAMPLE_RADIUS_SECONDARY + 1e-6, layer_id);
  306.         falloff_factor *= lerp(1.0, 1.0 / (MXAO_SAMPLE_RADIUS_SECONDARY * MXAO_SAMPLE_RADIUS_SECONDARY + 1e-6), layer_id);
  307.     #endif
  308. }
  309.  
  310. void smooth_normals(inout float3 normal, in float3 position, in MXAO_VSOUT MXAO)
  311. {
  312.     float2 scaled_radius = 0.018 / position.z * qUINT::ASPECT_RATIO;
  313.     float3 neighbour_normal[4] = {normal, normal, normal, normal};
  314.  
  315.     [unroll]
  316.     for(int i = 0; i < 4; i++)
  317.     {
  318.         float2 direction;
  319.         sincos(6.28318548 * 0.25 * i, direction.y, direction.x);
  320.  
  321.         [unroll]
  322.         for(int direction_step = 1; direction_step <= 5; direction_step++)
  323.         {
  324.             float search_radius = exp2(direction_step);
  325.             float2 sample_uv = MXAO.uv.zw + direction * search_radius * scaled_radius;
  326.  
  327.             float3 temp_normal = tex2Dlod(sMXAO_NormalTex, float4(sample_uv, 0, 0)).xyz * 2.0 - 1.0;
  328.             float3 temp_position = get_position_from_uv_mipmapped(sample_uv, MXAO, 0);
  329.  
  330.             float3 position_delta = temp_position - position;
  331.             float distance_weight = saturate(1.0 - dot(position_delta, position_delta) * 20.0 / search_radius);
  332.             float normal_angle = dot(normal, temp_normal);
  333.             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.
  334.  
  335.             float total_weight = saturate(3.0 * distance_weight * angle_weight / search_radius);
  336.  
  337.             neighbour_normal[i] = lerp(neighbour_normal[i], temp_normal, total_weight);
  338.         }
  339.     }
  340.  
  341.     normal = normalize(neighbour_normal[0] + neighbour_normal[1] + neighbour_normal[2] + neighbour_normal[3]);
  342. }
  343.  
  344. /*=============================================================================
  345.     Pixel Shaders
  346. =============================================================================*/
  347.  
  348. void PS_ResizeDepth(in MXAO_VSOUT MXAO, out float4 color : SV_Target0)
  349. {
  350.     color = tex2D(qUINT::sDepthBufferTex, MXAO.uv.xy).x;
  351. }
  352.  
  353. void PS_InputBufferSetup(in MXAO_VSOUT MXAO, out float4 color : SV_Target0, out float4 depth : SV_Target1, out float4 normal : SV_Target2)
  354. {
  355.     float3 single_pixel_offset = float3(qUINT::PIXEL_SIZE.xy, 0);
  356.  
  357.     float3 position          =              get_position_from_uv(MXAO.uv.xy, MXAO);
  358.     float3 position_delta_x1 = - position + get_position_from_uv(MXAO.uv.xy + single_pixel_offset.xz, MXAO);
  359.     float3 position_delta_x2 =   position - get_position_from_uv(MXAO.uv.xy - single_pixel_offset.xz, MXAO);
  360.     float3 position_delta_y1 = - position + get_position_from_uv(MXAO.uv.xy + single_pixel_offset.zy, MXAO);
  361.     float3 position_delta_y2 =   position - get_position_from_uv(MXAO.uv.xy - single_pixel_offset.zy, MXAO);
  362.  
  363.     position_delta_x1 = lerp(position_delta_x1, position_delta_x2, abs(position_delta_x1.z) > abs(position_delta_x2.z));
  364.     position_delta_y1 = lerp(position_delta_y1, position_delta_y2, abs(position_delta_y1.z) > abs(position_delta_y2.z));
  365.  
  366.     float deltaz = abs(position_delta_x1.z * position_delta_x1.z - position_delta_x2.z * position_delta_x2.z)
  367.                  + abs(position_delta_y1.z * position_delta_y1.z - position_delta_y2.z * position_delta_y2.z);
  368.  
  369.     normal  = float4(normalize(cross(position_delta_y1, position_delta_x1)) * 0.5 + 0.5, deltaz);
  370.     color   = tex2D(qUINT::sBackBufferTex, MXAO.uv.xy);
  371.     depth   = qUINT::linear_depth_resized(MXAO.uv.xy) * RESHADE_DEPTH_LINEARIZATION_FAR_PLANE;  
  372. }
  373.  
  374. void PS_StencilSetup(in MXAO_VSOUT MXAO, out float4 color : SV_Target0)
  375. {        
  376.     if(    qUINT::linear_depth_resized(MXAO.uv.zw) >= MXAO_FADE_DEPTH_END
  377.         || 0.25 * 0.5 * MXAO_SAMPLE_RADIUS / (tex2D(sMXAO_DepthTex, MXAO.uv.zw).x + 2.0) * BUFFER_HEIGHT < 1.0
  378.         || MXAO.uv.z > 1.0
  379.         || MXAO.uv.w > 1.0
  380.         ) discard;
  381.  
  382.     color = 1.0;
  383. }
  384.  
  385. void PS_AmbientObscurance(in MXAO_VSOUT MXAO, out float4 color : SV_Target0)
  386. {
  387.     float3 position = get_position_from_uv_mipmapped(MXAO.uv.zw, MXAO, 0);
  388.     float3 normal = tex2D(sMXAO_NormalTex, MXAO.uv.zw).xyz * 2.0 - 1.0;
  389.  
  390.     float sample_jitter = dot(floor(MXAO.vpos.xy % 4 + 0.1), float2(0.0625, 0.25)) + 0.0625;
  391.  
  392.     float  layer_id = (MXAO.vpos.x + MXAO.vpos.y) % 2.0;
  393.  
  394. #if(MXAO_SMOOTHNORMALS != 0)
  395.     smooth_normals(normal, position, MXAO);
  396. #endif
  397.     float linear_depth_resized = position.z / RESHADE_DEPTH_LINEARIZATION_FAR_PLANE;        
  398.     position += normal * linear_depth_resized;
  399.  
  400.     if(MXAO_GLOBAL_SAMPLE_QUALITY_PRESET == 7) MXAO.samples = 2 + floor(0.05 * MXAO_SAMPLE_RADIUS / linear_depth_resized);
  401.  
  402.     float scaled_radius;
  403.     float falloff_factor;
  404.     sample_parameter_setup(MXAO, position.z, layer_id, scaled_radius, falloff_factor);
  405.  
  406.     float2 sample_uv, sample_direction;
  407.     sincos(2.3999632 * 16 * sample_jitter, sample_direction.x, sample_direction.y); //2.3999632 * 16
  408.     sample_direction *= scaled_radius;  
  409.  
  410.     color = 0.0;
  411.  
  412.     [loop]
  413.     for(int i = 0; i < MXAO.samples; i++)
  414.     {                    
  415.         sample_uv = MXAO.uv.zw + sample_direction.xy * qUINT::ASPECT_RATIO * (i + sample_jitter);  
  416.         sample_direction.xy = mul(sample_direction.xy, float2x2(0.76465, -0.64444, 0.64444, 0.76465)); //cos/sin 2.3999632 * 16            
  417.  
  418.         float sample_mip = saturate(scaled_radius * i * 20.0) * 3.0;
  419.            
  420.         float3 occlusion_vector = -position + get_position_from_uv_mipmapped(sample_uv, MXAO, sample_mip + MXAO_MIPLEVEL_AO);                
  421.         float  occlusion_distance_squared = dot(occlusion_vector, occlusion_vector);
  422.         float  occlusion_normal_angle = dot(occlusion_vector, normal) * rsqrt(occlusion_distance_squared);
  423.  
  424.         float sample_occlusion = saturate(1.0 + falloff_factor * occlusion_distance_squared) * saturate(occlusion_normal_angle - MXAO_SAMPLE_NORMAL_BIAS);
  425. #if(MXAO_ENABLE_IL != 0)
  426.         [branch]
  427.         if(sample_occlusion > 0.1)
  428.         {
  429.                 float3 sample_indirect_lighting = tex2Dlod(sMXAO_ColorTex, float4(sample_uv, 0, sample_mip + MXAO_MIPLEVEL_IL)).xyz;
  430.                 float3 sample_normal = tex2Dlod(sMXAO_NormalTex, float4(sample_uv, 0, sample_mip + MXAO_MIPLEVEL_IL)).xyz * 2.0 - 1.0;
  431.                 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);
  432.                 color += float4(sample_indirect_lighting, sample_occlusion);
  433.         }
  434. #else
  435.         color.w += sample_occlusion;
  436. #endif
  437.     }
  438.  
  439.     color = saturate(color / ((1.0 - MXAO_SAMPLE_NORMAL_BIAS) * MXAO.samples) * 2.0);
  440.     color = color.BLUR_COMP_SWIZZLE;
  441.  
  442. #if(MXAO_TWO_LAYER != 0)
  443.     color *= lerp(MXAO_AMOUNT_COARSE, MXAO_AMOUNT_FINE, layer_id);
  444. #endif
  445. }
  446.  
  447. void PS_AmbientObscuranceHQ(in MXAO_VSOUT MXAO, out float4 color : SV_Target0)
  448. {
  449.     float3 position = get_position_from_uv_mipmapped(MXAO.uv.zw, MXAO, 0);
  450.     float3 normal   = tex2D(sMXAO_NormalTex, MXAO.uv.zw).xyz * 2.0 - 1.0;  
  451.  
  452. #if(MXAO_SMOOTHNORMALS != 0)
  453.     smooth_normals(normal, position, MXAO);
  454. #endif
  455.  
  456.     float3 viewdir  = normalize(-position);
  457.  
  458.     int directions = 2 + floor(MXAO.samples / 32) * 2;
  459.     int stepshalf = MXAO.samples / (directions * 2);
  460.    
  461.     float angle_correct = 1 - viewdir.z * viewdir.z;
  462.     float scaled_radius = MXAO_SAMPLE_RADIUS / position.z / stepshalf * RESHADE_DEPTH_LINEARIZATION_FAR_PLANE;
  463.     float falloff_factor = 0.25 * rcp(MXAO_SAMPLE_RADIUS * MXAO_SAMPLE_RADIUS);
  464.  
  465.     float sample_jitter = dot(floor(MXAO.vpos.xy % 4 + 0.1), float2(0.0625, 0.25)) + 0.0625;
  466.  
  467.     float dir_phi = 3.14159265 / directions;
  468.     float2 sample_direction; sincos(dir_phi * sample_jitter * 6, sample_direction.y, sample_direction.x);
  469.     float2x2 rot_dir = float2x2(cos(dir_phi),-sin(dir_phi),
  470.                                 sin(dir_phi),cos(dir_phi));
  471.  
  472.     color = 0;
  473.  
  474.     [loop]
  475.     for(float i = 0; i < directions; i++)
  476.     {
  477.         sample_direction = mul(sample_direction, rot_dir);
  478.         float2 start = sample_direction * sample_jitter;
  479.  
  480.         float3 sliceDir = float3(sample_direction, 0);
  481.         float2 h = -1.0;
  482.  
  483.         [loop]
  484.         for(int j = 0; j < stepshalf; j++)
  485.         {
  486.             float4 sample_uv = MXAO.uv.zwzw + scaled_radius * qUINT::PIXEL_SIZE.xyxy * start.xyxy * float4(1,1,-1,-1);
  487.             float sample_mip = saturate(scaled_radius * j * 0.01) * 3.0;
  488.  
  489.             float3 occlusion_vector[2];
  490.             occlusion_vector[0] = -position + get_position_from_uv_mipmapped(sample_uv.xy, MXAO, sample_mip + MXAO_MIPLEVEL_AO);  
  491.             occlusion_vector[1] = -position + get_position_from_uv_mipmapped(sample_uv.zw, MXAO, sample_mip + MXAO_MIPLEVEL_AO);
  492.  
  493.             float2  occlusion_distance_squared = float2(dot(occlusion_vector[0], occlusion_vector[0]),
  494.                                                         dot(occlusion_vector[1], occlusion_vector[1]));
  495.  
  496.             float2 inv_distance = rsqrt(occlusion_distance_squared);
  497.  
  498.             float2 sample_h = float2(dot(occlusion_vector[0], viewdir),
  499.                                      dot(occlusion_vector[1], viewdir)) * inv_distance;
  500.            
  501.             sample_h = lerp(sample_h, h, saturate( occlusion_distance_squared * falloff_factor));
  502.  
  503.             h.xy = (sample_h > h) ? sample_h : lerp(sample_h, h, 0.75);        
  504.             start += sample_direction;
  505.         }
  506.  
  507.         float3 normal_slice_plane = normalize(cross(sliceDir, viewdir));
  508.         float3 tangent = cross(viewdir, normal_slice_plane);
  509.         float3 proj_normal = normal - normal_slice_plane * dot(normal, normal_slice_plane);
  510.  
  511.         float proj_length = length(proj_normal);
  512.         float cos_gamma = clamp(dot(proj_normal, viewdir) * rcp(proj_length), -1.0, 1.0);
  513.         float gamma = -sign(dot(proj_normal, tangent)) * acos(cos_gamma);
  514.  
  515.         h = acos(min(h, 1));
  516.  
  517.         h.x = gamma + max(-h.x - gamma, -1.5707963);
  518.         h.y = gamma + min( h.y - gamma,  1.5707963);
  519.  
  520.         h *= 2;    
  521.  
  522.         float2 sample_occlusion = cos_gamma + h * sin(gamma) - cos(h - gamma);
  523.         color.w += proj_length * dot(sample_occlusion, 0.25);
  524.     }
  525.  
  526.     color /= directions;
  527.     color.w = 1 - color.w;
  528.     color = color.BLUR_COMP_SWIZZLE;
  529. }
  530.  
  531. void PS_SpatialFilter1(in MXAO_VSOUT MXAO, out float4 color : SV_Target0)
  532. {
  533.     color = blur_filter(MXAO, qUINT::sCommonTex0, MXAO_GLOBAL_RENDER_SCALE, 0.75, 4);
  534. }
  535.  
  536. void PS_SpatialFilter2(MXAO_VSOUT MXAO, out float4 color : SV_Target0)
  537. {
  538.     float4 ssil_ssao = blur_filter(MXAO, qUINT::sCommonTex1, 1, 1.0 / MXAO_GLOBAL_RENDER_SCALE, 8);
  539.  
  540.     color = tex2D(sMXAO_ColorTex, MXAO.uv.xy);
  541.  
  542.     static const float3 lumcoeff = float3(0.2126, 0.7152, 0.0722);
  543.     float scenedepth = qUINT::linear_depth_resized(MXAO.uv.xy);        
  544.     float colorgray = dot(color.rgb, lumcoeff);
  545.     float blendfact = 1.0 - colorgray;
  546.  
  547. #if(MXAO_ENABLE_IL != 0)
  548.     ssil_ssao.xyz  = lerp(dot(ssil_ssao.xyz, lumcoeff), ssil_ssao.xyz, MXAO_SSIL_SATURATION) * MXAO_SSIL_AMOUNT * 2.0;
  549. #else
  550.     ssil_ssao.xyz = 0.0;
  551. #endif
  552.  
  553.     ssil_ssao = saturate(ssil_ssao); //compiler..
  554. #if(MXAO_HQ == 0)
  555.     ssil_ssao.w  = 1.0 - pow(1.0 - ssil_ssao.w, MXAO_SSAO_AMOUNT * 2.0);
  556. #else
  557.     ssil_ssao.w  = 1.0 - pow(1.0 - ssil_ssao.w, MXAO_SSAO_AMOUNT);
  558. #endif
  559.     ssil_ssao    *= 1.0 - smoothstep(MXAO_FADE_DEPTH_START, MXAO_FADE_DEPTH_END, scenedepth * float4(2.0, 2.0, 2.0, 1.0));
  560.  
  561.     if(MXAO_BLEND_TYPE == 0)
  562.     {
  563.         color.rgb -= (ssil_ssao.www - ssil_ssao.xyz) * blendfact * color.rgb;
  564.     }
  565.     else if(MXAO_BLEND_TYPE == 1)
  566.     {
  567.         color.rgb = color.rgb * saturate(1.0 - ssil_ssao.www * blendfact * 1.2) + ssil_ssao.xyz * blendfact * colorgray * 2.0;
  568.     }
  569.     else if(MXAO_BLEND_TYPE == 2)
  570.     {
  571.         float colordiff = saturate(2.0 * distance(normalize(color.rgb + 1e-6),normalize(ssil_ssao.rgb + 1e-6)));
  572.         color.rgb = color.rgb + ssil_ssao.rgb * lerp(color.rgb, dot(color.rgb, 0.3333), colordiff) * blendfact * blendfact * 4.0;
  573.         color.rgb = color.rgb * (1.0 - ssil_ssao.www * (1.0 - dot(color.rgb, lumcoeff)));
  574.     }
  575.     else if(MXAO_BLEND_TYPE == 3)
  576.     {
  577.         color.rgb *= color.rgb;
  578.         color.rgb -= (ssil_ssao.www - ssil_ssao.xyz) * color.rgb;
  579.         color.rgb = sqrt(color.rgb);
  580.     }
  581.  
  582.     if(MXAO_DEBUG_VIEW_ENABLE == 1)
  583.     {
  584.         color.rgb = max(0.0, 1.0 - ssil_ssao.www + ssil_ssao.xyz);
  585.         color.rgb *= (MXAO_ENABLE_IL != 0) ? 0.5 : 1.0;
  586.     }
  587.     else if(MXAO_DEBUG_VIEW_ENABLE == 2)
  588.     {      
  589.         color.rgb = tex2D(sMXAO_NormalTex, MXAO.uv.xy).xyz;
  590.         color.b = 1-color.b; //looks nicer
  591.     }
  592.        
  593.     color.a = 1.0;        
  594. }
  595.  
  596. /*=============================================================================
  597.     Techniques
  598. =============================================================================*/
  599.  
  600. technique MXAO
  601. < ui_tooltip = "                     >> qUINT::MXAO <<\n\n"
  602.                "MXAO is a screen-space ambient occlusion shader.\n"
  603.                "It adds diffuse shading to object corners to give more depth\n"
  604.                "and detail to the scene. Check out the preprocessor options to\n"
  605.                "get access to more functionality.\n"
  606.                "\nMake sure to move MXAO to the very top of your shader list for\n"
  607.                "maximum compatibility with other shaders.\n"
  608.                "\nMXAO is written by Marty McFly / Pascal Gilcher"; >
  609. {
  610.     pass
  611.     {
  612.         VertexShader = PostProcessVS;
  613.         PixelShader = PS_ResizeDepth;
  614.         RenderTarget = qUINT::DepthBufferTexResized;
  615.     }
  616.     pass
  617.     {
  618.         VertexShader = VS_MXAO;
  619.         PixelShader  = PS_InputBufferSetup;
  620.         RenderTarget0 = MXAO_ColorTex;
  621.         RenderTarget1 = MXAO_DepthTex;
  622.         RenderTarget2 = MXAO_NormalTex;
  623.     }
  624.     pass
  625.     {
  626.         VertexShader = VS_MXAO;
  627.         PixelShader  = PS_StencilSetup;
  628.         /*Render Target is Backbuffer*/
  629.         ClearRenderTargets = true;
  630.         StencilEnable = true;
  631.         StencilPass = REPLACE;
  632.         StencilRef = 1;
  633.     }
  634. #if(MXAO_HQ != 0)
  635.     pass
  636.     {
  637.         VertexShader = VS_MXAO;
  638.         PixelShader  = PS_AmbientObscuranceHQ;
  639.         RenderTarget = qUINT::CommonTex0;
  640.         ClearRenderTargets = true;
  641.         StencilEnable = true;
  642.         StencilPass = KEEP;
  643.         StencilFunc = EQUAL;
  644.         StencilRef = 1;
  645.     }
  646. #else
  647.     pass
  648.     {
  649.         VertexShader = VS_MXAO;
  650.         PixelShader  = PS_AmbientObscurance;
  651.         RenderTarget = qUINT::CommonTex0;
  652.         ClearRenderTargets = true;
  653.         StencilEnable = true;
  654.         StencilPass = KEEP;
  655.         StencilFunc = EQUAL;
  656.         StencilRef = 1;
  657.     }
  658. #endif
  659.     pass
  660.     {
  661.         VertexShader = VS_MXAO;
  662.         PixelShader  = PS_SpatialFilter1;
  663.         RenderTarget = qUINT::CommonTex1;
  664.     }
  665.     pass
  666.     {
  667.         VertexShader = VS_MXAO;
  668.         PixelShader  = PS_SpatialFilter2;
  669.         /*Render Target is Backbuffer*/
  670.     }
  671. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Not a member of Pastebin yet?
Sign Up, it unlocks many cool features!
 
Top