|
|
@@ -4,89 +4,103 @@
|
|
|
|
|
|
#pragma anki fragShaderBegins
|
|
|
|
|
|
-#pragma anki include "shaders/LinearDepth.glsl"
|
|
|
#pragma anki include "shaders/Pack.glsl"
|
|
|
|
|
|
-uniform vec2 camerarange; // = vec2( znear, zfar )
|
|
|
-uniform sampler2D msDepthFai;
|
|
|
-uniform sampler2D noiseMap;
|
|
|
-uniform sampler2D msNormalFai;
|
|
|
+/// @name Uniforms
|
|
|
+/// @{
|
|
|
+uniform vec2 planes; ///< for the calculation of frag pos in view space
|
|
|
+uniform vec2 limitsOfNearPlane; ///< for the calculation of frag pos in view space
|
|
|
+uniform float zNear; ///< for the calculation of frag pos in view space
|
|
|
+uniform sampler2D msDepthFai; ///< for the calculation of frag pos in view space
|
|
|
|
|
|
-in vec2 vTexCoords;
|
|
|
-
|
|
|
-layout(location = 0) out float fFragColor;
|
|
|
+uniform sampler2D noiseMap; /// Used in getRandom
|
|
|
+uniform float noiseMapSize = 100.0; /// Used in getRandom
|
|
|
+uniform vec2 screenSize; /// Used in getRandom
|
|
|
|
|
|
-const float totStrength = 1.3;
|
|
|
-const float strength = 0.07;
|
|
|
-const float offset = 18.0;
|
|
|
-const float falloff = 0.000002;
|
|
|
-const float rad = 0.006;
|
|
|
-const int SAMPLES = 16; // 10 is good
|
|
|
-const float invSamples = 1.0/float(SAMPLES);
|
|
|
+uniform sampler2D msNormalFai; /// Used in getNormal
|
|
|
+/// @}
|
|
|
|
|
|
-const float MAX_SSAO_DISTANCE = 40.0;
|
|
|
+/// @name Varyings
|
|
|
+/// @{
|
|
|
+in vec2 vTexCoords;
|
|
|
+/// @}
|
|
|
|
|
|
-void main(void)
|
|
|
-{
|
|
|
- // these are the random vectors inside a unit sphere
|
|
|
- const vec3 pSphere[16] = vec3[](vec3(0.53812504, 0.18565957, -0.43192),vec3(0.13790712, 0.24864247, 0.44301823),vec3(0.33715037, 0.56794053, -0.005789503),vec3(-0.6999805, -0.04511441, -0.0019965635),vec3(0.06896307, -0.15983082, -0.85477847),vec3(0.056099437, 0.006954967, -0.1843352),vec3(-0.014653638, 0.14027752, 0.0762037),vec3(0.010019933, -0.1924225, -0.034443386),vec3(-0.35775623, -0.5301969, -0.43581226),vec3(-0.3169221, 0.106360726, 0.015860917),vec3(0.010350345, -0.58698344, 0.0046293875),vec3(-0.08972908, -0.49408212, 0.3287904),vec3(0.7119986, -0.0154690035, -0.09183723),vec3(-0.053382345, 0.059675813, -0.5411899),vec3(0.035267662, -0.063188605, 0.54602677),vec3(-0.47761092, 0.2847911, -0.0271716));
|
|
|
- //const vec3 pSphere[8] = vec3[](vec3(0.24710192, 0.6445882, 0.033550154),vec3(0.00991752, -0.21947019, 0.7196721),vec3(0.25109035, -0.1787317, -0.011580509),vec3(-0.08781511, 0.44514698, 0.56647956),vec3(-0.011737816, -0.0643377, 0.16030222),vec3(0.035941467, 0.04990871, -0.46533614),vec3(-0.058801126, 0.7347013, -0.25399926),vec3(-0.24799341, -0.022052078, -0.13399573));
|
|
|
- //const vec3 pSphere[12] = vec3[](vec3(-0.13657719, 0.30651027, 0.16118456),vec3(-0.14714938, 0.33245975, -0.113095455),vec3(0.030659059, 0.27887347, -0.7332209),vec3(0.009913514, -0.89884496, 0.07381549),vec3(0.040318526, 0.40091, 0.6847858),vec3(0.22311053, -0.3039437, -0.19340435),vec3(0.36235332, 0.21894878, -0.05407306),vec3(-0.15198798, -0.38409665, -0.46785462),vec3(-0.013492276, -0.5345803, 0.11307949),vec3(-0.4972847, 0.037064247, -0.4381323),vec3(-0.024175806, -0.008928787, 0.17719103),vec3(0.694014, -0.122672155, 0.33098832));
|
|
|
- //const vec3 pSphere[10] = vec3[](vec3(-0.010735935, 0.01647018, 0.0062425877),vec3(-0.06533369, 0.3647007, -0.13746321),vec3(-0.6539235, -0.016726388, -0.53000957),vec3(0.40958285, 0.0052428036, -0.5591124),vec3(-0.1465366, 0.09899267, 0.15571679),vec3(-0.44122112, -0.5458797, 0.04912532),vec3(0.03755566, -0.10961345, -0.33040273),vec3(0.019100213, 0.29652783, 0.066237666),vec3(0.8765323, 0.011236004, 0.28265962),vec3(0.29264435, -0.40794238, 0.15964167));
|
|
|
- // grab a normal for reflecting the sample rays later on
|
|
|
+/// @name Output
|
|
|
+/// @{
|
|
|
+layout(location = 0) out float fColor;
|
|
|
+/// @}
|
|
|
|
|
|
|
|
|
- float currentPixelDepth = readFromTexAndLinearizeDepth( msDepthFai, vTexCoords, camerarange.x, camerarange.y );
|
|
|
+/// @name Consts
|
|
|
+/// @{
|
|
|
+uniform float SAMPLE_RAD = 0.1; /// Used in main
|
|
|
+uniform float SCALE = 1.0; /// Used in doAmbientOcclusion
|
|
|
+uniform float INTENSITY = 3.0; /// Used in doAmbientOcclusion
|
|
|
+uniform float BIAS = 0.00; /// Used in doAmbientOcclusion
|
|
|
+/// @}
|
|
|
|
|
|
- /*if( currentPixelDepth * camerarange.y > MAX_SSAO_DISTANCE )
|
|
|
- {
|
|
|
- gl_FragColor.a = 1.0;
|
|
|
- return;
|
|
|
- }*/
|
|
|
|
|
|
- vec3 fres = normalize((texture2D(noiseMap,vTexCoords*offset).xyz*2.0) - vec3(1.0));
|
|
|
+/// globals: msNormalFai
|
|
|
+vec3 getNormal(in vec2 uv)
|
|
|
+{
|
|
|
+ return unpackNormal(texture2D(msNormalFai, uv).rg);
|
|
|
+}
|
|
|
|
|
|
- vec4 currentPixelSample = texture2D(msNormalFai,vTexCoords);
|
|
|
|
|
|
+/// globals: noiseMap, screenSize, noiseMapSize
|
|
|
+vec2 getRandom(in vec2 uv)
|
|
|
+{
|
|
|
+ return normalize(texture2D(noiseMap, screenSize * uv / noiseMapSize).xy * 2.0 - 1.0);
|
|
|
+}
|
|
|
|
|
|
|
|
|
- // current fragment coords in screen space
|
|
|
- vec3 ep = vec3( vTexCoords.xy, currentPixelDepth );
|
|
|
- // get the normal of current fragment
|
|
|
- vec3 norm = unpackNormal(currentPixelSample.xy);
|
|
|
+/// Get frag position in view space
|
|
|
+/// globals: msDepthFai, planes, zNear, limitsOfNearPlane
|
|
|
+vec3 getPosition(in vec2 uv)
|
|
|
+{
|
|
|
+ float depth = texture2D(msDepthFai, uv).r;
|
|
|
|
|
|
- float bl = 0.0;
|
|
|
- // adjust for the depth ( not shure if this is good..)
|
|
|
- float radD = rad/currentPixelDepth;
|
|
|
+ vec3 fragPosVspace;
|
|
|
+ fragPosVspace.z = -planes.y / (planes.x + depth);
|
|
|
+
|
|
|
+ fragPosVspace.xy = (((uv) * 2.0) - 1.0) * limitsOfNearPlane;
|
|
|
+
|
|
|
+ float sc = -fragPosVspace.z / zNear;
|
|
|
+ fragPosVspace.xy *= sc;
|
|
|
|
|
|
- vec3 ray, se, occNorm;
|
|
|
- float occluderDepth, depthDifference, normDiff;
|
|
|
+ return fragPosVspace;
|
|
|
+}
|
|
|
|
|
|
- for(int i=0; i<SAMPLES; ++i)
|
|
|
- {
|
|
|
- // get a vector (randomized inside of a sphere with radius 1.0) from a texture and reflect it
|
|
|
- ray = radD*reflect(pSphere[i],fres);
|
|
|
+/// Calculate the ambient occlusion factor
|
|
|
+float doAmbientOcclusion(in vec2 tcoord, in vec2 uv, in vec3 original, in vec3 cnorm)
|
|
|
+{
|
|
|
+ vec3 newp = getPosition(tcoord + uv);
|
|
|
+ vec3 diff = newp - original;
|
|
|
+ vec3 v = normalize(diff);
|
|
|
+ float d = length(diff) /* * SCALE*/;
|
|
|
|
|
|
- // if the ray is outside the hemisphere then change direction
|
|
|
- se = ep + sign(dot(ray,norm) )*ray;
|
|
|
+ float ret = max(0.0, dot(cnorm, v) /* - BIAS*/) * (INTENSITY / (1.0 + d));
|
|
|
+ return ret;
|
|
|
+}
|
|
|
|
|
|
- // get the depth of the occluder fragment
|
|
|
- vec4 occluderFragment = texture2D(msNormalFai,se.xy);
|
|
|
|
|
|
- // get the normal of the occluder fragment
|
|
|
- occNorm = unpackNormal(occluderFragment.xy);
|
|
|
+void main(void)
|
|
|
+{
|
|
|
+ const vec2 KERNEL[16] = vec2[](vec2(0.53812504, 0.18565957), vec2(0.13790712, 0.24864247), vec2(0.33715037, 0.56794053), vec2(-0.6999805, -0.04511441), vec2(0.06896307, -0.15983082), vec2(0.056099437, 0.006954967), vec2(-0.014653638, 0.14027752), vec2(0.010019933, -0.1924225), vec2(-0.35775623, -0.5301969), vec2(-0.3169221, 0.106360726), vec2(0.010350345, -0.58698344), vec2(-0.08972908, -0.49408212), vec2(0.7119986, -0.0154690035), vec2(-0.053382345, 0.059675813), vec2(0.035267662, -0.063188605), vec2(-0.47761092, 0.2847911));
|
|
|
|
|
|
- // if depthDifference is negative = occluder is behind current fragment
|
|
|
- depthDifference = currentPixelDepth - readFromTexAndLinearizeDepth( msDepthFai, se.xy, camerarange.x, camerarange.y );;
|
|
|
+ vec3 p = getPosition(vTexCoords);
|
|
|
+ vec3 n = getNormal(vTexCoords);
|
|
|
+ vec2 rand = getRandom(vTexCoords);
|
|
|
|
|
|
- // calculate the difference between the normals as a weight
|
|
|
+ fColor = 0.0;
|
|
|
|
|
|
- normDiff = (1.0-dot(occNorm,norm));
|
|
|
- // the falloff equation, starts at falloff and is kind of 1/x^2 falling
|
|
|
- bl += step(falloff,depthDifference)*normDiff*(1.0-smoothstep(falloff,strength,depthDifference));
|
|
|
+ const int ITERATIONS = 16;
|
|
|
+ for(int j = 0; j < ITERATIONS; ++j)
|
|
|
+ {
|
|
|
+ vec2 coord = reflect(KERNEL[j], rand) * SAMPLE_RAD;
|
|
|
+ fColor += doAmbientOcclusion(vTexCoords, coord, p, n);
|
|
|
}
|
|
|
|
|
|
- // output the result
|
|
|
- float ao = 1.0-totStrength*bl*invSamples;
|
|
|
- fFragColor = ao /** MAX_SSAO_DISTANCE*/;
|
|
|
+ fColor = 1.0 - fColor / ITERATIONS;
|
|
|
}
|
|
|
+
|