Guest User

HBAO ReShade

a guest
Jan 25th, 2015
78
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.  
  2. #define ScreenSize float4(BUFFER_WIDTH, BUFFER_RCP_WIDTH, float(BUFFER_WIDTH) / float(BUFFER_HEIGHT), float(BUFFER_HEIGHT) / float(BUFFER_WIDTH)) //x=Width, y=1/Width, z=ScreenScaleY, w=1/ScreenScaleY
  3.  
  4. //textures
  5. texture2D texColor : COLOR;
  6. texture2D texDepth : DEPTH;
  7. texture texNoise < string source = "mcnoise.png"; >
  8. {
  9. Width = 1920;
  10. Height = 1080;
  11. MipLevels = 1;
  12. Format = RGBA8;
  13. };
  14.  
  15. sampler2D SamplerColor
  16. {
  17. Texture = texColor;
  18. MinFilter = LINEAR;
  19. MagFilter = LINEAR;
  20. MipFilter = LINEAR;
  21. AddressU = Clamp;
  22. AddressV = Clamp;
  23. SRGBTexture=FALSE;
  24. MaxMipLevel=1;
  25. MipMapLodBias=0;
  26. };
  27.  
  28. sampler2D SamplerDepth
  29. {
  30. Texture = texDepth;
  31. MinFilter = POINT;
  32. MagFilter = POINT;
  33. MipFilter = NONE;
  34. AddressU = Clamp;
  35. AddressV = Clamp;
  36. SRGBTexture=FALSE;
  37. MaxMipLevel=1;
  38. MipMapLodBias=0;
  39. };
  40.  
  41. sampler2D SamplerNoise
  42. {
  43. Texture = texNoise;
  44. MinFilter = POINT;
  45. MagFilter = POINT;
  46. MipFilter = NONE;
  47. AddressU = Clamp;
  48. AddressV = Clamp;
  49. SRGBTexture=FALSE;
  50. MaxMipLevel=0;
  51. MipMapLodBias=0;
  52. };
  53.  
  54. struct VS_OUTPUT_POST
  55. {
  56. float4 vpos : SV_Position;
  57. float2 txcoord : TEXCOORD0;
  58. };
  59.  
  60. struct VS_INPUT_POST
  61. {
  62. uint id : SV_VertexID;
  63. };;
  64.  
  65.  
  66. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  67. //
  68. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  69.  
  70. VS_OUTPUT_POST VS_PostProcess(VS_INPUT_POST IN)
  71. {
  72. VS_OUTPUT_POST OUT;
  73. OUT.txcoord.x = (IN.id == 2) ? 2.0 : 0.0;
  74. OUT.txcoord.y = (IN.id == 1) ? 2.0 : 0.0;
  75. OUT.vpos = float4(OUT.txcoord * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
  76. return OUT;
  77. }
  78.  
  79. static float nearZ = 0.1;
  80. static float farZ = 100.0;
  81. #define FAR_PLANE_Z (460.0)
  82. static float g_Strength = 1.0f; // 0.0..3.0
  83. static float g_IntensityMul = 1.0f; // 1.0..3.0
  84.  
  85. static float g_NumSteps = 3; // 0..32
  86. static float g_NumDir = 5; // 0..25
  87. static float m_RadiusMultiplier = 0.5; // 0.0..2.0
  88. static float m_AngleBias = 0.0; // 0.0..60.0
  89. #define SAMPLE_FIRST_STEP 1
  90.  
  91.  
  92. #define M_PI 3.14159265f
  93. #define g_R (m_RadiusMultiplier * 1.0f )
  94. #define g_Radius2 (g_R * g_R)
  95. #define g_NegInvRadius2 (-1.0f / g_Radius2 )
  96. #define g_AngleBias ( m_AngleBias * M_PI / 180)
  97. #define g_TanAngleBias (tan(g_AngleBias))
  98. #define g_MaxRadiusPixels (0.1f * min(BUFFER_WIDTH, BUFFER_HEIGHT))
  99.  
  100. #define fovY 70
  101.  
  102. #define g_FocalLen float2(1.0f / tan(fovY * 0.5 * 0.01745) * BUFFER_WIDTH / BUFFER_HEIGHT, 1.0f / tan(fovY * 0.5 * 0.01745)) //needs PI/180 otherwise image is plain white
  103.  
  104.  
  105. #define SCREEN_SIZE float2(BUFFER_WIDTH, BUFFER_HEIGHT)
  106. #define PIXEL_SIZE float2(BUFFER_RCP_WIDTH, BUFFER_RCP_HEIGHT)
  107.  
  108.  
  109. /** Negative, "linear" values in world-space units */
  110. float LinearizeDepth(float depth)
  111. {
  112. //return (2.0f * nearZ) / (nearZ + farZ - depth * (farZ - nearZ));
  113. return 1 / ((depth * ((farZ - nearZ) / (-farZ * nearZ)) + farZ / (farZ * nearZ)));
  114. }
  115.  
  116.  
  117. //----------------------------------------------------------------------------------
  118. float3 fetchEyePos(in float2 v)
  119. {
  120. float z = tex2Dlod(SamplerDepth, float4(v, 0, 0)).x;
  121. v = v * 2 - 1;
  122. float3 result = float3(v * 1.0, 1) * z;
  123. return result;
  124. }
  125.  
  126. //----------------------------------------------------------------------------------
  127. float length2(float3 v)
  128. {
  129. return dot(v, v);
  130. }
  131.  
  132. //----------------------------------------------------------------------------------
  133. float invLength(float2 v)
  134. {
  135. return rsqrt(dot(v,v));
  136. }
  137.  
  138. //----------------------------------------------------------------------------------
  139. float3 minDiff(float3 P, float3 Pr, float3 Pl)
  140. {
  141. float3 V1 = Pr - P;
  142. float3 V2 = P - Pl;
  143. return (length2(V1) < length2(V2)) ? V1 : V2;
  144. }
  145.  
  146. //----------------------------------------------------------------------------------
  147. float2 rotateDirections(float2 Dir, float2 CosSin)
  148. {
  149. return float2(Dir.x*CosSin.x - Dir.y*CosSin.y, Dir.x*CosSin.y + Dir.y*CosSin.x);
  150. }
  151.  
  152. //----------------------------------------------------------------------------------
  153. float falloff(float d2)
  154. {
  155. return d2 * g_NegInvRadius2 + 1.0f;
  156. }
  157.  
  158. //----------------------------------------------------------------------------------
  159. float2 snapUVOffset(float2 uv)
  160. {
  161. return round(uv * SCREEN_SIZE) * PIXEL_SIZE;
  162. }
  163.  
  164. //----------------------------------------------------------------------------------
  165. float tangent(float3 T)
  166. {
  167. return -T.z * invLength(T.xy);
  168. }
  169.  
  170. //----------------------------------------------------------------------------------
  171. float tangent(float3 P, float3 S)
  172. {
  173. return (P.z - S.z) * invLength(S.xy - P.xy);
  174. }
  175.  
  176. //----------------------------------------------------------------------------------
  177. float biasedtangent(float3 T)
  178. {
  179. return tangent(T) + g_TanAngleBias;
  180. }
  181.  
  182. //----------------------------------------------------------------------------------
  183. float3 tangentVector(float2 deltaUV, float3 dPdu, float3 dPdv)
  184. {
  185. return deltaUV.x * dPdu + deltaUV.y * dPdv;
  186. }
  187.  
  188. //----------------------------------------------------------------------------------
  189. float tanToSin(float x)
  190. {
  191. return x * rsqrt(x*x + 1.0f);
  192. }
  193.  
  194. //----------------------------------------------------------------------------------
  195. void computeSteps(inout float2 step_size_uv, inout float numSteps, float ray_radius_pix, float rand)
  196. {
  197. // Avoid oversampling if g_NumSteps is greater than the kernel radius in pixels
  198. numSteps = min(g_NumSteps, ray_radius_pix);
  199.  
  200. // Divide by Ns+1 so that the farthest samples are not fully attenuated
  201. float step_size_pix = ray_radius_pix / (numSteps + 1);
  202.  
  203. // Clamp numSteps if it is greater than the max kernel footprint
  204. float maxNumSteps = g_MaxRadiusPixels / step_size_pix;
  205. [branch]
  206. if (maxNumSteps < numSteps)
  207. {
  208. // Use dithering to avoid AO discontinuities
  209. numSteps = floor(maxNumSteps + rand);
  210. numSteps = max(numSteps, 1);
  211. step_size_pix = g_MaxRadiusPixels / numSteps;
  212. }
  213.  
  214. // Step size in uv space
  215. step_size_uv = step_size_pix * PIXEL_SIZE;
  216. }
  217.  
  218. //----------------------------------------------------------------------------------
  219. float integerateOcclusion(float2 uv0, float2 snapped_duv, float3 P, float3 dPdu, float3 dPdv, inout float tanH)
  220. {
  221. float ao = 0;
  222.  
  223. // Compute a tangent vector for snapped_duv
  224. float3 T1 = tangentVector(snapped_duv, dPdu, dPdv);
  225. float tanT = biasedtangent(T1);
  226. float sinT = tanToSin(tanT);
  227.  
  228. float3 S = fetchEyePos(uv0 + snapped_duv);
  229. float tanS = tangent(P, S);
  230.  
  231. float sinS = tanToSin(tanS);
  232. float d2 = length2(S - P);
  233.  
  234. [branch]
  235. if ((d2 < g_Radius2) && (tanS > tanT))
  236. {
  237. // Compute AO between the tangent plane and the sample
  238. ao = falloff(d2) * (sinS - sinT);
  239.  
  240. // Update the horizon angle
  241. tanH = max(tanH, tanS);
  242. }
  243.  
  244. return ao;
  245. }
  246.  
  247. //----------------------------------------------------------------------------------
  248. float horizon_occlusion(float2 deltaUV, float2 texelDeltaUV, float2 uv0, float3 P, float numSteps, float randstep, float3 dPdu, float3 dPdv )
  249. {
  250. float ao = 0;
  251.  
  252. // Randomize starting point within the first sample distance
  253. float2 uv = uv0 + snapUVOffset( randstep * deltaUV );
  254.  
  255. // Snap increments to pixels to avoid disparities between xy
  256. // and z sample locations and sample along a line
  257. deltaUV = snapUVOffset( deltaUV );
  258.  
  259. // Compute tangent vector using the tangent plane
  260. float3 T = deltaUV.x * dPdu + deltaUV.y * dPdv;
  261.  
  262. float tanH = biasedtangent(T);
  263.  
  264. #if SAMPLE_FIRST_STEP
  265. // Take a first sample between uv0 and uv0 + deltaUV
  266. float2 snapped_duv = snapUVOffset( randstep * deltaUV + texelDeltaUV );
  267. ao = integerateOcclusion(uv0, snapped_duv, P, dPdu, dPdv, tanH);
  268. --numSteps;
  269. #endif
  270.  
  271. float sinH = tanH / sqrt(1.0f + tanH*tanH);
  272.  
  273. [loop]
  274. for (float j = 1; j <= numSteps; ++j)
  275. {
  276. uv += deltaUV;
  277. float3 S = fetchEyePos(uv);
  278. float tanS = tangent(P, S);
  279. float d2 = length2(S - P);
  280.  
  281. // Use a merged dynamic branch
  282. [branch]
  283. if ((d2 < g_Radius2) && (tanS > tanH))
  284. {
  285. // Accumulate AO between the horizon and the sample
  286. float sinS = tanS / sqrt(1.0f + tanS*tanS);
  287. ao += falloff(d2) * (sinS - sinH);
  288.  
  289. // Update the current horizon angle
  290. tanH = tanS;
  291. sinH = sinS;
  292. }
  293. }
  294.  
  295. return ao;
  296. }
  297.  
  298. /** Used for packing Z into the GB channels */
  299. float CSZToKey(float z)
  300. {
  301. return clamp(z * (1.0 / FAR_PLANE_Z), 0.0, 1.0);
  302. }
  303.  
  304. /** Used for packing Z into the GB channels */
  305. void packKey(float key, out float2 p)
  306. {
  307. // Round to the nearest 1/256.0
  308. float temp = floor(key * 256.0);
  309. // Integer part
  310. p.x = temp * (1.0 / 256.0);
  311. // Fractional part
  312. p.y = key * 256.0 - temp;
  313. }
  314.  
  315. float unpackKey(float2 p)
  316. {
  317. return p.x * (256.0 / 257.0) + p.y * (1.0 / 257.0);
  318. }
  319.  
  320.  
  321. float4 PS_HBAOCalculate(VS_OUTPUT_POST IN) : COLOR
  322. {
  323.  
  324. float4 output = float4(1,1,1,1);
  325. float3 P = fetchEyePos(IN.txcoord.xy);
  326. float3 rand = tex2Dlod(SamplerNoise, float4(IN.txcoord.xy * 64.0, 0, 0)).rgb*2-1;
  327.  
  328. float2 ray_radius_uv = 0.5 * g_R * g_FocalLen / P.z;
  329. float ray_radius_pix = ray_radius_uv.x * SCREEN_SIZE.x;
  330. if (ray_radius_pix < 10)
  331. {
  332. return 1.0;
  333. }
  334.  
  335. float numSteps;
  336. float2 step_size;
  337. computeSteps(step_size, numSteps, ray_radius_pix, rand.z);
  338.  
  339. packKey(CSZToKey(P.z), output.gb);
  340.  
  341. float3 Pr, Pl, Pt, Pb;
  342. Pr = fetchEyePos(IN.txcoord.xy + float2(PIXEL_SIZE.x, 0));
  343. Pl = fetchEyePos(IN.txcoord.xy + float2(-PIXEL_SIZE.x, 0));
  344. Pt = fetchEyePos(IN.txcoord.xy + float2(0, PIXEL_SIZE.y));
  345. Pb = fetchEyePos(IN.txcoord.xy + float2(0, -PIXEL_SIZE.y));
  346.  
  347. float3 dPdu = minDiff(P, Pr, Pl) * (SCREEN_SIZE.x * PIXEL_SIZE.y);
  348. float3 dPdv = minDiff(P, Pt, Pb) * (SCREEN_SIZE.y * PIXEL_SIZE.x);
  349.  
  350. float ao = 0;
  351. float d;
  352. float alpha = 2.0f * M_PI / g_NumDir;
  353.  
  354. [loop]
  355. for (d = 0; d < g_NumDir; ++d)
  356. {
  357. float angle = alpha * d;
  358. float2 dir = rotateDirections(float2(cos(angle), sin(angle)), rand.xy);
  359. float2 deltaUV = dir * step_size.xy;
  360. float2 texelDeltaUV = dir * PIXEL_SIZE;
  361. ao += horizon_occlusion(deltaUV, texelDeltaUV, IN.txcoord.xy, P, numSteps, rand.z, dPdu, dPdv);
  362. }
  363.  
  364. output.r = 1.0 - ao / g_NumDir * g_Strength * g_IntensityMul;
  365.  
  366. return float4(output.r, output.r, output.r, 1.0);
  367.  
  368.  
  369. //return tex2D(SamplerColor, IN.txcoord.xy)*1.5;
  370. }
  371.  
  372.  
  373. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  374. //
  375. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  376.  
  377. technique MasterEffect < bool enabled = 1; toggle = 0x20; >
  378. {
  379. pass s1
  380. {
  381. VertexShader = VS_PostProcess;
  382. PixelShader = PS_HBAOCalculate;
  383. }
  384. }
RAW Paste Data