octDecode.glsl 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. /**
  2. * Decodes a unit-length vector in 'oct' encoding to a normalized 3-component Cartesian vector.
  3. * The 'oct' encoding is described in "A Survey of Efficient Representations of Independent Unit Vectors",
  4. * Cigolle et al 2014: http://jcgt.org/published/0003/02/01/
  5. *
  6. * @name czm_octDecode
  7. * @param {vec2} encoded The oct-encoded, unit-length vector
  8. * @param {float} range The maximum value of the SNORM range. The encoded vector is stored in log2(rangeMax+1) bits.
  9. * @returns {vec3} The decoded and normalized vector
  10. */
  11. vec3 czm_octDecode(vec2 encoded, float range)
  12. {
  13. if (encoded.x == 0.0 && encoded.y == 0.0) {
  14. return vec3(0.0, 0.0, 0.0);
  15. }
  16. encoded = encoded / range * 2.0 - 1.0;
  17. vec3 v = vec3(encoded.x, encoded.y, 1.0 - abs(encoded.x) - abs(encoded.y));
  18. if (v.z < 0.0)
  19. {
  20. v.xy = (1.0 - abs(v.yx)) * czm_signNotZero(v.xy);
  21. }
  22. return normalize(v);
  23. }
  24. /**
  25. * Decodes a unit-length vector in 'oct' encoding to a normalized 3-component Cartesian vector.
  26. * The 'oct' encoding is described in "A Survey of Efficient Representations of Independent Unit Vectors",
  27. * Cigolle et al 2014: http://jcgt.org/published/0003/02/01/
  28. *
  29. * @name czm_octDecode
  30. * @param {vec2} encoded The oct-encoded, unit-length vector
  31. * @returns {vec3} The decoded and normalized vector
  32. */
  33. vec3 czm_octDecode(vec2 encoded)
  34. {
  35. return czm_octDecode(encoded, 255.0);
  36. }
  37. /**
  38. * Decodes a unit-length vector in 'oct' encoding packed into a floating-point number to a normalized 3-component Cartesian vector.
  39. * The 'oct' encoding is described in "A Survey of Efficient Representations of Independent Unit Vectors",
  40. * Cigolle et al 2014: http://jcgt.org/published/0003/02/01/
  41. *
  42. * @name czm_octDecode
  43. * @param {float} encoded The oct-encoded, unit-length vector
  44. * @returns {vec3} The decoded and normalized vector
  45. */
  46. vec3 czm_octDecode(float encoded)
  47. {
  48. float temp = encoded / 256.0;
  49. float x = floor(temp);
  50. float y = (temp - x) * 256.0;
  51. return czm_octDecode(vec2(x, y));
  52. }
  53. /**
  54. * Decodes three unit-length vectors in 'oct' encoding packed into two floating-point numbers to normalized 3-component Cartesian vectors.
  55. * The 'oct' encoding is described in "A Survey of Efficient Representations of Independent Unit Vectors",
  56. * Cigolle et al 2014: http://jcgt.org/published/0003/02/01/
  57. *
  58. * @name czm_octDecode
  59. * @param {vec2} encoded The packed oct-encoded, unit-length vectors.
  60. * @param {vec3} vector1 One decoded and normalized vector.
  61. * @param {vec3} vector2 One decoded and normalized vector.
  62. * @param {vec3} vector3 One decoded and normalized vector.
  63. */
  64. void czm_octDecode(vec2 encoded, out vec3 vector1, out vec3 vector2, out vec3 vector3)
  65. {
  66. float temp = encoded.x / 65536.0;
  67. float x = floor(temp);
  68. float encodedFloat1 = (temp - x) * 65536.0;
  69. temp = encoded.y / 65536.0;
  70. float y = floor(temp);
  71. float encodedFloat2 = (temp - y) * 65536.0;
  72. vector1 = czm_octDecode(encodedFloat1);
  73. vector2 = czm_octDecode(encodedFloat2);
  74. vector3 = czm_octDecode(vec2(x, y));
  75. }