Postprocessing: [Question] Confused about clipW in ssao fragment shader

Created on 3 Mar 2021  路  3Comments  路  Source: vanruesc/postprocessing

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.

question

All 3 comments

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).

Source

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. 馃槄

Was this page helpful?
0 / 5 - 0 ratings