Hi, I am learning ssao from your excellent library. But I am confused about your clipW calculation. Here is the snippet from ssao/shader.frag:
vec3 getViewPosition(const in vec2 screenPosition, const in float depth, const in float viewZ) {
float clipW = projectionMatrix[2][3] * viewZ + projectionMatrix[3][3];
vec4 clipPosition = vec4((vec3(screenPosition, depth) - 0.5) * 2.0, 1.0);
clipPosition *= clipW; // Unproject.
return (inverseProjectionMatrix * clipPosition).xyz;
}
The clipW is calculated by Az+B. But in OpenGL Projection Matrix, the projection matrix is:

The Az+B should be clipZ not clipW and the clipW should be -z.
What is the magic in your code ?
Thanks.
The getViewPosition function comes from the original SAOPass which probably copied it from the SSAOPass. I didn't come up with the math, but I agree that it seems a bit strange.
WebGL uses column-major matrices, so projectionMatrix[2][3] is actually -1.0 and projectionMatrix[3][3] is 0.0, so clipW is -viewZ. This code probably wasn't fully optimized although it seems to be an optimized version of the following:
vec4 clipPosition = vec4(vec3(screenPosition, depth) * 2.0 - 1.0, 1.0);
vec4 viewPosition = inverseProjectionMatrix * clipPosition;
viewPosition /= viewPosition.w; // Unproject (division uses more cycles).
This code probably wasn't fully optimized
On second thought, I think this clipW calculation is necessary to support both perspective as well as orthographic projections:

With this orthographic projection matrix, projectionMatrix[2][3] would be 0.0 and projectionMatrix[3][3] would be 1.0. So clipW would be 1.0 in this case.
Oh, I see. It is my mistake to get the wrong index of the projection matrix. 馃槄