We are trying to render custom geometry to the scene using a view extension. We are currently using `PostRenderBasePassDeferred_RenderThread(..)` to achieve this. With the upgrade to 5.7, some passes, for example SkyAtmosphere and ExponentialHeightFog, now use a copy of the scene depth prepass made at the very start of SingleLayerWaterDepthPrepass (SLW.DepthPrepassOutput). This copy of the depth is not passed to the view extension to be modified and therefore the custom geometry is not properly taken into account during these passes.
We have not found any clean ways to add custom geometry passes to the depth prepass, nor update the SLW.DepthPrepassOutput buffer.
What is the intended method to add custom geometry passes to the rendering pipeline? Is there some way to use the core gbuffer depth texture in these later transparency stages?
[Attachment Removed]
Hi Joel,
To give you a bit more context, the render pipeline is currently set up such that we create a copy of the main depth buffer, draw water into that copy, and mark all water pixels with a stencil bit (in the copy). This happens before the lighting stage, as the prepass is needed for VSM page allocation. After lighting the gbuffer, we draw the SLW main pass, which performs DEPTH_EQUAL and STENCIL_EQUAL on the depth buffer copy containing water. After the SLW pass, we swap the depth buffers, so now the rest of the renderer sees the depth buffer with water in it. All of this works under the assumption that there are no draws to the depth buffer between the water depth prepass (where we make the copy) and until after the SLW main pass (when we swap the depth buffers). Originally, there was just gbuffer lighting and potentially some translucency in between.
We changed some of that behavior recently, so what’s likely happening on your end now is that you are drawing into the main depth buffer directly after the basepass, but we then swap out that depth buffer a few steps later in the pipeline after SLW. The issue would likely not occur if GetSingleLayerWaterDepthPrepassLocation() returns ESingleLayerWaterPrepassLocation::AfterBasePass. The trivial fix in this case would be to introduce a cvar to override the behavior of GetSingleLayerWaterDepthPrepassLocation().
Can I ask you what exactly you are doing within the scene view extension? Typically, we advise people to use primitive proxies and add those into the scene, such that the correct passes can work with the geometry you create.
[Attachment Removed]
Ok, I understand. I don’t know what your plan is with the alternative solution. Could you provide any extra details so I can get a better picture of the plan? The SLW implementation actually has two depth buffers: one for optical depth and one for EarlyZ depth rejection. As long as you properly handle these buffers, you should be fine, but that is based on the limited info you have given me. Also, I’d like to point out that this will need some engine modifications, which we usually discourage. Please be careful when attempting any custom changes.
[Attachment Removed]
We took a look this last week into using proxies.
We are rending grass procedurally in the scene view. It seemed like a good place to do it because we specifically are not creating a concrete persistent vertex buffer. The problem with trying to move this into proxies is that it seems like the only way to make that work is by actually making full vertex buffers for the procedural grass, which more or less defeats the point.
The alternative we are looking at right now is merging the depth buffer back in to the depth buffer copy after the grass draw.
[Attachment Removed]