| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155 |
- #version 330 core
- //https://developer.download.nvidia.com/presentations/2008/SIGGRAPH/HBAO_SIG08b.pdf
- out float fragColor;
- noperspective in highp vec2 v_texCoords;
- uniform sampler2D u_gPosition;
- uniform isampler2D u_gNormal;
- uniform sampler2D u_texNoise;
- uniform mat4 u_projection; // camera projection matrix
- uniform mat4 u_view; // camera view matrix
- const float INFINITY = 1.f/0.f;
- vec3 fromuShortToFloat(ivec3 a)
- {
- vec3 ret = a;
- //[0 65536] -> [0 1]
- ret /= 65536;
- //[0 1] -> [0 2]
- ret *= 2.f;
- //[0 2] -> [-1 1]
- ret -= 1.f;
- return normalize(ret);
- }
- float saturate(float a)
- {
- return min(max(a,0),1);
- }
- vec2 computeAO(vec3 normal, vec2 direction, vec2 screenSize, vec3 fragPos)
- {
- float RAD = 0.05;
- float RAD_FOR_DIRECTION = length( direction*vec2(10.0) / (vec2(abs(fragPos.z))*screenSize));
- vec3 viewVector = normalize(fragPos);
- vec3 leftDirection = cross(viewVector, vec3(direction,0));
- vec3 projectedNormal = normal - dot(leftDirection, normal) * leftDirection;
- float projectedLen = length(projectedNormal);
- projectedNormal /= projectedLen;
- vec3 tangent = cross(projectedNormal, leftDirection);
- //vec3 leftDirection = cross(normal, vec3(direction, 0));
- //vec3 tangent = normalize( cross(leftDirection, normal) );
- const float bias = (3.141592/360)*20.f;
- float tangentAngle = atan(tangent.z / length(tangent.xy));
- float sinTangentAngle = sin(tangentAngle + bias);
-
- //
- vec2 texelSize = vec2(1.f,1.f) / screenSize;
- float highestZ = -INFINITY;
- vec3 foundPos = vec3(0,0,-INFINITY);
-
- for(int i=2; i<=10; i++)
- {
- vec2 marchPosition = v_texCoords + i*texelSize*direction;
-
- vec3 fragPosMarch = texture(u_gPosition, marchPosition).xyz;
-
- vec3 hVector = normalize(fragPosMarch-fragPos); //inspre origine
- float rangeCheck = 1 - saturate(length(fragPosMarch-fragPos) / RAD-1);
- //hVector.z = mix(hVector.z, fragPos.z-RAD*2, rangeCheck);
- if(hVector.z > highestZ && length(fragPosMarch-fragPos) < RAD)
- {
- highestZ = hVector.z;
- foundPos = fragPosMarch;
- }
- }
- //float rangeCheck = smoothstep(0.0, 1.0, 10*length(screenSize) / length(foundPos - fragPos));
- //if(length(foundPos - fragPos) > length(screenSize)*10){rangeCheck=0;}
- //vec3 foundPos = vec3(0,0,-INFINITY);
- //float longest = -INFINITY;
- //for(int i=1; i<=10; i++)
- //{
- // vec2 marchPosition = v_texCoords + i*texelSize*direction;
- //
- // vec3 fragPosMarch = texture(u_gPosition, marchPosition).xyz;
- //
- // //find distance to tangent
- // vec3 fragPosNormal = normalize(fragPosMarch);
- // float dist = length(tangent-fragPosNormal);
- //
- // if(dist > longest && length(fragPosMarch-fragPos) < length(i*texelSize)*abs(fragPos.z)*2)
- // {
- // dist = longest;
- // foundPos = fragPosMarch;
- // }
- //}
- vec3 horizonVector = (foundPos - fragPos);
- float horizonAngle = atan(horizonVector.z/length(horizonVector.xy));
-
- float sinHorizonAngle = sin(horizonAngle);
- vec2 rez = vec2(saturate((sinHorizonAngle - sinTangentAngle))/2, projectedLen);
- return rez;
- }
- void main()
- {
- vec2 screenSize = textureSize(u_gPosition, 0).xy/2.f; //smaller rez
- vec2 noiseScale = vec2(screenSize.x/4.0, screenSize.y/4.0);
- vec2 noisePos = v_texCoords * noiseScale;
- vec3 fragPos = texture(u_gPosition, v_texCoords).xyz; //view space
- if(fragPos.z == -INFINITY){fragColor = 1; return;}
- vec3 normal = normalize( vec3(
- transpose(inverse(mat3(u_view))) *
- fromuShortToFloat(texture(u_gNormal, v_texCoords).xyz)
- ));
- //vec2 randomVec = normalize(texture2D(u_texNoise, noisePos).xy);
- vec2 randomVec = vec2(0,1);
- vec2 rez = vec2(0,0);
- vec3 viewVector = normalize(fragPos);
- rez += computeAO(normal, vec2(randomVec), screenSize, fragPos);
- rez += computeAO(normal, -vec2(randomVec), screenSize, fragPos);
- rez += computeAO(normal, vec2(-randomVec.y,randomVec.x), screenSize, fragPos);
- rez += computeAO(normal, vec2(randomVec.y, -randomVec.x), screenSize, fragPos);
-
- rez.x /= rez.y;
-
- fragColor = 1.f - rez.x;
- }
|