Overlay-Next: Fix discrepancy with xray fade and in-front

This require another depth buffer for correct merging
of overlays. Hopefully we can remove this mandatory
allocation later.
This commit is contained in:
Clément Foucault
2024-11-21 18:38:02 +01:00
parent e13504f435
commit b36a11aee2
5 changed files with 35 additions and 9 deletions

View File

@@ -384,7 +384,9 @@ void Instance::draw(Manager &manager)
/* For X-ray we render the scene to a separate depth buffer. */
resources.xray_depth_tx.acquire(render_size, GPU_DEPTH24_STENCIL8);
resources.depth_target_tx.wrap(resources.xray_depth_tx);
resources.depth_target_in_front_tx.wrap(resources.xray_depth_tx);
/* TODO(fclem): Remove mandatory allocation. */
resources.xray_depth_in_front_tx.acquire(render_size, GPU_DEPTH24_STENCIL8);
resources.depth_target_in_front_tx.wrap(resources.xray_depth_in_front_tx);
}
else {
/* TODO(fclem): Remove mandatory allocation. */
@@ -469,6 +471,7 @@ void Instance::draw(Manager &manager)
resources.line_tx.release();
resources.overlay_tx.release();
resources.xray_depth_tx.release();
resources.xray_depth_in_front_tx.release();
resources.depth_in_front_alloc_tx.release();
resources.color_overlay_alloc_tx.release();
resources.color_render_alloc_tx.release();
@@ -523,7 +526,7 @@ void Instance::draw_v3d(Manager &manager, View &view)
regular.prepass.draw(resources.overlay_line_fb, manager, view);
if (!state.xray_enabled && state.v3d && state.v3d->shading.type > OB_SOLID) {
if (state.xray_enabled || (state.v3d && state.v3d->shading.type > OB_SOLID)) {
/* If workbench is not enabled, the infront buffer might contain garbage. */
GPU_framebuffer_bind(resources.overlay_line_in_front_fb);
GPU_framebuffer_clear_depth(resources.overlay_line_in_front_fb, 1.0f);

View File

@@ -354,6 +354,7 @@ struct Resources : public select::SelectMap {
TextureFromPool overlay_tx = {"overlay_tx"};
/* Target containing depth of overlays when xray is enabled. */
TextureFromPool xray_depth_tx = {"xray_depth_tx"};
TextureFromPool xray_depth_in_front_tx = {"xray_depth_in_front_tx"};
/* Texture that are usually allocated inside. These are fallback when they aren't.
* They are then wrapped inside the #TextureRefs below. */

View File

@@ -357,6 +357,7 @@ ShaderModule::ShaderModule(const SelectionType selection_type, const bool clippi
xray_fade = shader("overlay_xray_fade", [](gpu::shader::ShaderCreateInfo &info) {
info.sampler(2, ImageType::DEPTH_2D, "xrayDepthTexInfront");
info.sampler(3, ImageType::DEPTH_2D, "depthTexInfront");
});
/** Selectable Shaders */

View File

@@ -43,6 +43,7 @@ class XrayFade {
/* TODO(fclem): Confusing. The meaning of xray depth texture changed between legacy engine
* and overlay next. To be renamed after shaders are not shared anymore. */
pass.bind_texture("depthTex", &res.xray_depth_tx);
pass.bind_texture("depthTexInfront", &res.xray_depth_in_front_tx);
pass.bind_texture("xrayDepthTex", &res.depth_tx);
pass.bind_texture("xrayDepthTexInfront", &res.depth_in_front_tx);
pass.push_constant("opacity", 1.0f - state.xray_opacity);

View File

@@ -4,18 +4,38 @@
void main()
{
float depth = texture(depthTex, uvcoordsvar.xy).r;
float depth_xray = texture(xrayDepthTex, uvcoordsvar.xy).r;
#ifdef OVERLAY_NEXT
float depth_xray_infront = texture(xrayDepthTexInfront, uvcoordsvar.xy).r;
if (((depth_xray_infront == 1.0) && (depth > depth_xray)) || (depth > depth_xray_infront)) {
fragColor = vec4(opacity);
}
else {
/* TODO(fclem): Cleanup naming. Here the xray depth mean the scene depth (from workbench) and
* simple depth is the overlay depth. */
float depth_infront = textureLod(depthTexInfront, uvcoordsvar.xy, 0.0).r;
float depth_xray_infront = textureLod(xrayDepthTexInfront, uvcoordsvar.xy, 0.0).r;
if (depth_infront != 1.0) {
if (depth_xray_infront < depth_infront) {
fragColor = vec4(opacity);
return;
}
discard;
return;
}
float depth = textureLod(depthTex, uvcoordsvar.xy, 0.0).r;
float depth_xray = textureLod(xrayDepthTex, uvcoordsvar.xy, 0.0).r;
/* Merge infront depth. */
if (depth_xray_infront != 1.0) {
depth_xray = 0.0;
}
if (depth_xray < depth) {
fragColor = vec4(opacity);
return;
}
discard;
return;
#else
float depth = texture(depthTex, uvcoordsvar.xy).r;
float depth_xray = texture(xrayDepthTex, uvcoordsvar.xy).r;
fragColor = vec4((depth < 1.0 && depth > depth_xray) ? opacity : 1.0);
#endif
}