Advertisement
Guest User

ScreenSpaceReflections.hlsl

a guest
May 26th, 2018
286
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.81 KB | None | 0 0
  1. #ifndef UNITY_POSTFX_SSR
  2. #define UNITY_POSTFX_SSR
  3.  
  4. #include "UnityCG.cginc"
  5. #include "UnityPBSLighting.cginc"
  6. #include "UnityStandardBRDF.cginc"
  7. #include "UnityStandardUtils.cginc"
  8.  
  9. // Lux
  10. #include "../../../../Lux 2.02 Plus/Lux Shaders/Lux Core/Lux Utils/LuxUtilsDeferred.cginc"
  11.  
  12. #define SSR_MINIMUM_ATTENUATION 0.275
  13. #define SSR_ATTENUATION_SCALE (1.0 - SSR_MINIMUM_ATTENUATION)
  14.  
  15. #define SSR_VIGNETTE_INTENSITY _VignetteIntensity
  16. #define SSR_VIGNETTE_SMOOTHNESS 5.
  17.  
  18. #define SSR_COLOR_NEIGHBORHOOD_SAMPLE_SPREAD 1.0
  19.  
  20. #define SSR_FINAL_BLEND_STATIC_FACTOR 0.95
  21. #define SSR_FINAL_BLEND_DYNAMIC_FACTOR 0.7
  22.  
  23. #define SSR_ENABLE_CONTACTS 0
  24. #define SSR_KILL_FIREFLIES 0
  25.  
  26. //
  27. // Helper structs
  28. //
  29. struct Ray
  30. {
  31. float3 origin;
  32. float3 direction;
  33. };
  34.  
  35. struct Segment
  36. {
  37. float3 start;
  38. float3 end;
  39.  
  40. float3 direction;
  41. };
  42.  
  43. struct Result
  44. {
  45. bool isHit;
  46.  
  47. float2 uv;
  48. float3 position;
  49.  
  50. int iterationCount;
  51. };
  52.  
  53. //
  54. // Uniforms
  55. //
  56. Texture2D _MainTex; SamplerState sampler_MainTex;
  57. Texture2D _History; SamplerState sampler_History;
  58.  
  59. Texture2D _CameraDepthTexture; SamplerState sampler_CameraDepthTexture;
  60. Texture2D _CameraMotionVectorsTexture; SamplerState sampler_CameraMotionVectorsTexture;
  61. Texture2D _CameraReflectionsTexture; SamplerState sampler_CameraReflectionsTexture;
  62.  
  63. Texture2D _CameraGBufferTexture0; // albedo = g[0].rgb
  64. Texture2D _CameraGBufferTexture1; // roughness = g[1].a
  65. Texture2D _CameraGBufferTexture2; SamplerState sampler_CameraGBufferTexture2; // normal.xyz 2. * g[2].rgb - 1.
  66.  
  67. Texture2D _Noise; SamplerState sampler_Noise;
  68.  
  69. Texture2D _Test; SamplerState sampler_Test;
  70. Texture2D _Resolve; SamplerState sampler_Resolve;
  71.  
  72. float4 _MainTex_TexelSize;
  73. float4 _Test_TexelSize;
  74.  
  75. float4x4 _ViewMatrix;
  76. float4x4 _InverseViewMatrix;
  77. float4x4 _InverseProjectionMatrix;
  78. float4x4 _ScreenSpaceProjectionMatrix;
  79.  
  80. float4 _Params; // x: vignette intensity, y: distance fade, z: maximum march distance, w: blur pyramid lod count
  81. float4 _Params2; // x: aspect ratio, y: noise tiling, z: thickness, w: maximum iteration count
  82. #define _Attenuation .25
  83. #define _VignetteIntensity _Params.x
  84. #define _DistanceFade _Params.y
  85. #define _MaximumMarchDistance _Params.z
  86. #define _BlurPyramidLODCount _Params.w
  87. #define _AspectRatio _Params2.x
  88. #define _NoiseTiling _Params2.y
  89. #define _Bandwidth _Params2.z
  90. #define _MaximumIterationCount _Params2.w
  91.  
  92. //
  93. // Helper functions
  94. //
  95. float Attenuate(float2 uv)
  96. {
  97. float offset = min(1.0 - max(uv.x, uv.y), min(uv.x, uv.y));
  98.  
  99. float result = offset / (SSR_ATTENUATION_SCALE * _Attenuation + SSR_MINIMUM_ATTENUATION);
  100. result = saturate(result);
  101.  
  102. return pow(result, 0.5);
  103. }
  104.  
  105. float Vignette(float2 uv)
  106. {
  107. float2 k = abs(uv - 0.5) * SSR_VIGNETTE_INTENSITY;
  108. k.x *= _MainTex_TexelSize.y * _MainTex_TexelSize.z;
  109. return pow(saturate(1.0 - dot(k, k)), SSR_VIGNETTE_SMOOTHNESS);
  110. }
  111.  
  112. float3 GetViewSpacePosition(float2 uv)
  113. {
  114. float depth = _CameraDepthTexture.SampleLevel(sampler_CameraDepthTexture, UnityStereoTransformScreenSpaceTex(uv), 0).r;
  115. float4 result = mul(_InverseProjectionMatrix, float4(2.0 * uv - 1.0, depth, 1.0));
  116. return result.xyz / result.w;
  117. }
  118.  
  119. float GetSquaredDistance(float2 first, float2 second)
  120. {
  121. first -= second;
  122. return dot(first, first);
  123. }
  124.  
  125. float4 ProjectToScreenSpace(float3 position)
  126. {
  127. return float4(
  128. _ScreenSpaceProjectionMatrix[0][0] * position.x + _ScreenSpaceProjectionMatrix[0][2] * position.z,
  129. _ScreenSpaceProjectionMatrix[1][1] * position.y + _ScreenSpaceProjectionMatrix[1][2] * position.z,
  130. _ScreenSpaceProjectionMatrix[2][2] * position.z + _ScreenSpaceProjectionMatrix[2][3],
  131. _ScreenSpaceProjectionMatrix[3][2] * position.z
  132. );
  133. }
  134.  
  135. // Heavily adapted from McGuire and Mara's original implementation
  136. // http://casual-effects.blogspot.com/2014/08/screen-space-ray-tracing.html
  137. Result March(Ray ray, VaryingsDefault input)
  138. {
  139. Result result;
  140.  
  141. result.isHit = false;
  142.  
  143. result.uv = 0.0;
  144. result.position = 0.0;
  145.  
  146. result.iterationCount = 0;
  147.  
  148. Segment segment;
  149.  
  150. segment.start = ray.origin;
  151.  
  152. float end = ray.origin.z + ray.direction.z * _MaximumMarchDistance;
  153. float magnitude = _MaximumMarchDistance;
  154.  
  155. if (end > -_ProjectionParams.y)
  156. magnitude = (-_ProjectionParams.y - ray.origin.z) / ray.direction.z;
  157.  
  158. segment.end = ray.origin + ray.direction * magnitude;
  159.  
  160. float4 r = ProjectToScreenSpace(segment.start);
  161. float4 q = ProjectToScreenSpace(segment.end);
  162.  
  163. const float2 homogenizers = rcp(float2(r.w, q.w));
  164.  
  165. segment.start *= homogenizers.x;
  166. segment.end *= homogenizers.y;
  167.  
  168. float4 endPoints = float4(r.xy, q.xy) * homogenizers.xxyy;
  169. endPoints.zw += step(GetSquaredDistance(endPoints.xy, endPoints.zw), 0.0001) * max(_Test_TexelSize.x, _Test_TexelSize.y);
  170.  
  171. float2 displacement = endPoints.zw - endPoints.xy;
  172.  
  173. bool isPermuted = false;
  174.  
  175. if (abs(displacement.x) < abs(displacement.y))
  176. {
  177. isPermuted = true;
  178.  
  179. displacement = displacement.yx;
  180. endPoints.xyzw = endPoints.yxwz;
  181. }
  182.  
  183. float direction = sign(displacement.x);
  184. float normalizer = direction / displacement.x;
  185.  
  186. segment.direction = (segment.end - segment.start) * normalizer;
  187. float4 derivatives = float4(float2(direction, displacement.y * normalizer), (homogenizers.y - homogenizers.x) * normalizer, segment.direction.z);
  188.  
  189. float stride = 1.0 - min(1.0, -ray.origin.z * 0.01);
  190.  
  191. float2 uv = input.texcoord * _NoiseTiling;
  192. uv.y *= _AspectRatio;
  193.  
  194. float jitter = _Noise.SampleLevel(sampler_Noise, uv + _WorldSpaceCameraPos.xz, 0).a;
  195. stride *= _Bandwidth;
  196.  
  197. derivatives *= stride;
  198. segment.direction *= stride;
  199.  
  200. float2 z = 0.0;
  201. float4 tracker = float4(endPoints.xy, homogenizers.x, segment.start.z) + derivatives * jitter;
  202.  
  203. for (int i = 0; i < _MaximumIterationCount; ++i)
  204. {
  205. if (any(result.uv < 0.0) || any(result.uv > 1.0))
  206. {
  207. result.isHit = false;
  208. return result;
  209. }
  210.  
  211. tracker += derivatives;
  212.  
  213. z.x = z.y;
  214. z.y = tracker.w + derivatives.w * 0.5;
  215. z.y /= tracker.z + derivatives.z * 0.5;
  216.  
  217. #if SSR_KILL_FIREFLIES
  218. UNITY_FLATTEN
  219. if (z.y < -_MaximumMarchDistance)
  220. {
  221. result.isHit = false;
  222. return result;
  223. }
  224. #endif
  225.  
  226. UNITY_FLATTEN
  227. if (z.y > z.x)
  228. {
  229. float k = z.x;
  230. z.x = z.y;
  231. z.y = k;
  232. }
  233.  
  234. uv = tracker.xy;
  235.  
  236. UNITY_FLATTEN
  237. if (isPermuted)
  238. uv = uv.yx;
  239.  
  240. uv *= _Test_TexelSize.xy;
  241.  
  242. float d = _CameraDepthTexture.SampleLevel(sampler_CameraDepthTexture, UnityStereoTransformScreenSpaceTex(uv), 0);
  243. float depth = -LinearEyeDepth(d);
  244.  
  245. UNITY_FLATTEN
  246. if (z.y < depth)
  247. {
  248. result.uv = uv;
  249. result.isHit = true;
  250. result.iterationCount = i + 1;
  251. return result;
  252. }
  253. }
  254.  
  255. return result;
  256. }
  257.  
  258. //
  259. // Fragment shaders
  260. //
  261. float4 FragTest(VaryingsDefault i) : SV_Target
  262. {
  263. float4 gbuffer2 = _CameraGBufferTexture2.Sample(sampler_CameraGBufferTexture2, i.texcoordStereo);
  264.  
  265. if (dot(gbuffer2, 1.0) == 0.0)
  266. return 0.0;
  267.  
  268. // Lux
  269. half materialIndex = GetLuxMaterialIndexNormal(gbuffer2.a);
  270. const half isSkinMat = (materialIndex == 0) ? 1 : 0;
  271. float3 normal = GetLuxNormal(gbuffer2, materialIndex, i.texcoordStereo);
  272. //float3 normal = 2.0 * gbuffer2.rgb - 1.0;
  273. // End Lux
  274.  
  275. normal = mul((float3x3)_ViewMatrix, normal);
  276.  
  277. Ray ray;
  278.  
  279. ray.origin = GetViewSpacePosition(i.texcoord);
  280.  
  281. if (ray.origin.z < -_MaximumMarchDistance)
  282. return 0.0;
  283.  
  284. ray.direction = normalize(reflect(normalize(ray.origin), normal));
  285.  
  286. if (ray.direction.z > 0.0)
  287. return 0.0;
  288.  
  289. Result result = March(ray, i);
  290.  
  291. float confidence = (float)result.iterationCount / (float)_MaximumIterationCount;
  292. return float4(result.uv, confidence, (float)result.isHit);
  293. }
  294.  
  295. float4 FragResolve(VaryingsDefault i) : SV_Target
  296. {
  297. float4 test = _Test.Load(int3(i.vertex.xy, 0));
  298.  
  299. if (test.w == 0.0)
  300. return _MainTex.Sample(sampler_MainTex, i.texcoordStereo);
  301.  
  302. float4 color = _MainTex.SampleLevel(sampler_MainTex, UnityStereoTransformScreenSpaceTex(test.xy), 0);
  303.  
  304. float confidence = test.w * Attenuate(test.xy) * Vignette(test.xy);
  305.  
  306. color.rgb *= confidence;
  307. color.a = test.z;
  308.  
  309. return color;
  310. }
  311.  
  312. float4 FragReproject(VaryingsDefault i) : SV_Target
  313. {
  314. float2 motion = _CameraMotionVectorsTexture.SampleLevel(sampler_CameraMotionVectorsTexture, i.texcoordStereo, 0).xy;
  315. float2 uv = i.texcoord - motion;
  316.  
  317. const float2 k = SSR_COLOR_NEIGHBORHOOD_SAMPLE_SPREAD * _MainTex_TexelSize.xy;
  318.  
  319. float4 color = _MainTex.SampleLevel(sampler_MainTex, i.texcoordStereo, 0);
  320.  
  321. // 0 1 2
  322. // 3
  323. float4x4 top = float4x4(
  324. _MainTex.SampleLevel(sampler_MainTex, UnityStereoTransformScreenSpaceTex(i.texcoord + float2(-k.x, -k.y)), 0),
  325. _MainTex.SampleLevel(sampler_MainTex, UnityStereoTransformScreenSpaceTex(i.texcoord + float2( 0.0, -k.y)), 0),
  326. _MainTex.SampleLevel(sampler_MainTex, UnityStereoTransformScreenSpaceTex(i.texcoord + float2( k.x, -k.y)), 0),
  327. _MainTex.SampleLevel(sampler_MainTex, UnityStereoTransformScreenSpaceTex(i.texcoord + float2(-k.x, 0.0)), 0)
  328. );
  329.  
  330. // 0
  331. // 1 2 3
  332. float4x4 bottom = float4x4(
  333. _MainTex.SampleLevel(sampler_MainTex, UnityStereoTransformScreenSpaceTex(i.texcoord + float2( k.x, 0.0)), 0),
  334. _MainTex.SampleLevel(sampler_MainTex, UnityStereoTransformScreenSpaceTex(i.texcoord + float2(-k.x, k.y)), 0),
  335. _MainTex.SampleLevel(sampler_MainTex, UnityStereoTransformScreenSpaceTex(i.texcoord + float2( 0.0, k.y)), 0),
  336. _MainTex.SampleLevel(sampler_MainTex, UnityStereoTransformScreenSpaceTex(i.texcoord + float2( k.x, k.y)), 0)
  337. );
  338.  
  339. // PS4 INTRINSIC_MINMAX3
  340. #if SHADER_API_PSSL
  341. float4 minimum = min3(min3(min3(min3(top[0], top[1], top[2]), top[3], bottom[0]), bottom[1], bottom[2]), bottom[3], color);
  342. float4 maximum = max3(max3(max3(max3(top[0], top[1], top[2]), top[3], bottom[0]), bottom[1], bottom[2]), bottom[3], color);
  343. #else
  344. float4 minimum = min(min(min(min(min(min(min(min(top[0], top[1]), top[2]), top[3]), bottom[0]), bottom[1]), bottom[2]), bottom[3]), color);
  345. float4 maximum = max(max(max(max(max(max(max(max(top[0], top[1]), top[2]), top[3]), bottom[0]), bottom[1]), bottom[2]), bottom[3]), color);
  346. #endif
  347.  
  348. float4 history = _History.SampleLevel(sampler_History, UnityStereoTransformScreenSpaceTex(uv), 0);
  349. history = clamp(history, minimum, maximum);
  350.  
  351. color.a = saturate(smoothstep(0.002 * _MainTex_TexelSize.z, 0.0035 * _MainTex_TexelSize.z, length(motion)));
  352.  
  353. float weight = clamp(lerp(SSR_FINAL_BLEND_STATIC_FACTOR, SSR_FINAL_BLEND_DYNAMIC_FACTOR,
  354. history.a * 100.0), SSR_FINAL_BLEND_DYNAMIC_FACTOR, SSR_FINAL_BLEND_STATIC_FACTOR);
  355.  
  356. color.a *= 0.85;
  357. return lerp(color, history, weight);
  358. }
  359.  
  360. float4 FragComposite(VaryingsDefault i) : SV_Target
  361. {
  362. float z = _CameraDepthTexture.SampleLevel(sampler_CameraDepthTexture, i.texcoordStereo, 0).r;
  363.  
  364. if (Linear01Depth(z) > 0.999)
  365. return _MainTex.Sample(sampler_MainTex, i.texcoordStereo);
  366.  
  367. float4 gbuffer0 = _CameraGBufferTexture0.Load(int3(i.vertex.xy, 0));
  368. float4 gbuffer1 = _CameraGBufferTexture1.Load(int3(i.vertex.xy, 0));
  369. float4 gbuffer2 = _CameraGBufferTexture2.Load(int3(i.vertex.xy, 0));
  370.  
  371. //Lux
  372. half materialIndex = GetLuxMaterialIndexFull(gbuffer2.a);
  373. float3 specColor = GetLuxSpecular(gbuffer1.rgb, gbuffer0, gbuffer2.b, materialIndex);
  374. //EndLux
  375.  
  376. float oneMinusReflectivity = 0.0;
  377. EnergyConservationBetweenDiffuseAndSpecular(gbuffer0.rgb, specColor, oneMinusReflectivity); // For Lux
  378. //EnergyConservationBetweenDiffuseAndSpecular(gbuffer0.rgb, gbuffer1.rgb, oneMinusReflectivity);
  379.  
  380. float3 normal = 2.0 * gbuffer2.rgb - 1.0;
  381. float3 position = GetViewSpacePosition(i.texcoord);
  382.  
  383. float3 eye = mul((float3x3)_InverseViewMatrix, normalize(position));
  384. position = mul(_InverseViewMatrix, float4(position, 1.0)).xyz;
  385.  
  386. #if SSR_ENABLE_CONTACTS
  387. float4 test = _Test.SampleLevel(sampler_Test, i.texcoordStereo, 0);
  388. float4 resolve = _Resolve.SampleLevel(sampler_Resolve, i.texcoordStereo, SmoothnessToRoughness(gbuffer1.a) * (_BlurPyramidLODCount - 1.0) * test.z + 1.0);
  389. #else
  390. float4 resolve = _Resolve.SampleLevel(sampler_Resolve, i.texcoordStereo, SmoothnessToRoughness(gbuffer1.a) * (_BlurPyramidLODCount - 1.0) + 1.0);
  391. #endif
  392.  
  393. float confidence = saturate(2.0 * dot(-eye, normalize(reflect(-eye, normal))));
  394.  
  395. UnityLight light;
  396. light.color = 0.0;
  397. light.dir = 0.0;
  398. light.ndotl = 0.0;
  399.  
  400. UnityIndirect indirect;
  401. indirect.diffuse = 0.0;
  402. indirect.specular = resolve.rgb;
  403.  
  404. resolve.rgb = UNITY_BRDF_PBS(gbuffer0.rgb, specColor, oneMinusReflectivity, gbuffer1.a, normal, -eye, light, indirect).rgb; // for Lux
  405. //resolve.rgb = UNITY_BRDF_PBS(gbuffer0.rgb, gbuffer1.rgb, oneMinusReflectivity, gbuffer1.a, normal, -eye, light, indirect).rgb;
  406.  
  407. float4 reflectionProbes = _CameraReflectionsTexture.Sample(sampler_CameraReflectionsTexture, i.texcoordStereo);
  408.  
  409. float4 color = _MainTex.Sample(sampler_MainTex, i.texcoordStereo);
  410. color.rgb = max(0.0, color.rgb - reflectionProbes.rgb);
  411.  
  412. resolve.a *= 2. * resolve.a; // 2 and 1.5 are quite important for the correct ratio of 3:2 distribution
  413. float fade = 1.0 - saturate(1.5 * resolve.a * smoothstep(0.5, 1.0, 1.5 * resolve.a) * _DistanceFade);
  414.  
  415. resolve.rgb = lerp(reflectionProbes.rgb, resolve.rgb, confidence * fade);
  416. color.rgb += resolve.rgb * gbuffer0.a;
  417.  
  418. return color;
  419. }
  420.  
  421. #endif // UNITY_POSTFX_SSR
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement