Advertisement
Guest User

Reshade_Modified_quInt_ssr

a guest
Jul 21st, 2019
366
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.96 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. Screen-Space Reflections
  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.  
  23. /*=============================================================================
  24. UI Uniforms
  25. =============================================================================*/
  26.  
  27. uniform float SSR_FIELD_OF_VIEW <
  28. ui_type = "drag";
  29. ui_min = 0.00; ui_max = 100.00;
  30. ui_label = "Vertical Field of View";
  31. ui_tooltip = "Vertical FoV, should match camera FoV but since ReShade's\ndepth linearization is not always precise, this value\nmight differ from the actual value. Just set to what looks best.";
  32. ui_category = "Global";
  33. > = 50.0;
  34.  
  35. uniform float SSR_REFLECTION_INTENSITY <
  36. ui_type = "drag";
  37. ui_min = 0.00; ui_max = 1.00;
  38. ui_label = "Reflection Intensity";
  39. ui_tooltip = "Amount of reflection.";
  40. ui_category = "Global";
  41. > = 1.0;
  42.  
  43. uniform float SSR_FRESNEL_EXP <
  44. ui_type = "drag";
  45. ui_min = 1.00; ui_max = 10.00;
  46. ui_label = "Reflection Exponent";
  47. ui_tooltip = "qUINT uses Schlick's fresnel approximation.\nThis parameter represents the power of the angle falloff.\nHigher values restrict reflections to very flat angles.\nOriginal Schlick value: 5.\nThe Fresnel Coefficient is set to 0 to match most surfaces.";
  48. ui_category = "Global";
  49. > = 5.0;
  50.  
  51. uniform float SSR_FADE_DIST <
  52. ui_type = "drag";
  53. ui_min = 0.001; ui_max = 1.00;
  54. ui_label = "Fade Distance";
  55. ui_tooltip = "Distance where reflection is completely faded out.\n1 means infinite distance.";
  56. ui_category = "Global";
  57. > = 0.8;
  58.  
  59. uniform float SSR_RAY_INC <
  60. ui_type = "drag";
  61. ui_min = 1.01; ui_max = 3.00;
  62. ui_label = "Ray Increment";
  63. ui_tooltip = "Rate of ray step size growth.\nA parameter of 1.0 means same sized steps,\n2.0 means the step size doubles each iteration.\nIncrease if not the entire scene is represented (e.g. sky missing) at the cost of precision.";
  64. ui_category = "Ray Tracing";
  65. > = 1.6;
  66.  
  67. uniform float SSR_ACCEPT_RANGE <
  68. ui_type = "drag";
  69. ui_min = 0.0; ui_max = 12.00;
  70. ui_label = "Acceptance Range";
  71. ui_tooltip = "Acceptable error for ray intersection. Larger values will cause more coherent but incorrect reflections.";
  72. ui_category = "Ray Tracing";
  73. > = 2.5;
  74.  
  75. uniform float SSR_JITTER_AMOUNT <
  76. ui_type = "drag";
  77. ui_min = 0.0; ui_max = 1.00;
  78. ui_label = "Ray Jitter Amount";
  79. ui_tooltip = "Changes ray step size randomly per pixel to produce\na more coherent reflection at the cost of noise that needs to be filtered away.";
  80. ui_category = "Ray Tracing";
  81. > = 0.25;
  82.  
  83. uniform float SSR_FILTER_SIZE <
  84. ui_type = "drag";
  85. ui_min = 0.0; ui_max = 5.00;
  86. ui_label = "Filter Kernel Size";
  87. ui_tooltip = "Size of spatial filter, higher values create more blurry reflections at the cost of detail.";
  88. ui_category = "Filtering and Details";
  89. > = 0.5;
  90.  
  91. uniform float SSR_RELIEF_AMOUNT <
  92. ui_type = "drag";
  93. ui_min = 0.0; ui_max = 1.00;
  94. ui_label = "Surface Relief Height";
  95. ui_tooltip = "Strength of embossed texture relief. Higher values cause more bumpy surfaces.";
  96. ui_category = "Filtering and Details";
  97. > = 0.05;
  98.  
  99. uniform float SSR_RELIEF_SCALE <
  100. ui_type = "drag";
  101. ui_min = 0.1; ui_max = 1.00;
  102. ui_label = "Surface Relief Scale";
  103. ui_tooltip = "Scale of embossed texture relief, lower values cause more high frequency relief.";
  104. ui_category = "Filtering and Details";
  105. > = 0.35;
  106.  
  107. /*=============================================================================
  108. Textures, Samplers, Globals
  109. =============================================================================*/
  110.  
  111. #include "qUINT_common.fxh"
  112.  
  113. texture2D SSR_ColorTex { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA8; AddressU = MIRROR;};
  114. sampler2D sSSR_ColorTex { Texture = SSR_ColorTex; };
  115.  
  116. /*=============================================================================
  117. Vertex Shader
  118. =============================================================================*/
  119.  
  120. struct SSR_VSOUT
  121. {
  122. float4 vpos : SV_Position;
  123. float2 uv : TEXCOORD0;
  124. float3 uvtoviewADD : TEXCOORD4;
  125. float3 uvtoviewMUL : TEXCOORD5;
  126. };
  127.  
  128. SSR_VSOUT VS_SSR(in uint id : SV_VertexID)
  129. {
  130. SSR_VSOUT o;
  131. o.uv.x = (id == 2) ? 2.0 : 0.0;
  132. o.uv.y = (id == 1) ? 2.0 : 0.0;
  133. o.vpos = float4(o.uv.xy * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
  134.  
  135. //o.uvtoviewADD = float3(-1.0,-1.0,1.0);
  136. //o.uvtoviewMUL = float3(2.0,2.0,0.0);
  137.  
  138. o.uvtoviewADD = float3(-tan(radians(SSR_FIELD_OF_VIEW * 0.5)).xx,1.0) * qUINT::ASPECT_RATIO.yxx;
  139. o.uvtoviewMUL = float3(-2.0 * o.uvtoviewADD.xy,0.0);
  140.  
  141. return o;
  142. }
  143.  
  144. /*=============================================================================
  145. Functions
  146. =============================================================================*/
  147.  
  148. float3 get_position_from_uv(in float2 uv, in SSR_VSOUT i)
  149. {
  150. return (uv.xyx * i.uvtoviewMUL + i.uvtoviewADD) * qUINT::linear_depth_resized(uv) * RESHADE_DEPTH_LINEARIZATION_FAR_PLANE;
  151. }
  152.  
  153. float2 get_uv_from_position(in float3 pos, in SSR_VSOUT i)
  154. {
  155. return pos.xy / (i.uvtoviewMUL.xy * pos.z) - i.uvtoviewADD.xy/i.uvtoviewMUL.xy;
  156. }
  157.  
  158. float4 get_normal_and_edges_from_depth(in SSR_VSOUT i)
  159. {
  160. float3 single_pixel_offset = float3(qUINT::PIXEL_SIZE, 0);
  161.  
  162. float3 position = get_position_from_uv(i.uv, i);
  163. float3 position_delta_x1 = - position + get_position_from_uv(i.uv + single_pixel_offset.xz, i);
  164. float3 position_delta_x2 = position - get_position_from_uv(i.uv - single_pixel_offset.xz, i);
  165. float3 position_delta_y1 = - position + get_position_from_uv(i.uv + single_pixel_offset.zy, i);
  166. float3 position_delta_y2 = position - get_position_from_uv(i.uv - single_pixel_offset.zy, i);
  167.  
  168. position_delta_x1 = lerp(position_delta_x1, position_delta_x2, abs(position_delta_x1.z) > abs(position_delta_x2.z));
  169. position_delta_y1 = lerp(position_delta_y1, position_delta_y2, abs(position_delta_y1.z) > abs(position_delta_y2.z));
  170.  
  171. float deltaz = abs(position_delta_x1.z * position_delta_x1.z - position_delta_x2.z * position_delta_x2.z)
  172. + abs(position_delta_y1.z * position_delta_y1.z - position_delta_y2.z * position_delta_y2.z);
  173.  
  174. return float4(normalize(cross(position_delta_y1, position_delta_x1)), deltaz);
  175. }
  176.  
  177. float3 get_normal_from_color(float2 uv, float2 offset, float scale, float sharpness)
  178. {
  179. float3 offset_swiz = float3(offset.xy, 0);
  180. float hpx = dot(tex2Dlod(qUINT::sBackBufferTex, float4(uv + offset_swiz.xz,0,0)).xyz, 0.333) * scale;
  181. float hmx = dot(tex2Dlod(qUINT::sBackBufferTex, float4(uv - offset_swiz.xz,0,0)).xyz, 0.333) * scale;
  182. float hpy = dot(tex2Dlod(qUINT::sBackBufferTex, float4(uv + offset_swiz.zy,0,0)).xyz, 0.333) * scale;
  183. float hmy = dot(tex2Dlod(qUINT::sBackBufferTex, float4(uv - offset_swiz.zy,0,0)).xyz, 0.333) * scale;
  184.  
  185. float dpx = qUINT::linear_depth_resized(uv + offset_swiz.xz);
  186. float dmx = qUINT::linear_depth_resized(uv - offset_swiz.xz);
  187. float dpy = qUINT::linear_depth_resized(uv + offset_swiz.zy);
  188. float dmy = qUINT::linear_depth_resized(uv - offset_swiz.zy);
  189.  
  190. float2 xymult = float2(abs(dmx - dpx), abs(dmy - dpy)) * sharpness;
  191. xymult = saturate(1.0 - xymult);
  192.  
  193. float3 normal;
  194. normal.xy = float2(hmx - hpx, hmy - hpy) * xymult / offset.xy * 0.5;
  195. normal.z = 1.0;
  196.  
  197. return normalize(normal);
  198. }
  199.  
  200. float3 blend_normals(float3 n1, float3 n2)
  201. {
  202. //return normalize(float3(n1.xy*n2.z + n2.xy*n1.z, n1.z*n2.z));
  203. n1 += float3( 0, 0, 1);
  204. n2 *= float3(-1, -1, 1);
  205. return n1*dot(n1, n2)/n1.z - n2;
  206. }
  207.  
  208. float bayer(float2 vpos, int max_level)
  209. {
  210. float finalBayer = 0.0;
  211. float finalDivisor = 0.0;
  212. float layerMult = 1.0;
  213.  
  214. for(float bayerLevel = max_level; bayerLevel >= 1.0; bayerLevel--)
  215. {
  216. layerMult *= 4.0;
  217.  
  218. float2 bayercoord = floor(vpos.xy * exp2(1 - bayerLevel)) % 2;
  219. float line0202 = bayercoord.x*2.0;
  220.  
  221. finalBayer += lerp(line0202, 3.0 - line0202, bayercoord.y) / 3.0 * layerMult;
  222. finalDivisor += layerMult;
  223. }
  224.  
  225. return finalBayer / finalDivisor;
  226. }
  227.  
  228. /*=============================================================================
  229. Pixel Shaders
  230. =============================================================================*/
  231.  
  232. struct Ray
  233. {
  234. float3 origin;
  235. float3 dir;
  236. float step;
  237. float3 pos;
  238. };
  239.  
  240. struct SceneData
  241. {
  242. float3 eyedir;
  243. float3 normal;
  244. float3 position;
  245. float depth;
  246. };
  247.  
  248. struct TraceData
  249. {
  250. int num_steps;
  251. int num_refines;
  252. float2 uv;
  253. float3 error;
  254. bool hit;
  255. };
  256.  
  257. struct BlurData
  258. {
  259. float4 key;
  260. float4 mask;
  261. };
  262.  
  263. void PS_ResizeDepth(in SSR_VSOUT i, out float4 o : SV_Target0)
  264. {
  265. o = tex2D(qUINT::sDepthBufferTex, i.uv).x;
  266. }
  267.  
  268. void PS_PrepareColor(in SSR_VSOUT i, out float4 o : SV_Target0)
  269. {
  270. o = tex2D(qUINT::sBackBufferTex, i.uv);
  271. }
  272. void PS_SSR(in SSR_VSOUT i, out float4 reflection : SV_Target0, out float4 blurbuffer : SV_Target1)
  273. {
  274. blurbuffer = get_normal_and_edges_from_depth(i);
  275. float jitter = bayer(i.vpos.xy,3) - 0.5;
  276.  
  277. SceneData scene;
  278. scene.position = get_position_from_uv(i.uv, i);
  279. scene.eyedir = normalize(scene.position); //not the direction where the eye it but where it looks at
  280. scene.normal = blend_normals(blurbuffer.xyz, get_normal_from_color(i.uv, 40.0 * qUINT::PIXEL_SIZE / scene.position.z * SSR_RELIEF_SCALE, 0.005 * SSR_RELIEF_AMOUNT, 1000.0));
  281. scene.depth = scene.position.z / RESHADE_DEPTH_LINEARIZATION_FAR_PLANE;
  282.  
  283. Ray ray;
  284. ray.origin = scene.position;
  285. ray.dir = reflect(scene.eyedir, scene.normal);
  286. ray.step = (0.2 + 0.05 * jitter * SSR_JITTER_AMOUNT) * sqrt(scene.depth) * rcp(1e-3 + saturate(1 - dot(ray.dir, scene.eyedir))); //<-ensure somewhat uniform step size in screen percentage
  287. ray.pos = ray.origin + ray.dir * ray.step;
  288.  
  289. TraceData trace;
  290. trace.uv = i.uv;
  291. trace.hit = 0;
  292. trace.num_steps = 20;
  293. trace.num_refines = 3;
  294.  
  295. int j = 0;
  296. int k = 0;
  297. bool uv_inside_screen;
  298.  
  299. while(j++ < trace.num_steps)
  300. {
  301. trace.uv = get_uv_from_position(ray.pos, i);
  302. trace.error = get_position_from_uv(trace.uv, i) - ray.pos;
  303.  
  304. if(trace.error.z < 0 && trace.error.z > -SSR_ACCEPT_RANGE * ray.step)
  305. {
  306. j = 0; //ensure we have enough steps left to complete our refinement
  307.  
  308. if(k < trace.num_refines)
  309. {
  310. //step back
  311. ray.step /= SSR_RAY_INC;
  312. ray.pos -= ray.dir * ray.step;
  313. //decrease stepsize by magic amount - at some point the increased
  314. //resolution is too small to notice and just adds up to the render cost
  315. ray.step *= SSR_RAY_INC * rcp(trace.num_steps);
  316. }
  317. else
  318. {
  319. j += trace.num_steps; //algebraic "break" - much faster
  320. }
  321. k++;
  322. }
  323.  
  324. ray.pos += ray.dir * ray.step;
  325. ray.step *= SSR_RAY_INC;
  326.  
  327. uv_inside_screen = all(saturate(-trace.uv.y * trace.uv.y + trace.uv.y));
  328. j += trace.num_steps * !uv_inside_screen;
  329. }
  330.  
  331. trace.hit = k != 0; //we did refinements -> we initially found an intersection
  332.  
  333. float SSR_FRESNEL_K = 0.0; //matches most surfaces
  334. //Van Damme between physically correct and total artistic nonsense
  335. float schlick = lerp(SSR_FRESNEL_K, 1, pow(saturate(1 - dot(-scene.eyedir, scene.normal)), SSR_FRESNEL_EXP)) * SSR_REFLECTION_INTENSITY;
  336. float fade = saturate(dot(scene.eyedir, ray.dir)) * saturate(1 - dot(-scene.eyedir, scene.normal));
  337.  
  338. reflection.a = trace.hit * schlick * fade;
  339. reflection.rgb = tex2D(sSSR_ColorTex, trace.uv).rgb * reflection.a;
  340.  
  341. blurbuffer.xyz = blurbuffer.xyz * 0.5 + 0.5;
  342. }
  343.  
  344. void spatial_blur_data(inout BlurData o, in sampler inputsampler, in float4 uv)
  345. {
  346. o.key = tex2Dlod(inputsampler, uv);
  347. o.mask = tex2Dlod(qUINT::sCommonTex1, uv);
  348. o.mask.xyz = o.mask.xyz * 2 - 1;
  349. }
  350.  
  351. float compute_spatial_tap_weight(in BlurData center, in BlurData tap)
  352. {
  353. float depth_term = saturate(1 - abs(tap.mask.w - center.mask.w) * 50);
  354. float normal_term = saturate(dot(tap.mask.xyz, center.mask.xyz) * 50 - 49);
  355. return depth_term * normal_term;
  356. }
  357.  
  358. float4 blur_filter(in SSR_VSOUT i, in sampler inputsampler, in float radius, in float2 axis)
  359. {
  360. float4 blur_uv = float4(i.uv.xy, 0, 0);
  361.  
  362. BlurData center, tap;
  363. spatial_blur_data(center, inputsampler, blur_uv);
  364.  
  365. if(SSR_FILTER_SIZE == 0) return center.key;
  366.  
  367. float kernel_size = radius;
  368. float k = -2.0 * rcp(kernel_size * kernel_size + 1e-3);
  369.  
  370. float4 blursum = 0;
  371. float4 blursum_noweight = 0;
  372. float blursum_weight = 1e-3;
  373. float blursum_noweight_weight = 1e-3; //lel
  374.  
  375. [loop]
  376. for(float j = -floor(kernel_size); j <= floor(kernel_size); j++)
  377. {
  378. spatial_blur_data(tap, inputsampler, float4(i.uv + axis * (2.0 * j - 0.5), 0, 0));
  379. float tap_weight = compute_spatial_tap_weight(center, tap);
  380.  
  381. blursum += tap.key * tap_weight * exp(j * j * k) * tap.key.w;
  382. blursum_weight += tap_weight * exp(j * j * k) * tap.key.w;
  383. blursum_noweight += tap.key * exp(j * j * k) * tap.key.w;
  384. blursum_noweight_weight += exp(j * j * k) * tap.key.w;
  385. }
  386.  
  387. blursum /= blursum_weight;
  388. blursum_noweight /= blursum_noweight_weight;
  389.  
  390. return lerp(center.key, blursum, saturate(blursum_weight * 2));
  391. }
  392.  
  393. void PS_FilterH(in SSR_VSOUT i, out float4 o : SV_Target0)
  394. {
  395. o = blur_filter(i, qUINT::sCommonTex0, SSR_FILTER_SIZE, float2(0, 1) * qUINT::PIXEL_SIZE);
  396. }
  397.  
  398. void PS_FilterV(in SSR_VSOUT i, out float4 o : SV_Target0)
  399. {
  400. float4 reflection = blur_filter(i, sSSR_ColorTex, SSR_FILTER_SIZE, float2(1, 0) * qUINT::PIXEL_SIZE);
  401. float alpha = reflection.w; //tex2D(qUINT::sCommonTex0, i.uv).w;
  402.  
  403. float fade = saturate(1 - qUINT::linear_depth_resized(i.uv) / SSR_FADE_DIST);
  404. o = tex2D(qUINT::sBackBufferTex, i.uv);
  405.  
  406. o.rgb = lerp(o.rgb, reflection.rgb, alpha * fade);
  407. }
  408.  
  409. /*=============================================================================
  410. Techniques
  411. =============================================================================*/
  412.  
  413. technique SSR
  414. < ui_tooltip = " >> qUINT::SSR <<\n\n"
  415. "SSR adds screen-space reflections to the scene. This shader is\n"
  416. "intended to only be used in screenshots as it will add reflections\n"
  417. "to _everything_ - ReShade limitation.\n"
  418. "\nSSR is written by Marty McFly / Pascal Gilcher"; >
  419. {
  420. pass
  421. {
  422. VertexShader = PostProcessVS;
  423. PixelShader = PS_ResizeDepth;
  424. RenderTarget = qUINT::DepthBufferTexResized;
  425. }
  426. pass
  427. {
  428. VertexShader = VS_SSR;
  429. PixelShader = PS_PrepareColor;
  430. RenderTarget = SSR_ColorTex;
  431. }
  432. pass
  433. {
  434. VertexShader = VS_SSR;
  435. PixelShader = PS_SSR;
  436. RenderTarget0 = qUINT::CommonTex0;
  437. RenderTarget1 = qUINT::CommonTex1;
  438. }
  439. pass
  440. {
  441. VertexShader = VS_SSR;
  442. PixelShader = PS_FilterH;
  443. RenderTarget = SSR_ColorTex;
  444. }
  445. pass
  446. {
  447. VertexShader = VS_SSR;
  448. PixelShader = PS_FilterV;
  449. }
  450. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement