Modifying the depth buffer during the post processing pipeline

TL;DR: Is it possible to modify the depth buffer in a PostProcess, so that the next one in the pipeline gets this change?

Basically I have something like this:

let renderSceneBasePP = new BABYLON.PassPostProcess(...);

// this is a modified version of the OceanPP that used to be shipped with babylon.
// It renders the ocean with ray marching and I want to set the Z buffer as well.
let oceanPostProcess = new OceanPostProcess(...); 

// now I want to access in the fragment shader for this PP the color buffer (got it, works) and 
// the depth buffer (which doesn't seem to be updated at all)
let myFancyPostProcess = new MyFancyPostProcess(...);

const renderLayer = new BABYLON.PostProcessRenderEffect(
        function () { return [renderSceneBase, oceanPostProcess, myFancyPostProcess]; }

I expected that setting gl_FragDepth on the fragment shader of OceanPostProcess would modify the z-buffer, but there is no discernible change, neither on the inspector textures or on the uniform depthTexture (rendering it as the gl_FragColor to debug).

Reason why I want this: I’m modifying the old OceanPostProcess code to work underwater as well and I want to be able to properly blend the distance to handle limited underwater visibility, so getting the Z coordinate is important. The final code will be released on GitHub.

It’s possible but you have to do a bit of work because post processes don’t use depth buffers by default.

So, you need to:

  • create a depth texture for the Ocean post process. You do this by getting the RenderTargetWrapper of the post process and by calling createDepthStencilTexture on it
  • enable depth testing/writing for the post process. For some reason, only enabling depth writing is not enough for gl_FragDepth to work, you must also enable depth testing… You also need to clear the depth buffer (use engine.clear(...))
  • use gl_FragDepth in the shader to write depth values




Note for people who read this in the future when they get weird results for no apparent reason: you’ll need to release and rebuild the this secondary depth texture if you call engine.resize().