Advertisement

Adaptive Depth offset for texture sampling

Started by March 16, 2021 12:52 PM
3 comments, last by Frantic PonE 3 years, 7 months ago

Hi,

I have a complex 3D scenes, the values in my depth buffer ranges from close shot, few centimeters, to various kilometers.

For some various effects I am using a depth bias, offset to circumvent some artifacts (SSAO, Shadow). Even during depth peeling by comparing depth between the current peel and the previous one some issues can occur when sampling the previous screen texture.

I have fix those issues for close up shot but when the fragment is far enough, the bias become obsolete.

I am wondering how to tackle the bias for such scenes. Something around bias depending on the current world depth of the current pixel or maybe completely disabling the effect at a given depth ?

Is there some good practices regarding those issues, and how can I address them ?

SSAO Artifacts

Wait why are you depth peeling, that's crazily expensive.

Anyway, it sounds like a floating point error yes? Well the only trick I know is flipped z, which is pretty standard today. You flip your depth axis and resample from there, gives a more linear approximation of depth and can solve some precision issues nigh for free. Here's a longer tutorial: https://nlguillemot.wordpress.com/2016/12/07/reversed-z-in-opengl/

I'm assuming the bias is small enough that precision issues start creeping in? Also the effect is actually a neat kind line drawing art style.

Advertisement

I didn't know the reverse trick might give it a go sometime, thanks.

I am working on a simulation software for building, and for those specifics needs I had to implement depth peeling, and yes it's crazily expensive, but I found a way to compute the most appropriate number of peels. the latest peels dont't bring a lot of information on your final image.

So I have found a solution to my problem

I have sound this link for shadow bias https://digitalrune.github.io/DigitalRune-Documentation/html/3f4d959e-9c98-4a97-8d85-7a73c26145d7.htm

Depth bias and normal offset values are specified in shadow map texels. For example, depth bias = 3 means that the pixels is moved the length of 3 shadows map texels closer to the light.

By keeping the bias proportional to the projected shadow map texels, the same settings work at all distances.

I use the difference in world space between the current point and a neighboring pixel with the same depth component. the bias become something close to "the average distance between 2 neighboring pixels". The further the pixel is the larger the bias will be (from few millimeters close to the near plane to meters at the far plane).

So for each of my sampling point, I offset its position from some pixels in its x direction (3 pixels give me good results on various scenes).

I compute the world difference between the currentPoint and this new offsetedPoint

I use this difference as a bias for all my depth testing

code

float compute_depth_offset() {

    mat4 inv_mvp = inverse(mvp);
    vec2 currentPixel = vec2(gl_FragCoord.xy) / dim;
    vec2 nextPixel = vec2(gl_FragCoord.xy + vec2(depth_transparency_bias, 0.0)) / dim;

    vec4 currentNDC;
    vec4 nextNDC;

    currentNDC.xy = currentPixel * 2.0 - 1.0;
    currentNDC.z = (2.0 * gl_FragCoord.z - depth_range.near - depth_range.far) / (depth_range.far - depth_range.near);
    currentNDC.w = 1.0;

    nextNDC.xy = nextPixel * 2.0 - 1.0;
    nextNDC.z = currentNDC.z;
    nextNDC.w = currentNDC.w;

    vec4 world = (inv_mvp * currentNDC);
    world.xyz = world.xyz / world.w;

    vec4 nextWorld = (inv_mvp * nextNDC);
    nextWorld.xyz = nextWorld.xyz / nextWorld.w;

    return length(nextWorld.xyz - world.xyz);
}

Result

No correction for shadow cascade variance and tricky interpolation stuff (it's always more complicated than I think), I was wondering why it showed up in such an odd pattern, it seems blindingly obvious in retrospect. Glad you found the answer.

This topic is closed to new replies.

Advertisement