1
0
Fork 0
fgdata/Shaders/HDR/ao.frag

72 lines
2 KiB
GLSL
Raw Normal View History

2021-04-10 09:14:16 +00:00
#version 330 core
#pragma optionNV (unroll all)
out float fragColor;
in vec2 texCoord;
uniform sampler2D depth_tex;
uniform sampler2D normal_tex;
uniform mat4 fg_ProjectionMatrix;
const float RADIUS = 0.04;
const float BIAS = 0.05;
const float SCALE = 3.0;
const float MAX_DISTANCE = 0.08;
const float INTENSITY = 1.5;
const vec2 kernel[4] = vec2[](
vec2( 0.0, 1.0), // top
vec2( 1.0, 0.0), // right
vec2( 0.0, -1.0), // bottom
vec2(-1.0, 0.0)); // left
vec3 positionFromDepth(vec2 pos, float depth);
vec3 decodeNormal(vec2 enc);
float rand(vec2 co) {
return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
}
float sampleAO(vec3 fragPos, vec3 normal, vec2 coords)
{
float sampleDepth = texture(depth_tex, coords).r * 2.0 - 1.0;
vec3 samplePoint = positionFromDepth(coords * 2.0 - 1.0, sampleDepth);
vec3 diff = samplePoint - fragPos;
float l = length(diff);
vec3 v = diff / l;
float d = l * SCALE;
float ao = max(0.0, dot(normal, v) - BIAS) * (1.0 / (1.0 + d));
ao *= smoothstep(MAX_DISTANCE, MAX_DISTANCE * 0.5, l);
return ao;
}
void main()
{
float fragDepth = texture(depth_tex, texCoord).r;
vec3 fragPos = positionFromDepth(texCoord * 2.0 - 1.0, fragDepth * 2.0 - 1.0);
vec3 normal = normalize(decodeNormal(texture(normal_tex, texCoord).rg));
vec2 randomVec = normalize(vec2(rand(texCoord) * 2.0 - 1.0,
rand(texCoord+1.0) * 2.0 - 1.0));
const float sin45 = 0.707107;
float occlusion = 0.0;
for (int i = 0; i < 4; ++i) {
vec2 k1 = reflect(kernel[i], randomVec) * RADIUS;
vec2 k2 = vec2(k1.x * sin45 - k1.y * sin45, k1.x * sin45 + k1.y * sin45);
occlusion += sampleAO(fragPos, normal, texCoord + k1);
occlusion += sampleAO(fragPos, normal, texCoord + k2 * 0.75);
occlusion += sampleAO(fragPos, normal, texCoord + k1 * 0.5);
occlusion += sampleAO(fragPos, normal, texCoord + k2 * 0.25);
}
occlusion /= 16.0;
fragColor = clamp(1.0 - occlusion * INTENSITY, 0.0, 1.0);
}