[EEVEE & C-Dev] hijacking mist output for depth with DRW_STATE_DEPTH_GREATER_EQUAL

Hey People!

I am trying to get Eevee to output a rough approximated thickness of a given camera view, it needs to get outputted as a render layer so I can render it to an EXR.

My basic approach is the following:

  1. Hijack the Mist Shader to just output depth.
  2. Render the depth prepass twice once with GREATER EQUAL
  3. Then render mist (e.g. just copy depth to mist rendertarget)
  4. Render depth normally and proceed as usual (without rendering mist again).

I have succeeded in getting Mist to output depth (modified shader, set g_data->renderpass_postprocess = PASS_POST_DEPTH),
however my efforts to get the inverse depth pass to work have been flaunted.
So far I tried adding a new pass to Eevee by adding it to eevee_materials.c:

DRWState state_invdepth = DRW_STATE_WRITE_DEPTH | 
DRW_STATE_DEPTH_GREATER_EQUAL;
EEVEE_PASS_CREATE(invdepth, state_invdepth);
EEVEE_CLIP_PASS_CREATE(invdepth, state_invdepth);

And trying to invoke it before the depth prepass:
{
/* Inverse Depth for Thickness! */
if (fbl->mist_accum_fb != NULL) {
GPU_framebuffer_bind(fbl->main_fb);
GPU_framebuffer_clear_color_depth_stencil(fbl->main_fb, clear_col, 0.0f, clear_stencil);
DRW_draw_pass(psl->invdepth_ps);

    GPU_framebuffer_bind(fbl->mist_accum_fb);
    const float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};
    GPU_framebuffer_clear_color(fbl->mist_accum_fb, clear);
    DRW_draw_pass(psl->mist_accum_ps);

    /* Restore */
    GPU_framebuffer_bind(fbl->main_fb);
  }

}

GPU_framebuffer_clear_color_depth_stencil(fbl->main_fb, clear_col, clear_depth, clear_stencil);


/* Depth prepass */
DRW_draw_pass(psl->depth_ps);

Unfortunately mist still ends up outputting normal prepass depth!
Maybe someone has a hint for me of how to get it working?
I am fairly new to working in the blender codebase so it is not quite obvious to me how it works exactly e.g. order of draw calls and all that! Would be glad if someone can point me into the right direction!

Thank you!

1 Like

Hi,

Its hard to understand how everything is connected. It could be that the incorrect buffers are connected or that the order the code is added is not in the correct place. Would help if you upload a diff to developer.blender.org/paste with the full change.

It really depends on your usecase how to get thickness.
The trick with the average depth is in Eevee is that occlusion filters could remove objects as they aren’t visible. Also it is won’t be the tickness of an object, but of the furthest away intersection and the most on top intersection at that pixel, that could be different objects. Alpha mode blending uses a different buffer, etc.

Still a nice project to get a understanding how Blender and Eevee works. If you need help please drop by the eevee-viewport-module in blender chat.

Are you using tools like renderdoc? This tool really helps in debugging the actual state and how eevee works.

Jeroen

1 Like

Thank you for your reply!
I was wondering about renderdoc! I have not tried to use it yet but will dive into it.

My specific use case is that we are developing a pixel art game using blender and we are rendering ultra low res sprite sheets from 3d models. We require mutliple render passes with buffers like normals, depth and thickness as well as a few other material parameters.
Right now we are doing 3 passes: One for basic material data, e.g. diffuse color, emissive color, depth, normals. One for velocity, roughness and metallic (we need to switch to cycles for that) and one for thickness (we render the scene from the other direction (cameras use orthographic projection) and substract from original depth.).

When rendering out animations for a Unit for example with lets say 100 frames we are right now rendering 8 directions x 100 frames x 3 passes = 2400 renders.
Getting rid of the thickness pass by getting this "inverted’ Z buffer would be a huge win for us and cut down render and iteration time by a lot!

I am aware that that would not be the exact thickness of an object but for us it would be a good enough approximation to do our effects!

You can see a full diff here in my fork:

Cheers!

2 Likes

Thanks for sharing the info. Gives me better understanding what you’re looking for. Adding a pass for this is doable. I will have a look at your branch shortly and point you into the right direction.

Eevee and renderpasses can listen close to each other and might just be that things are done in the wrong place. Materials have a depth shader reason is for transparency (clipped/hashed) are material based depths.