| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105 |
- // Copyright (C) 2009-2017, Panagiotis Christopoulos Charitos and contributors.
- // All rights reserved.
- // Code licensed under the BSD License.
- // http://www.anki3d.org/LICENSE
- // SSAO fragment shader
- #include "shaders/Common.glsl"
- #include "shaders/Pack.glsl"
- #include "shaders/Functions.glsl"
- const vec2 KERNEL[SAMPLES] = KERNEL_ARRAY; // This will be appended in C++
- const float BIAS = 0.2;
- const float STRENGTH = 1.1;
- layout(location = 0) in vec2 in_uv;
- layout(location = 0) out float out_color;
- layout(ANKI_UBO_BINDING(0, 0), std140, row_major) uniform _blk
- {
- vec4 u_unprojectionParams;
- vec4 u_projectionMat;
- };
- layout(ANKI_TEX_BINDING(0, 0)) uniform sampler2D u_mMsDepthRt;
- layout(ANKI_TEX_BINDING(0, 1)) uniform sampler2D u_msRt;
- layout(ANKI_TEX_BINDING(0, 2)) uniform sampler2DArray u_noiseMap;
- // Get normal
- vec3 readNormal(in vec2 uv)
- {
- vec3 normal;
- readNormalFromGBuffer(u_msRt, uv, normal);
- return normal;
- }
- // Read the noise tex
- float readRandom(in vec2 uv)
- {
- const vec2 tmp = vec2(float(WIDTH) / float(NOISE_MAP_SIZE), float(HEIGHT) / float(NOISE_MAP_SIZE));
- return texture(u_noiseMap, vec3(tmp * uv, 0.0)).r;
- }
- // Returns the Z of the position in view space
- float readZ(in vec2 uv)
- {
- float depth = texture(u_mMsDepthRt, uv).r;
- float z = u_unprojectionParams.z / (u_unprojectionParams.w + depth);
- return z;
- }
- // Read position in view space
- vec3 readPosition(in vec2 uv)
- {
- vec3 fragPosVspace;
- fragPosVspace.z = readZ(uv);
- fragPosVspace.xy = (2.0 * uv - 1.0) * u_unprojectionParams.xy * fragPosVspace.z;
- return fragPosVspace;
- }
- vec4 project(vec4 point)
- {
- return projectPerspective(point, u_projectionMat.x, u_projectionMat.y, u_projectionMat.z, u_projectionMat.w);
- }
- void main(void)
- {
- vec2 ndc = in_uv * 2.0 - 1.0;
- vec3 origin = readPosition(in_uv);
- vec3 normal = readNormal(in_uv);
- float randFactor = readRandom(in_uv);
- float randAng = randFactor * PI * 2.0;
- float cosAng = cos(randAng);
- float sinAng = sin(randAng);
- // Find the projected radius
- vec3 sphereLimit = origin + vec3(RADIUS, 0.0, 0.0);
- vec4 projSphereLimit = project(vec4(sphereLimit, 1.0));
- vec2 projSphereLimit2 = projSphereLimit.xy / projSphereLimit.w;
- float projRadius = length(projSphereLimit2 - ndc);
- // Integrate
- float factor = 0.0;
- for(uint i = 0U; i < SAMPLES; ++i)
- {
- // Rotate the disk point
- vec2 diskPoint = KERNEL[i] * projRadius;
- vec2 rotDiskPoint;
- rotDiskPoint.x = diskPoint.x * cosAng - diskPoint.y * sinAng;
- rotDiskPoint.y = diskPoint.y * cosAng + diskPoint.x * sinAng;
- vec2 finalDiskPoint = ndc + rotDiskPoint;
- vec3 s = readPosition(NDC_TO_UV(finalDiskPoint));
- vec3 u = s - origin;
- float f = max(dot(normal, u) + BIAS, 0.0) / max(dot(u, u), EPSILON);
- factor += f;
- }
- out_color = 1.0 - factor / float(SAMPLES) * STRENGTH;
- }
|