vec3 GetWorldDirection()
{
    vec2 uv = gl_FragCoord.xy / vec2(viewWidth, viewHeight);
    vec4 clip = vec4(uv * 2.0 - 1.0, 1.0, 1.0);

    vec4 view = gbufferProjectionInverse * clip;
    view.xyz /= view.w;

    return normalize(mat3(gbufferModelViewInverse) * view.xyz);
}

vec3 GetWorldPos(vec2 uv, float depth)
{
    vec4 clip = vec4(uv * 2.0 - 1.0, depth * 2.0 - 1.0, 1.0);
    vec4 view = gbufferProjectionInverse * clip;
    view /= view.w;

    vec4 world = gbufferModelViewInverse * view;
    world.xyz += cameraPosition;

    return world.xyz;
}

vec3 GetViewDir()
{
    vec2 uv = gl_FragCoord.xy / vec2(viewWidth, viewHeight);

    vec4 clip = vec4(uv * 2.0 - 1.0, 1.0, 1.0);

    vec4 view = gbufferProjectionInverse * clip;
    view.xyz /= view.w;

    return normalize(view.xyz);
}

vec3 vpGetViewPosition(vec2 uv, float depth){
    vec4 clip = vec4( uv * 2.0 - 1.0, depth * 2.0 - 1.0, 1.0);
    vec4 view = gbufferProjectionInverse * clip;

    view /= view.w;

    return view.xyz;
}