1
2#define EPSILON 0.00001
3
4#define CAVITY_BUFFER_RANGE 4.0
5
6#ifdef WORKBENCH_ENCODE_NORMALS
7
8#  define WB_Normal vec2
9
10/* From http://aras-p.info/texts/CompactNormalStorage.html
11 * Using Method #4: Spheremap Transform */
12vec3 workbench_normal_decode(vec4 enc)
13{
14  vec2 fenc = enc.xy * 4.0 - 2.0;
15  float f = dot(fenc, fenc);
16  float g = sqrt(1.0 - f / 4.0);
17  vec3 n;
18  n.xy = fenc * g;
19  n.z = 1 - f / 2;
20  return n;
21}
22
23/* From http://aras-p.info/texts/CompactNormalStorage.html
24 * Using Method #4: Spheremap Transform */
25WB_Normal workbench_normal_encode(bool front_face, vec3 n)
26{
27  n = normalize(front_face ? n : -n);
28  float p = sqrt(n.z * 8.0 + 8.0);
29  n.xy = clamp(n.xy / p + 0.5, 0.0, 1.0);
30  return n.xy;
31}
32
33#else
34#  define WB_Normal vec3
35/* Well just do nothing... */
36#  define workbench_normal_encode(f, a) (a)
37#  define workbench_normal_decode(a) (a.xyz)
38#endif /* WORKBENCH_ENCODE_NORMALS */
39
40/* Encoding into the alpha of a RGBA16F texture. (10bit mantissa) */
41#define TARGET_BITCOUNT 8u
42#define METALLIC_BITS 3u /* Metallic channel is less important. */
43#define ROUGHNESS_BITS (TARGET_BITCOUNT - METALLIC_BITS)
44
45/* Encode 2 float into 1 with the desired precision. */
46float workbench_float_pair_encode(float v1, float v2)
47{
48  // const uint v1_mask = ~(0xFFFFFFFFu << ROUGHNESS_BITS);
49  // const uint v2_mask = ~(0xFFFFFFFFu << METALLIC_BITS);
50  /* Same as above because some compiler are very dumb and think we use medium int. */
51  const int v1_mask = 0x1F;
52  const int v2_mask = 0x7;
53  int iv1 = int(v1 * float(v1_mask));
54  int iv2 = int(v2 * float(v2_mask)) << int(ROUGHNESS_BITS);
55  return float(iv1 | iv2);
56}
57
58void workbench_float_pair_decode(float data, out float v1, out float v2)
59{
60  // const uint v1_mask = ~(0xFFFFFFFFu << ROUGHNESS_BITS);
61  // const uint v2_mask = ~(0xFFFFFFFFu << METALLIC_BITS);
62  /* Same as above because some compiler are very dumb and think we use medium int.  */
63  const int v1_mask = 0x1F;
64  const int v2_mask = 0x7;
65  int idata = int(data);
66  v1 = float(idata & v1_mask) * (1.0 / float(v1_mask));
67  v2 = float(idata >> int(ROUGHNESS_BITS)) * (1.0 / float(v2_mask));
68}
69