Workbench Next: Fix Overlay composition
Set "In Front" objects depth to 0, so overlays are not drawn on top of them.
This commit is contained in:
@@ -583,6 +583,7 @@ set(GLSL_SRC
|
||||
engines/workbench/shaders/workbench_material_lib.glsl
|
||||
engines/workbench/shaders/workbench_merge_infront_frag.glsl
|
||||
engines/workbench/shaders/workbench_next_merge_depth_frag.glsl
|
||||
engines/workbench/shaders/workbench_overlay_depth_frag.glsl
|
||||
engines/workbench/shaders/workbench_prepass_frag.glsl
|
||||
engines/workbench/shaders/workbench_prepass_hair_vert.glsl
|
||||
engines/workbench/shaders/workbench_prepass_pointcloud_vert.glsl
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Foundation
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "gpu_shader_create_info.hh"
|
||||
|
||||
GPU_SHADER_CREATE_INFO(workbench_overlay_depth)
|
||||
.sampler(0, ImageType::DEPTH_2D, "depth_tx")
|
||||
.sampler(1, ImageType::UINT_2D, "stencil_tx")
|
||||
.fragment_source("workbench_overlay_depth_frag.glsl")
|
||||
.additional_info("draw_fullscreen")
|
||||
.depth_write(DepthWrite::ANY)
|
||||
.do_static_compilation(true);
|
||||
@@ -0,0 +1,15 @@
|
||||
/* Prepare the Depth Buffer for the Overlay Engine. */
|
||||
|
||||
void main()
|
||||
{
|
||||
uint stencil = texelFetch(stencil_tx, ivec2(gl_FragCoord.xy), 0).r;
|
||||
if (stencil != 0) {
|
||||
/* Set the depth to 0 for "In Front" objects,
|
||||
* so the Overlay engine doesn't draw on top of them. */
|
||||
gl_FragDepth = 0.0;
|
||||
}
|
||||
else {
|
||||
float depth = texelFetch(depth_tx, ivec2(gl_FragCoord.xy), 0).r;
|
||||
gl_FragDepth = depth;
|
||||
}
|
||||
}
|
||||
@@ -115,6 +115,7 @@ AntiAliasingPass::AntiAliasingPass()
|
||||
smaa_edge_detect_sh_ = GPU_shader_create_from_info_name("workbench_smaa_stage_0");
|
||||
smaa_aa_weight_sh_ = GPU_shader_create_from_info_name("workbench_smaa_stage_1");
|
||||
smaa_resolve_sh_ = GPU_shader_create_from_info_name("workbench_smaa_stage_2");
|
||||
overlay_depth_sh_ = GPU_shader_create_from_info_name("workbench_overlay_depth");
|
||||
|
||||
smaa_search_tx_.ensure_2d(
|
||||
GPU_R8, {SEARCHTEX_WIDTH, SEARCHTEX_HEIGHT}, GPU_TEXTURE_USAGE_SHADER_READ);
|
||||
@@ -143,6 +144,13 @@ void AntiAliasingPass::init(const SceneState &scene_state)
|
||||
|
||||
void AntiAliasingPass::sync(SceneResources &resources, int2 resolution)
|
||||
{
|
||||
overlay_depth_ps_.init();
|
||||
overlay_depth_ps_.state_set(DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS);
|
||||
overlay_depth_ps_.shader_set(overlay_depth_sh_);
|
||||
overlay_depth_ps_.bind_texture("depth_tx", &resources.depth_tx);
|
||||
overlay_depth_ps_.bind_texture("stencil_tx", &stencil_tx_);
|
||||
overlay_depth_ps_.draw_procedural(GPU_PRIM_TRIS, 1, 3);
|
||||
|
||||
if (!enabled_) {
|
||||
taa_accumulation_tx_.free();
|
||||
sample0_depth_tx_.free();
|
||||
@@ -244,12 +252,16 @@ void AntiAliasingPass::draw(Manager &manager,
|
||||
GPUTexture *depth_tx,
|
||||
GPUTexture *color_tx)
|
||||
{
|
||||
auto draw_overlay_depth = [&](GPUTexture *target) {
|
||||
stencil_tx_ = resources.depth_tx.stencil_view();
|
||||
overlay_depth_fb_.ensure(GPU_ATTACHMENT_TEXTURE(target));
|
||||
overlay_depth_fb_.bind();
|
||||
manager.submit(overlay_depth_ps_);
|
||||
};
|
||||
|
||||
if (!enabled_) {
|
||||
/* TODO(@pragma37): Should render to the input color_tx and depth_tx in the first place.
|
||||
* This requires the use of TextureRefs with stencil_view() support,
|
||||
* but whether TextureRef will stay is still TBD. */
|
||||
GPU_texture_copy(color_tx, resources.color_tx);
|
||||
GPU_texture_copy(depth_tx, resources.depth_tx);
|
||||
draw_overlay_depth(depth_tx);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -273,20 +285,10 @@ void AntiAliasingPass::draw(Manager &manager,
|
||||
}
|
||||
|
||||
if (sample_ == 0) {
|
||||
if (sample0_depth_tx_.is_valid()) {
|
||||
GPU_texture_copy(sample0_depth_tx_, resources.depth_tx);
|
||||
}
|
||||
/* TODO(@pragma37): Should render to the input depth_tx in the first place
|
||||
* This requires the use of TextureRef with stencil_view() support,
|
||||
* but whether TextureRef will stay is still TBD. */
|
||||
|
||||
/* Copy back the saved depth buffer for correct overlays. */
|
||||
GPU_texture_copy(depth_tx, resources.depth_tx);
|
||||
}
|
||||
else {
|
||||
/* Copy back the saved depth buffer for correct overlays. */
|
||||
GPU_texture_copy(depth_tx, sample0_depth_tx_);
|
||||
draw_overlay_depth(sample0_depth_tx_);
|
||||
}
|
||||
/* Copy back the saved depth buffer for correct overlays. */
|
||||
GPU_texture_copy(depth_tx, sample0_depth_tx_);
|
||||
|
||||
if (!DRW_state_is_image_render() || last_sample) {
|
||||
smaa_weight_tx_.acquire(
|
||||
|
||||
@@ -212,15 +212,11 @@ class Instance {
|
||||
if (scene_state.xray_mode || is_transparent) {
|
||||
if (in_front) {
|
||||
draw_callback(transparent_ps.accumulation_in_front_ps_);
|
||||
if (scene_state.draw_transparent_depth) {
|
||||
draw_callback(transparent_depth_ps.in_front_ps_);
|
||||
}
|
||||
draw_callback(transparent_depth_ps.in_front_ps_);
|
||||
}
|
||||
else {
|
||||
draw_callback(transparent_ps.accumulation_ps_);
|
||||
if (scene_state.draw_transparent_depth) {
|
||||
draw_callback(transparent_depth_ps.main_ps_);
|
||||
}
|
||||
draw_callback(transparent_depth_ps.main_ps_);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -472,12 +468,8 @@ class Instance {
|
||||
}
|
||||
}
|
||||
|
||||
opaque_ps.draw(manager,
|
||||
view,
|
||||
resources,
|
||||
resolution,
|
||||
&shadow_ps,
|
||||
transparent_ps.accumulation_ps_.is_empty());
|
||||
opaque_ps.draw(
|
||||
manager, view, resources, resolution, scene_state.draw_shadows ? &shadow_ps : nullptr);
|
||||
transparent_ps.draw(manager, view, resources, resolution);
|
||||
transparent_depth_ps.draw(manager, view, resources);
|
||||
|
||||
|
||||
@@ -149,8 +149,7 @@ void OpaquePass::draw(Manager &manager,
|
||||
View &view,
|
||||
SceneResources &resources,
|
||||
int2 resolution,
|
||||
ShadowPass *shadow_pass,
|
||||
bool accumulation_ps_is_empty)
|
||||
ShadowPass *shadow_pass)
|
||||
{
|
||||
if (is_empty()) {
|
||||
return;
|
||||
@@ -189,8 +188,7 @@ void OpaquePass::draw(Manager &manager,
|
||||
manager.submit(gbuffer_ps_, view);
|
||||
}
|
||||
|
||||
bool needs_stencil_copy = shadow_pass && !gbuffer_in_front_ps_.is_empty() &&
|
||||
!accumulation_ps_is_empty;
|
||||
bool needs_stencil_copy = shadow_pass && !gbuffer_in_front_ps_.is_empty();
|
||||
|
||||
if (needs_stencil_copy) {
|
||||
shadow_depth_stencil_tx.ensure_2d(GPU_DEPTH24_STENCIL8,
|
||||
@@ -201,18 +199,15 @@ void OpaquePass::draw(Manager &manager,
|
||||
GPU_texture_copy(shadow_depth_stencil_tx, resources.depth_tx);
|
||||
|
||||
deferred_ps_stencil_tx = shadow_depth_stencil_tx.stencil_view();
|
||||
}
|
||||
else {
|
||||
shadow_depth_stencil_tx.free();
|
||||
|
||||
deferred_ps_stencil_tx = resources.depth_tx.stencil_view();
|
||||
}
|
||||
|
||||
if (shadow_pass && !gbuffer_in_front_ps_.is_empty()) {
|
||||
opaque_fb.ensure(GPU_ATTACHMENT_TEXTURE(deferred_ps_stencil_tx));
|
||||
opaque_fb.bind();
|
||||
GPU_framebuffer_clear_stencil(opaque_fb, 0);
|
||||
}
|
||||
else {
|
||||
shadow_depth_stencil_tx.free();
|
||||
deferred_ps_stencil_tx = resources.depth_tx.stencil_view();
|
||||
}
|
||||
|
||||
if (shadow_pass) {
|
||||
shadow_pass->draw(
|
||||
|
||||
@@ -88,7 +88,6 @@ struct SceneState {
|
||||
bool draw_aa = false;
|
||||
|
||||
bool draw_object_id = false;
|
||||
bool draw_transparent_depth = false;
|
||||
|
||||
int sample = 0;
|
||||
int samples_len = 0;
|
||||
@@ -207,8 +206,7 @@ class OpaquePass {
|
||||
View &view,
|
||||
SceneResources &resources,
|
||||
int2 resolution,
|
||||
class ShadowPass *shadow_pass,
|
||||
bool accumulation_ps_is_empty);
|
||||
class ShadowPass *shadow_pass);
|
||||
bool is_empty() const;
|
||||
};
|
||||
|
||||
@@ -455,6 +453,7 @@ class AntiAliasingPass {
|
||||
float weights_sum_ = 0;
|
||||
|
||||
Texture sample0_depth_tx_ = {"sample0_depth_tx"};
|
||||
GPUTexture *stencil_tx_ = nullptr;
|
||||
|
||||
Texture taa_accumulation_tx_ = {"taa_accumulation_tx"};
|
||||
Texture smaa_search_tx_ = {"smaa_search_tx"};
|
||||
@@ -466,6 +465,7 @@ class AntiAliasingPass {
|
||||
Framebuffer smaa_edge_fb_ = {"smaa_edge_fb"};
|
||||
Framebuffer smaa_weight_fb_ = {"smaa_weight_fb"};
|
||||
Framebuffer smaa_resolve_fb_ = {"smaa_resolve_fb"};
|
||||
Framebuffer overlay_depth_fb_ = {"overlay_depth_fb"};
|
||||
|
||||
float4 smaa_viewport_metrics_ = float4(0);
|
||||
float smaa_mix_factor_ = 0;
|
||||
@@ -474,11 +474,13 @@ class AntiAliasingPass {
|
||||
GPUShader *smaa_edge_detect_sh_ = nullptr;
|
||||
GPUShader *smaa_aa_weight_sh_ = nullptr;
|
||||
GPUShader *smaa_resolve_sh_ = nullptr;
|
||||
GPUShader *overlay_depth_sh_ = nullptr;
|
||||
|
||||
PassSimple taa_accumulation_ps_ = {"TAA.Accumulation"};
|
||||
PassSimple smaa_edge_detect_ps_ = {"SMAA.EdgeDetect"};
|
||||
PassSimple smaa_aa_weight_ps_ = {"SMAA.BlendWeights"};
|
||||
PassSimple smaa_resolve_ps_ = {"SMAA.Resolve"};
|
||||
PassSimple overlay_depth_ps_ = {"Overlay Depth"};
|
||||
|
||||
public:
|
||||
AntiAliasingPass();
|
||||
|
||||
@@ -173,7 +173,6 @@ void SceneState::init(Object *camera_ob /*= nullptr*/)
|
||||
draw_dof = camera && camera->dof.flag & CAM_DOF_ENABLED &&
|
||||
shading.flag & V3D_SHADING_DEPTH_OF_FIELD;
|
||||
|
||||
draw_transparent_depth = draw_outline || draw_dof;
|
||||
draw_object_id = draw_outline || draw_curvature;
|
||||
};
|
||||
|
||||
|
||||
@@ -679,6 +679,7 @@ set(SRC_SHADER_CREATE_INFOS
|
||||
../draw/engines/workbench/shaders/infos/workbench_effect_dof_info.hh
|
||||
../draw/engines/workbench/shaders/infos/workbench_effect_outline_info.hh
|
||||
../draw/engines/workbench/shaders/infos/workbench_merge_infront_info.hh
|
||||
../draw/engines/workbench/shaders/infos/workbench_overlay_depth_info.hh
|
||||
../draw/engines/workbench/shaders/infos/workbench_prepass_info.hh
|
||||
../draw/engines/workbench/shaders/infos/workbench_shadow_info.hh
|
||||
../draw/engines/workbench/shaders/infos/workbench_transparent_resolve_info.hh
|
||||
|
||||
Reference in New Issue
Block a user