Hello all,
I've recently ported over some Alchemy AO code to glsl into my engine and get decent results:
[attachment=17995:giboxao1.png][attachment=17996:giboxao2.png]
The only issue seems to be the thin black edge around each object, which is exactly 1 pixel thick. Does anyone who has implemented Alchemy AO know what the cause of it is and how I can minimize it?
Here's my code:
const vec2 focalLength = vec2(1.0/tan(45.0*0.5)*screenRes.y/screenRes.x,1.0/tan(45.0*0.5));
float linearDepth(float d, float near, float far)
{
d = d*2.0 - 1.0;
vec2 lin = vec2((near-far)/(2.0*near*far),(near+far)/(2.0*near*far));
return -1.0/(lin.x*d+lin.y);
}
vec3 UVtoViewSpace(vec2 uv, float z)
{
vec2 UVtoViewA = vec2(-2.0/focalLength.x,-2.0/focalLength.y);
vec2 UVtoViewB = vec2(1.0/focalLength.x,1.0/focalLength.y);
uv = UVtoViewA*uv + UVtoViewB;
return vec3(uv*z,z);
}
vec3 GetViewPos(vec2 uv)
{
float z = linearDepth(texture(depthTex, uv).r,0.1,100.0);
return UVtoViewSpace(uv, z);
}
vec2 RotateDir(vec2 dir, vec2 cosSin)
{
return vec2(dir.x*cosSin.x - dir.y*cosSin.y, dir.x*cosSin.y + dir.y*cosSin.x);
}
vec2 tapLocation(int sampleNumber, float spinAngle, out float ssR)
{
float alpha = float(sampleNumber + 0.5) * (1.0 / NUM_SAMPLES);
float angle = alpha * (NUM_SPIRAL_TURNS * 6.28) + spinAngle;
ssR = alpha;
return vec2(cos(angle), sin(angle));
}
void main()
{
float ao = 0.0;
float aoRad = 0.5;
float aoBias = 0.002;
vec2 aoTexCoord = gl_FragCoord.xy/vec2(screenRes.x,screenRes.y);
vec2 aoRes = vec2(screenRes.x,screenRes.y);
vec3 aoRand = texture(aoRandTex, aoTexCoord*aoRes/1).xyz;
vec3 aoC = GetViewPos(aoTexCoord);
vec3 aoN_C = normalize(cross(dFdx(aoC),dFdy(aoC)));
float uvDiskRadius = 0.5*focalLength.y*aoRad/aoC.z;
vec2 pixelPosC = gl_FragCoord.xy;
pixelPosC.y = screenRes.y-pixelPosC.y;
float randPatternRotAngle = (3*int(pixelPosC.x)^int(pixelPosC.y)+int(pixelPosC.x)*int(pixelPosC.y))*10.0;
float aoAlpha = 2.0*pi/NUM_SAMPLES + randPatternRotAngle;
for(int i = 0; i < NUM_SAMPLES; ++i)
{
float ssR;
vec2 aoUnitOffset = tapLocation(i, randPatternRotAngle, ssR);
ssR *= uvDiskRadius;
vec2 aoTexS = aoTexCoord + ssR*aoUnitOffset;
vec3 aoQ = GetViewPos(aoTexS);
vec3 aoV = aoQ - aoC;
float aoVv = dot(aoV,aoV);
float aoVn = dot(aoV, aoN_C);
float aoEp = 0.01;
float aoF = max(aoRad*aoRad - aoVv, 0.0);
ao += aoF*aoF*aoF*max((aoVn - aoBias)/(aoEp+aoVv),0.0);
}
float aoTemp = aoRad*aoRad*aoRad;
ao /= aoTemp*aoTemp;
ao = max(0.0,1.0 - ao*(1.0/NUM_SAMPLES));
color = vec4(vec3(ao),1);
}