Advertisement
Guest User

Demul Shenmue SSAO Reshade.fx

a guest
Jun 26th, 2016
459
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.67 KB | None | 0 0
  1. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2. // ReShade effect file
  3. // visit facebook.com/MartyMcModding for news/updates
  4. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5. // Ambient Obscurance with Indirect Lighting "MXAO" 1.1r by Marty McFly
  6. // Copyright © 2008-2016 Marty McFly
  7. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  8.  
  9. #define fMXAOAmbientOcclusionAmount 2.0 //[0.0 to 2.0] Linearly increases AO intensity. Can cause pitch black clipping if set too high.
  10. #define bMXAOIndirectLightingEnable 0 //[0 or 1] Enables Indirect Lighting calculation. Will cause a major fps hit.
  11. #define fMXAOIndirectLightingAmount 4.0 //[0.0 to 8.0] Linearly increases IL intensity.
  12. #define fMXAOIndirectLightingSaturation 1.0 //[0.0 to 3.0] Boosts IL saturation for more pronounced effect.
  13.  
  14. #define fMXAOSampleRadius 5.0 //[0.5 to 20.0] Sample radius of GI, higher values drop performance. Heavily depending on game, GTASA: 10 = GTA V: 40ish
  15. #define iMXAOSampleCount 255 //[16 to 255] Amount of MXAO samples. Higher means more accurate and less noisy AO at the cost of fps.
  16. #define bMXAOSmartSamplingEnable 1 //[0 or 1] Enables smart sample count reduction for far areas. May look ugly when low sample count (16 or less) is used, turn it off then.
  17. #define fMXAOSampleRandomization 1.0 //[0.0 to 1.0] Breaks up the dither pattern a bit if sample spiral gets too visible (low samples and/or high radius). Needs stronger blurring though.
  18. #define fMXAONormalBias 0.2 //[0.00 to 0.4] Normals bias to reduce self-occlusion of surfaces that have a low angle to each other.
  19. #define bMXAOBackfaceCheckEnable 0 //[0 or 1] For indirect lighting only! Enables back face check so surfaces facing away from the source position don't cast light. It comes with a slight fps drop.
  20. #define bMXAOBoundaryCheckEnable 0 //[0 or 1] Enables screen boundary check for samples. Can be useful to remove odd behaviour with too high sample radius / objects very close to camera. It comes with a slight fps drop.
  21. #define bMXAOLowPrecisionEnable 1 //[0 or 1] Enables lower bit mode for AO source texture (R32F vs R16F). This will improve performance but may introduce some artifacts at distant objects.
  22. #define fMXAOBlurSharpness 2.5 //[0.00 to 3.0] AO sharpness, higher means more sharp geometry edges but noisier AO, less means smoother AO but blurry in the distance.
  23. #define fMXAOBlurSteps 3 //[2 to 7] Offset count for AO smoothening. Higher means more smooth AO but also blurrier AO.
  24.  
  25. #define fMXAOSizeScale 1.0 //[0.5 to 1.0] Resolution scale in which AO is being calculated.
  26. #define fMXAOMipLevelIL 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.
  27. #define fMXAOMipLevelAO 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
  28.  
  29. #define bMXAODebugViewEnable 1 //[0 or 1] Enables raw AO/IL output for debugging and tuning purposes.
  30.  
  31. //custom variables, depleted after Framework implementation.
  32. #define AO_FADE____START 0.6 //[0.0 to 1.0] Depth at which AO starts to fade out. 0.0 = camera, 1.0 = sky. Must be lower than AO fade end.
  33. #define AO_FADE____END 0.9 //[0.0 to 1.0] Depth at which AO completely fades out. 0.0 = camera, 1.0 = sky. Must be higher than AO fade start.
  34. #define MXAO_TOGGLEKEY 0x20 //NUM5
  35.  
  36. #pragma reshade showfps
  37.  
  38. uniform float Timer < source = "timer"; >;
  39.  
  40. #define PixelSize float2(BUFFER_RCP_WIDTH, BUFFER_RCP_HEIGHT)
  41. //textures
  42. texture2D texColor : COLOR;
  43. texture2D texDepth : DEPTH;
  44. texture2D texLOD { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA8; MipLevels = 5+fMXAOMipLevelIL;};
  45.  
  46. #if(bMXAOLowPrecisionEnable != 0)
  47. texture2D texDepthLOD { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = R16F; MipLevels = 5+fMXAOMipLevelAO;};
  48. #else
  49. texture2D texDepthLOD { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = R32F; MipLevels = 5+fMXAOMipLevelAO;};
  50. #endif
  51.  
  52. #if(bMXAOBackfaceCheckEnable != 0)
  53. texture2D texNormal { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA8; MipLevels = 5+fMXAOMipLevelIL;};
  54. #else
  55. texture2D texNormal { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA8; };
  56. #endif
  57.  
  58. texture2D texSSAO { Width = BUFFER_WIDTH*fMXAOSizeScale; Height = BUFFER_HEIGHT*fMXAOSizeScale; Format = RGBA8; };
  59. texture2D texDither <string source = "bayer16x16.png";> { Width = 16;Height = 16;Format = R8;};
  60.  
  61. sampler2D SamplerColor
  62. {
  63. Texture = texColor;
  64. MinFilter = LINEAR;
  65. MagFilter = LINEAR;
  66. MipFilter = LINEAR;
  67. AddressU = Clamp;
  68. AddressV = Clamp;
  69. };
  70.  
  71. sampler2D SamplerDepth
  72. {
  73. Texture = texDepth;
  74. MinFilter = LINEAR;
  75. MagFilter = LINEAR;
  76. MipFilter = LINEAR;
  77. AddressU = Clamp;
  78. AddressV = Clamp;
  79. };
  80.  
  81. sampler2D SamplerLOD
  82. {
  83. Texture = texLOD;
  84. MinFilter = LINEAR;
  85. MagFilter = LINEAR;
  86. MipFilter = LINEAR;
  87. AddressU = Clamp;
  88. AddressV = Clamp;
  89. };
  90.  
  91. sampler2D SamplerDepthLOD
  92. {
  93. Texture = texDepthLOD;
  94. MinFilter = LINEAR;
  95. MagFilter = LINEAR;
  96. MipFilter = LINEAR;
  97. AddressU = Clamp;
  98. AddressV = Clamp;
  99. };
  100.  
  101. sampler2D SamplerNormal
  102. {
  103. Texture = texNormal;
  104. MinFilter = LINEAR;
  105. MagFilter = LINEAR;
  106. MipFilter = LINEAR;
  107. AddressU = Clamp;
  108. AddressV = Clamp;
  109. };
  110.  
  111. sampler2D SamplerSSAO
  112. {
  113. Texture = texSSAO;
  114. MinFilter = LINEAR;
  115. MagFilter = LINEAR;
  116. MipFilter = LINEAR;
  117. AddressU = Clamp;
  118. AddressV = Clamp;
  119. };
  120.  
  121. sampler2D SamplerDither
  122. {
  123. Texture = texDither;
  124. MinFilter = POINT;
  125. MagFilter = POINT;
  126. MipFilter = POINT;
  127. AddressU = Wrap;
  128. AddressV = Wrap;
  129. };
  130.  
  131. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  132. //
  133. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  134.  
  135. void VS_PostProcess(in uint id : SV_VertexID, out float4 pos : SV_Position, out float2 texcoord : TEXCOORD)
  136. {
  137. texcoord.x = (id == 2) ? 2.0 : 0.0;
  138. texcoord.y = (id == 1) ? 2.0 : 0.0;
  139. pos = float4(texcoord * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
  140. }
  141.  
  142. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  143. //
  144. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  145.  
  146. #define RESHADE_DEPTH_LINEARIZATION_FAR_PLANE 1000.0
  147.  
  148. float GetLinearDepth(float2 coords)
  149. {
  150. float depth = tex2Dlod(SamplerDepth, float4(coords.xy,0,0)).x;
  151. depth = -depth + 0.00;
  152. return depth;
  153. }
  154.  
  155. float3 GetPosition(float2 coords)
  156. {
  157. float EyeDepth = GetLinearDepth(coords.xy)*RESHADE_DEPTH_LINEARIZATION_FAR_PLANE;
  158. return float3((coords.xy * 2.0 - 1.0)*EyeDepth,EyeDepth);
  159. }
  160.  
  161. float3 GetPositionLOD(float2 coords, int mipLevel)
  162. {
  163. float EyeDepth = tex2Dlod(SamplerDepthLOD, float4(coords.xy,0,mipLevel)).x;
  164. return float3((coords.xy * 2.0 - 1.0)*EyeDepth,EyeDepth);
  165. }
  166.  
  167. float3 GetNormalFromDepth(float2 coords)
  168. {
  169. float3 centerPos = GetPosition(coords.xy);
  170. float2 offs = PixelSize.xy*1.0;
  171. float3 ddx1 = GetPosition(coords.xy + float2(offs.x, 0)) - centerPos;
  172. float3 ddx2 = centerPos - GetPosition(coords.xy + float2(-offs.x, 0));
  173.  
  174. float3 ddy1 = GetPosition(coords.xy + float2(0, offs.y)) - centerPos;
  175. float3 ddy2 = centerPos - GetPosition(coords.xy + float2(0, -offs.y));
  176.  
  177. ddx1 = lerp(ddx1, ddx2, abs(ddx1.z) > abs(ddx2.z));
  178. ddy1 = lerp(ddy1, ddy2, abs(ddy1.z) > abs(ddy2.z));
  179.  
  180. float3 normal = cross(ddy1, ddx1);
  181.  
  182. return normalize(normal);
  183. }
  184.  
  185. float4 GetBlurFactors(float2 coords)
  186. {
  187. return float4(tex2Dlod(SamplerNormal, float4(coords.xy,0,0)).xyz*2.0-1.0,GetLinearDepth(coords.xy));
  188. }
  189.  
  190. float GetBlurWeight(float r, float4 z, float4 z0)
  191. {
  192. float normaldiff = distance(z.xyz,z0.xyz);
  193. float depthdiff = abs(z.w-z0.w);
  194.  
  195. float depthfalloff = pow(saturate(1.0 - z0.w),3.0);
  196. float fresnelfactor = saturate(min(-z0.z,-z.z));
  197.  
  198. float normalweight = saturate(1.0-normaldiff * fMXAOBlurSharpness);
  199. float depthweight = saturate(1.0-depthdiff * RESHADE_DEPTH_LINEARIZATION_FAR_PLANE * fMXAOBlurSharpness * fresnelfactor * depthfalloff * 0.5);
  200.  
  201. return min(depthweight,normalweight);
  202. }
  203.  
  204. float2 GetRandom2FromCoord(float2 coords)
  205. {
  206. coords *= 1000.0;
  207. float3 coords3 = frac(float3(coords.xyx) * 0.1031);
  208. coords3 += dot(coords3.xyz, coords3.yzx+19.19);
  209. return frac(float2((coords3.x + coords3.y)*coords3.z, (coords3.x+coords3.z)*coords3.y));
  210. }
  211.  
  212. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  213. //
  214. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  215.  
  216. void PS_AO_Pre(float4 vpos : SV_Position, float2 texcoord : TEXCOORD, out float4 color : SV_Target0, out float4 depth : SV_Target1, out float4 normal : SV_Target2)
  217. {
  218. color = tex2D(SamplerColor, texcoord.xy);
  219. depth = GetLinearDepth(texcoord.xy)*RESHADE_DEPTH_LINEARIZATION_FAR_PLANE;
  220. normal = GetNormalFromDepth(texcoord.xy).xyzz*0.5+0.5; // * 0.5 + 0.5; //packing into 2 components not possible.
  221. }
  222.  
  223. void PS_AO_Gen(float4 vpos : SV_Position, float2 texcoord : TEXCOORD, out float4 res : SV_Target0)
  224. {
  225. float3 ScreenSpaceNormals = GetNormalFromDepth(texcoord.xy); //tex2D(SamplerNormal, texcoord.xy).xyz * 2.0 - 1.0; //better to use best possible data than rounded texture values
  226. float3 ScreenSpacePosition = GetPositionLOD(texcoord.xy, 0);
  227.  
  228. float scenedepth = ScreenSpacePosition.z / RESHADE_DEPTH_LINEARIZATION_FAR_PLANE;
  229. ScreenSpacePosition += ScreenSpaceNormals * scenedepth;
  230.  
  231. float numSamples = lerp(iMXAOSampleCount,12,scenedepth / AO_FADE____END); //AO FADEOUT //12 is minimum acceptable sampling count and max(12,...) makes falloff ineffective for small sample counts.
  232. float2 SampleRadiusScaled = fMXAOSampleRadius / (numSamples * ScreenSpacePosition.z * float2(1.0, PixelSize.x/PixelSize.y) * 0.6);
  233. float radialJitter = (GetRandom2FromCoord(texcoord.xy).x-0.5) * fMXAOSampleRandomization;
  234.  
  235. float rotAngle = tex2D(SamplerDither, texcoord.xy * float2(BUFFER_WIDTH,BUFFER_HEIGHT) * fMXAOSizeScale * 0.0625).x;
  236. float mipFactor = SampleRadiusScaled.x*numSamples*19.0;
  237.  
  238. float4 AOandGI = 0.0;
  239.  
  240. float2x2 radialMatrix = float2x2(0.575,0.81815,-0.81815,0.575); //E.F
  241. float2 currentVector = float2(cos(rotAngle*6.283), sin(rotAngle*6.283));
  242.  
  243. float fNegInvR2 = -1.0/(fMXAOSampleRadius*fMXAOSampleRadius);
  244.  
  245. [loop]
  246. for (float i=1.0; i <= numSamples; i++)
  247. {
  248. currentVector = mul(currentVector.xy, radialMatrix);
  249. float2 currentOffset = texcoord.xy + currentVector.xy * SampleRadiusScaled.xy * (i+radialJitter);
  250.  
  251. #if(bMXAOBoundaryCheckEnable != 0)
  252. [branch]
  253. if(currentOffset.x < 1.0 && currentOffset.y < 1.0 && currentOffset.x > 0.0 && currentOffset.y > 0.0)
  254. {
  255. #endif
  256. float mipLevel = clamp((int)floor(log2(mipFactor*i)) - 3, fMXAOMipLevelAO, 5); //AO must not go beyond 5
  257.  
  258. float3 occlVec = GetPositionLOD(currentOffset.xy, mipLevel) - ScreenSpacePosition;
  259. float occlDistance = length(occlVec);
  260. float SurfaceAngle = dot(occlVec/occlDistance, ScreenSpaceNormals);
  261.  
  262. float fAO = saturate(occlDistance * fNegInvR2 + 1.0) * saturate(SurfaceAngle - fMXAONormalBias);
  263.  
  264. #if(bMXAOIndirectLightingEnable != 0)
  265. float3 fIL = tex2Dlod(SamplerLOD, float4(currentOffset,0,mipLevel + fMXAOMipLevelIL)).xyz;
  266. #if(bMXAOBackfaceCheckEnable != 0)
  267. float3 offsetNormals = tex2Dlod(SamplerNormal, float4(currentOffset,0,mipLevel + fMXAOMipLevelIL)).xyz * 2.0 - 1.0;
  268. float facingtoSource = dot(-normalize(occlVec),offsetNormals);
  269. facingtoSource = smoothstep(-0.5,0.0,facingtoSource);
  270. fIL *= facingtoSource;
  271. #endif
  272. AOandGI.w += fAO*saturate(1-dot(fIL,float3(0.299,0.587,0.114)));
  273. AOandGI.xyz += fIL*fAO;
  274. #else
  275. AOandGI.w += fAO;
  276. #endif
  277.  
  278. #if(bMXAOBoundaryCheckEnable != 0)
  279. }
  280. #endif
  281. }
  282.  
  283. AOandGI *= 20.0 / ((1.0-fMXAONormalBias)*numSamples*fMXAOSampleRadius);
  284. res = lerp(AOandGI,float4(0.0.xxx,0.0), AO_FADE____END < scenedepth); //AO FADEOUT
  285. }
  286.  
  287. void PS_AO_Blur1(float4 vpos : SV_Position, float2 texcoord : TEXCOORD, out float4 res : SV_Target0)
  288. {
  289. float4 center_factor = GetBlurFactors(texcoord.xy);
  290. float4 temp_factor = 0.0;
  291.  
  292. float totalweight = 1.0;
  293. float tempweight = 0.0;
  294.  
  295. float4 total_ao = tex2Dlod(SamplerSSAO, float4(texcoord.xy,0,0));
  296. float4 temp_ao = 0.0;
  297.  
  298. [loop]
  299. for(float r = 1.0; r <= fMXAOBlurSteps; r += 1.0)
  300. {
  301. float2 axis = float2(-r,r)/fMXAOSizeScale*1.25;
  302.  
  303. temp_factor = GetBlurFactors(texcoord.xy + axis * PixelSize.xy);
  304. temp_ao = tex2Dlod(SamplerSSAO, float4(texcoord.xy + axis * PixelSize.xy,0,0));
  305. tempweight = GetBlurWeight(r, temp_factor, center_factor);
  306.  
  307. total_ao += temp_ao * tempweight;
  308. totalweight += tempweight;
  309.  
  310. temp_factor = GetBlurFactors(texcoord.xy - axis * PixelSize.xy);
  311. temp_ao = tex2Dlod(SamplerSSAO, float4(texcoord.xy - axis * PixelSize.xy,0,0));
  312. tempweight = GetBlurWeight(r, temp_factor, center_factor);
  313.  
  314. total_ao += temp_ao * tempweight;
  315. totalweight += tempweight;
  316. }
  317.  
  318. total_ao /= totalweight;
  319. res = total_ao;
  320. }
  321.  
  322. void PS_AO_Blur2(float4 vpos : SV_Position, float2 texcoord : TEXCOORD, out float4 res : SV_Target0)
  323. {
  324. float4 center_factor = GetBlurFactors(texcoord.xy);
  325. float4 temp_factor = 0.0;
  326.  
  327. float totalweight = 1.0;
  328. float tempweight = 0.0;
  329.  
  330. float4 total_ao = tex2Dlod(SamplerColor, float4(texcoord.xy,0,0));
  331. float4 temp_ao = 0.0;
  332.  
  333. [loop]
  334. for(float r = 1.0; r <= fMXAOBlurSteps; r += 1.0)
  335. {
  336. float2 axis = float2(r,r)/fMXAOSizeScale*1.25;
  337.  
  338. temp_factor = GetBlurFactors(texcoord.xy + axis * PixelSize.xy);
  339. temp_ao = tex2Dlod(SamplerColor, float4(texcoord.xy + axis * PixelSize.xy,0,0));
  340. tempweight = GetBlurWeight(r, temp_factor, center_factor);
  341.  
  342. total_ao += temp_ao * tempweight;
  343. totalweight += tempweight;
  344.  
  345. temp_factor = GetBlurFactors(texcoord.xy - axis * PixelSize.xy);
  346. temp_ao = tex2Dlod(SamplerColor, float4(texcoord.xy - axis * PixelSize.xy,0,0));
  347. tempweight = GetBlurWeight(r, temp_factor, center_factor);
  348.  
  349. total_ao += temp_ao * tempweight;
  350. totalweight += tempweight;
  351. }
  352.  
  353. total_ao /= totalweight;
  354. float4 mxao = saturate(total_ao);
  355.  
  356. float scenedepth = GetLinearDepth(texcoord.xy); //might change center_factor so better fetch depth directly here.
  357. float4 color = max(0.0,tex2D(SamplerLOD, texcoord.xy));
  358. float colorgray = dot(color.xyz,float3(0.299,0.587,0.114));
  359.  
  360. mxao.xyz = lerp(dot(mxao.xyz,float3(0.299,0.587,0.114)),mxao.xyz,fMXAOIndirectLightingSaturation) * fMXAOIndirectLightingAmount;
  361. mxao.w = 1.0-pow(1.0-mxao.w, fMXAOAmbientOcclusionAmount * 2.0);
  362.  
  363. #if(bMXAODebugViewEnable == 0)
  364. mxao = lerp(mxao, 0.0, pow(colorgray,2.0));
  365. #endif
  366. mxao.w = lerp(mxao.w, 0.0,smoothstep(AO_FADE____START, AO_FADE____END, scenedepth)); //AO FADEOUT
  367. mxao.xyz = lerp(mxao.xyz,0.0,smoothstep(AO_FADE____START*0.5, AO_FADE____END*0.5, scenedepth)); //AO FADEOUT //IL can look really bad on far objects.
  368.  
  369. float3 GI = mxao.w - mxao.xyz;
  370. GI = max(0.0,1-GI);
  371. color.xyz *= GI;
  372.  
  373. #if(bMXAODebugViewEnable != 0)
  374. #if(bMXAOIndirectLightingEnable != 0)
  375. color.xyz = 1-mxao.w;
  376. #else
  377. color.xyz = 1-mxao.w;
  378. #endif
  379. #endif
  380.  
  381. res = color;
  382. }
  383.  
  384. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  385. //
  386. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  387.  
  388. technique PostProcess < bool enabled = 1;toggle = MXAO_TOGGLEKEY;>
  389. {
  390. pass P0
  391. {
  392. VertexShader = VS_PostProcess;
  393. PixelShader = PS_AO_Pre;
  394. RenderTarget0 = texLOD;
  395. RenderTarget1 = texDepthLOD;
  396. RenderTarget2 = texNormal;
  397. }
  398. pass P1
  399. {
  400. VertexShader = VS_PostProcess;
  401. PixelShader = PS_AO_Gen;
  402. RenderTarget = texSSAO;
  403. }
  404. pass P2_0
  405. {
  406. VertexShader = VS_PostProcess;
  407. PixelShader = PS_AO_Blur1;
  408. }
  409. pass P2_1
  410. {
  411. VertexShader = VS_PostProcess;
  412. PixelShader = PS_AO_Blur2;
  413. }
  414. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement