2
0

Pack.glsl 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. /// Pack 3D normal to 2D vector
  2. /// See the clean code in comments in revision < r467
  3. vec2 packNormal(in vec3 normal)
  4. {
  5. const float SCALE = 1.7777;
  6. float scalar1 = (normal.z + 1.0) * (SCALE * 2.0);
  7. return normal.xy / scalar1 + 0.5;
  8. }
  9. /// Reverse the packNormal
  10. vec3 unpackNormal(in vec2 enc)
  11. {
  12. const float SCALE = 1.7777;
  13. vec2 nn = enc * (2.0 * SCALE) - SCALE;
  14. float g = 2.0 / (dot(nn.xy, nn.xy) + 1.0);
  15. vec3 normal;
  16. normal.xy = g * nn.xy;
  17. normal.z = g - 1.0;
  18. return normal;
  19. }
  20. #if GL_ES || __VERSION__ < 400
  21. // Vectorized version. See clean one at <= r1048
  22. uint packUnorm4x8(in vec4 v)
  23. {
  24. vec4 a = clamp(v, 0.0, 1.0) * 255.0;
  25. uvec4 b = uvec4(a) << uvec4(0U, 8U, 16U, 24U);
  26. uvec2 c = b.xy | b.zw;
  27. return c.x | c.y;
  28. }
  29. // Vectorized version. See clean one at <= r1048
  30. vec4 unpackUnorm4x8(in highp uint u)
  31. {
  32. uvec4 a = uvec4(u) >> uvec4(0U, 8U, 16U, 24U);
  33. uvec4 b = a & uvec4(0xFFU);
  34. vec4 c = vec4(b);
  35. return c * (1.0 / 255.0);
  36. }
  37. #endif
  38. // If not defined fake it to stop some compilers from complaining
  39. #ifndef USE_MRT
  40. # define USE_MRT 1
  41. #endif
  42. #define MAX_SPECULARITY 128.0
  43. // Populate the G buffer
  44. void writeGBuffer(
  45. in vec3 diffColor, in vec3 normal, in float specColor, in float specPower,
  46. #if USE_MRT
  47. out vec4 fai0, out vec4 fai1
  48. #else
  49. out highp uvec2 fai0
  50. #endif
  51. )
  52. {
  53. vec3 unorm = normal * 0.5 + 0.5;
  54. #if USE_MRT
  55. fai0 = vec4(diffColor, specColor);
  56. fai1 = vec4(unorm.xyz, specPower / MAX_SPECULARITY);
  57. #else
  58. fai0.x = packUnorm4x8(vec4(diffColor, specColor));
  59. fai0.y = packUnorm4x8(vec4(unorm, specPower / MAX_SPECULARITY));
  60. #endif
  61. }
  62. // Read from the G buffer
  63. void readGBuffer(
  64. #if USE_MRT
  65. in sampler2D fai0, in sampler2D fai1,
  66. #else
  67. in highp usampler2D fai0,
  68. #endif
  69. in vec2 texCoord,
  70. out vec3 diffColor, out vec3 normal, out float specColor,
  71. out float specPower)
  72. {
  73. #if USE_MRT
  74. vec4 comp = textureFai(fai0, texCoord);
  75. diffColor = comp.rgb;
  76. specColor = comp.a;
  77. comp = textureFai(fai1, texCoord);
  78. normal = normalize(comp.xyz * 2.0 - 1.0);
  79. specPower = comp.w * MAX_SPECULARITY;
  80. #else
  81. highp uvec2 all_ = textureFai(fai0, texCoord).rg;
  82. vec4 v = unpackUnorm4x8(all_[0]);
  83. diffColor = v.rgb;
  84. specColor = v.a;
  85. v = unpackUnorm4x8(all_[1]);
  86. normal = normalize(v.xyz * 2.0 - 1.0);
  87. specPower = v.w * MAX_SPECULARITY;
  88. #endif
  89. }
  90. // Read only normal from G buffer
  91. void readNormalFromGBuffer(
  92. #if USE_MRT
  93. in sampler2D fai1,
  94. #else
  95. in highp usampler2D fai0,
  96. #endif
  97. in vec2 texCoord,
  98. out vec3 normal)
  99. {
  100. #if USE_MRT
  101. normal = normalize(textureFai(fai1, texCoord).xyz);
  102. #else
  103. vec4 v = unpackUnorm4x8(textureFai(fai0, texCoord).g);
  104. normal = normalize(v.xyz * 2.0 - 1.0);
  105. #endif
  106. }