hbao_optimized.frag 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. #version 330 core
  2. //https://developer.download.nvidia.com/presentations/2008/SIGGRAPH/HBAO_SIG08b.pdf
  3. out float fragColor;
  4. noperspective in highp vec2 v_texCoords;
  5. uniform sampler2D u_gPosition;
  6. uniform isampler2D u_gNormal;
  7. uniform sampler2D u_texNoise;
  8. uniform mat4 u_projection; // camera projection matrix
  9. uniform mat4 u_view; // camera view matrix
  10. const float INFINITY = 1.f/0.f;
  11. vec3 fromuShortToFloat(ivec3 a)
  12. {
  13. vec3 ret = a;
  14. //[0 65536] -> [0 1]
  15. ret /= 65536;
  16. //[0 1] -> [0 2]
  17. ret *= 2.f;
  18. //[0 2] -> [-1 1]
  19. ret -= 1.f;
  20. return normalize(ret);
  21. }
  22. float saturate(float a)
  23. {
  24. return min(max(a,0),1);
  25. }
  26. vec2 computeAO(vec3 normal, vec2 direction, vec2 screenSize, vec3 fragPos)
  27. {
  28. float RAD = 0.05;
  29. float RAD_FOR_DIRECTION = length( direction*vec2(10.0) / (vec2(abs(fragPos.z))*screenSize));
  30. vec3 viewVector = normalize(fragPos);
  31. vec3 leftDirection = cross(viewVector, vec3(direction,0));
  32. vec3 projectedNormal = normal - dot(leftDirection, normal) * leftDirection;
  33. float projectedLen = length(projectedNormal);
  34. projectedNormal /= projectedLen;
  35. vec3 tangent = cross(projectedNormal, leftDirection);
  36. //vec3 leftDirection = cross(normal, vec3(direction, 0));
  37. //vec3 tangent = normalize( cross(leftDirection, normal) );
  38. const float bias = (3.141592/360)*20.f;
  39. float tangentAngle = atan(tangent.z / length(tangent.xy));
  40. float sinTangentAngle = sin(tangentAngle + bias);
  41. //
  42. vec2 texelSize = vec2(1.f,1.f) / screenSize;
  43. float highestZ = -INFINITY;
  44. vec3 foundPos = vec3(0,0,-INFINITY);
  45. for(int i=2; i<=10; i++)
  46. {
  47. vec2 marchPosition = v_texCoords + i*texelSize*direction;
  48. vec3 fragPosMarch = texture(u_gPosition, marchPosition).xyz;
  49. vec3 hVector = normalize(fragPosMarch-fragPos); //inspre origine
  50. float rangeCheck = 1 - saturate(length(fragPosMarch-fragPos) / RAD-1);
  51. //hVector.z = mix(hVector.z, fragPos.z-RAD*2, rangeCheck);
  52. if(hVector.z > highestZ && length(fragPosMarch-fragPos) < RAD)
  53. {
  54. highestZ = hVector.z;
  55. foundPos = fragPosMarch;
  56. }
  57. }
  58. //float rangeCheck = smoothstep(0.0, 1.0, 10*length(screenSize) / length(foundPos - fragPos));
  59. //if(length(foundPos - fragPos) > length(screenSize)*10){rangeCheck=0;}
  60. //vec3 foundPos = vec3(0,0,-INFINITY);
  61. //float longest = -INFINITY;
  62. //for(int i=1; i<=10; i++)
  63. //{
  64. // vec2 marchPosition = v_texCoords + i*texelSize*direction;
  65. //
  66. // vec3 fragPosMarch = texture(u_gPosition, marchPosition).xyz;
  67. //
  68. // //find distance to tangent
  69. // vec3 fragPosNormal = normalize(fragPosMarch);
  70. // float dist = length(tangent-fragPosNormal);
  71. //
  72. // if(dist > longest && length(fragPosMarch-fragPos) < length(i*texelSize)*abs(fragPos.z)*2)
  73. // {
  74. // dist = longest;
  75. // foundPos = fragPosMarch;
  76. // }
  77. //}
  78. vec3 horizonVector = (foundPos - fragPos);
  79. float horizonAngle = atan(horizonVector.z/length(horizonVector.xy));
  80. float sinHorizonAngle = sin(horizonAngle);
  81. vec2 rez = vec2(saturate((sinHorizonAngle - sinTangentAngle))/2, projectedLen);
  82. return rez;
  83. }
  84. void main()
  85. {
  86. vec2 screenSize = textureSize(u_gPosition, 0).xy/2.f; //smaller rez
  87. vec2 noiseScale = vec2(screenSize.x/4.0, screenSize.y/4.0);
  88. vec2 noisePos = v_texCoords * noiseScale;
  89. vec3 fragPos = texture(u_gPosition, v_texCoords).xyz; //view space
  90. if(fragPos.z == -INFINITY){fragColor = 1; return;}
  91. vec3 normal = normalize( vec3(
  92. transpose(inverse(mat3(u_view))) *
  93. fromuShortToFloat(texture(u_gNormal, v_texCoords).xyz)
  94. ));
  95. //vec2 randomVec = normalize(texture2D(u_texNoise, noisePos).xy);
  96. vec2 randomVec = vec2(0,1);
  97. vec2 rez = vec2(0,0);
  98. vec3 viewVector = normalize(fragPos);
  99. rez += computeAO(normal, vec2(randomVec), screenSize, fragPos);
  100. rez += computeAO(normal, -vec2(randomVec), screenSize, fragPos);
  101. rez += computeAO(normal, vec2(-randomVec.y,randomVec.x), screenSize, fragPos);
  102. rez += computeAO(normal, vec2(randomVec.y, -randomVec.x), screenSize, fragPos);
  103. rez.x /= rez.y;
  104. fragColor = 1.f - rez.x;
  105. }