Merge pull request #55084 from JFonS/fix_depth_prepass

Fix Depth-Prepass transparency mode
This commit is contained in:
Rémi Verschelde 2021-11-18 17:39:46 +01:00 committed by GitHub
commit fa11b45961
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 41 additions and 21 deletions

View file

@ -334,6 +334,10 @@ void RenderForwardClustered::_render_list_template(RenderingDevice::DrawListID p
const GeometryInstanceSurfaceDataCache *surf = p_params->elements[i];
const RenderElementInfo &element_info = p_params->element_info[i];
if ((p_pass_mode == PASS_MODE_COLOR || p_pass_mode == PASS_MODE_COLOR_SPECULAR) && !(surf->flags & GeometryInstanceSurfaceDataCache::FLAG_PASS_OPAQUE)) {
continue; // Objects with "Depth-prepass" transparency are included in both render lists, but should only be rendered in the transparent pass
}
if (surf->owner->instance_count == 0) {
continue;
}
@ -958,20 +962,20 @@ void RenderForwardClustered::_fill_render_list(RenderListType p_render_list, con
bool uses_gi = false;
float fade_alpha = 1.0;
if (p_render_list == RENDER_LIST_OPAQUE) {
if (inst->fade_near || inst->fade_far) {
float fade_dist = inst->transform.origin.distance_to(p_render_data->cam_transform.origin);
if (inst->fade_far && fade_dist > inst->fade_far_begin) {
fade_alpha = MAX(0.0, 1.0 - (fade_dist - inst->fade_far_begin) / (inst->fade_far_end - inst->fade_far_begin));
} else if (inst->fade_near && fade_dist < inst->fade_near_end) {
fade_alpha = MAX(0.0, (fade_dist - inst->fade_near_begin) / (inst->fade_near_end - inst->fade_near_begin));
}
if (inst->fade_near || inst->fade_far) {
float fade_dist = inst->transform.origin.distance_to(p_render_data->cam_transform.origin);
if (inst->fade_far && fade_dist > inst->fade_far_begin) {
fade_alpha = MAX(0.0, 1.0 - (fade_dist - inst->fade_far_begin) / (inst->fade_far_end - inst->fade_far_begin));
} else if (inst->fade_near && fade_dist < inst->fade_near_end) {
fade_alpha = MAX(0.0, (fade_dist - inst->fade_near_begin) / (inst->fade_near_end - inst->fade_near_begin));
}
}
fade_alpha *= inst->force_alpha * inst->parent_fade_alpha;
fade_alpha *= inst->force_alpha * inst->parent_fade_alpha;
flags = (flags & ~INSTANCE_DATA_FLAGS_FADE_MASK) | (uint32_t(fade_alpha * 255.0) << INSTANCE_DATA_FLAGS_FADE_SHIFT);
flags = (flags & ~INSTANCE_DATA_FLAGS_FADE_MASK) | (uint32_t(fade_alpha * 255.0) << INSTANCE_DATA_FLAGS_FADE_SHIFT);
if (p_render_list == RENDER_LIST_OPAQUE) {
// Setup GI
if (inst->lightmap_instance.is_valid()) {
int32_t lightmap_cull_index = -1;
@ -1206,6 +1210,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
scene_state.ubo.viewport_size[0] = vp_he.x;
scene_state.ubo.viewport_size[1] = vp_he.y;
scene_state.ubo.directional_light_count = 0;
scene_state.ubo.opaque_prepass_threshold = 0.99f;
Size2i screen_size;
RID opaque_framebuffer;
@ -1449,6 +1454,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
RD::get_singleton()->draw_command_begin_label("Render Opaque Pass");
scene_state.ubo.directional_light_count = p_render_data->directional_light_count;
scene_state.ubo.opaque_prepass_threshold = 0.0f;
_setup_environment(p_render_data, p_render_data->reflection_probe.is_valid(), screen_size, !p_render_data->reflection_probe.is_valid(), p_default_bg_color, p_render_data->render_buffers.is_valid());
@ -1632,6 +1638,7 @@ void RenderForwardClustered::_render_shadow_append(RID p_framebuffer, const Page
render_data.render_info = p_render_info;
scene_state.ubo.dual_paraboloid_side = p_use_dp_flip ? -1 : 1;
scene_state.ubo.opaque_prepass_threshold = 0.1f;
_setup_environment(&render_data, true, Vector2(1, 1), !p_flip_y, Color(), false, p_use_pancake, shadow_pass_index);
@ -1718,6 +1725,7 @@ void RenderForwardClustered::_render_particle_collider_heightfield(RID p_fb, con
_update_render_base_uniform_set();
scene_state.ubo.dual_paraboloid_side = 0;
scene_state.ubo.opaque_prepass_threshold = 0.0;
_setup_environment(&render_data, true, Vector2(1, 1), true, Color(), false, false);
@ -1755,6 +1763,7 @@ void RenderForwardClustered::_render_material(const Transform3D &p_cam_transform
scene_state.ubo.dual_paraboloid_side = 0;
scene_state.ubo.material_uv2_mode = false;
scene_state.ubo.opaque_prepass_threshold = 0.0f;
_setup_environment(&render_data, true, Vector2(1, 1), false, Color());
@ -1798,6 +1807,7 @@ void RenderForwardClustered::_render_uv2(const PagedArray<GeometryInstance *> &p
scene_state.ubo.dual_paraboloid_side = 0;
scene_state.ubo.material_uv2_mode = true;
scene_state.ubo.opaque_prepass_threshold = 0.0;
_setup_environment(&render_data, true, Vector2(1, 1), false, Color());

View file

@ -257,7 +257,8 @@ class RenderForwardClustered : public RendererSceneRenderRD {
float roughness_limiter_amount;
float roughness_limiter_limit;
uint32_t roughness_limiter_pad[2];
float opaque_prepass_threshold;
uint32_t roughness_limiter_pad;
float sdf_to_bounds[16];

View file

@ -650,6 +650,7 @@ void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const Strin
actions.render_mode_defines["cull_front"] = "#define DO_SIDE_CHECK\n";
actions.render_mode_defines["cull_disabled"] = "#define DO_SIDE_CHECK\n";
actions.render_mode_defines["particle_trails"] = "#define USE_PARTICLE_TRAILS\n";
actions.render_mode_defines["depth_draw_opaque"] = "#define USE_OPAQUE_PREPASS\n";
bool force_lambert = GLOBAL_GET("rendering/shading/overrides/force_lambert_over_burley");

View file

@ -483,6 +483,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
scene_state.ubo.viewport_size[0] = vp_he.x;
scene_state.ubo.viewport_size[1] = vp_he.y;
scene_state.ubo.directional_light_count = 0;
scene_state.ubo.opaque_prepass_threshold = 0.0;
// We can only use our full subpass approach if we're:
// - not reading from SCREEN_TEXTURE/DEPTH_TEXTURE
@ -793,7 +794,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
if (using_subpass_transparent) {
RD::FramebufferFormatID fb_format = RD::get_singleton()->framebuffer_get_format(framebuffer);
RenderListParameters render_list_params(render_list[RENDER_LIST_ALPHA].elements.ptr(), render_list[RENDER_LIST_ALPHA].element_info.ptr(), render_list[RENDER_LIST_ALPHA].elements.size(), reverse_cull, PASS_MODE_COLOR, rp_uniform_set, spec_constant_base_flags, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_lod_threshold, p_render_data->view_count);
RenderListParameters render_list_params(render_list[RENDER_LIST_ALPHA].elements.ptr(), render_list[RENDER_LIST_ALPHA].element_info.ptr(), render_list[RENDER_LIST_ALPHA].elements.size(), reverse_cull, PASS_MODE_COLOR_TRANSPARENT, rp_uniform_set, spec_constant_base_flags, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_lod_threshold, p_render_data->view_count);
render_list_params.framebuffer_format = fb_format;
if ((uint32_t)render_list_params.element_count > render_list_thread_threshold && false) {
// secondary command buffers need more testing at this time
@ -897,6 +898,7 @@ void RenderForwardMobile::_render_shadow_append(RID p_framebuffer, const PagedAr
render_data.lod_distance_multiplier = p_lod_distance_multiplier;
scene_state.ubo.dual_paraboloid_side = p_use_dp_flip ? -1 : 1;
scene_state.ubo.opaque_prepass_threshold = 0.1;
_setup_environment(&render_data, true, Vector2(1, 1), !p_flip_y, Color(), false, p_use_pancake, shadow_pass_index);
@ -978,6 +980,7 @@ void RenderForwardMobile::_render_material(const Transform3D &p_cam_transform, c
scene_state.ubo.dual_paraboloid_side = 0;
scene_state.ubo.material_uv2_mode = false;
scene_state.ubo.opaque_prepass_threshold = 0.0f;
RenderDataRD render_data;
render_data.cam_projection = p_cam_projection;
@ -1089,6 +1092,7 @@ void RenderForwardMobile::_render_particle_collider_heightfield(RID p_fb, const
_update_render_base_uniform_set();
scene_state.ubo.dual_paraboloid_side = 0;
scene_state.ubo.opaque_prepass_threshold = 0.0;
RenderDataRD render_data;
render_data.cam_projection = p_cam_projection;
@ -1447,13 +1451,13 @@ void RenderForwardMobile::_fill_render_list(RenderListType p_render_list, const
}
// ADD Element
if (p_pass_mode == PASS_MODE_COLOR) {
if (p_pass_mode == PASS_MODE_COLOR || p_pass_mode == PASS_MODE_COLOR_TRANSPARENT) {
#ifdef DEBUG_ENABLED
bool force_alpha = unlikely(get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_OVERDRAW);
#else
bool force_alpha = false;
#endif
if (!force_alpha && (surf->flags & (GeometryInstanceSurfaceDataCache::FLAG_PASS_DEPTH | GeometryInstanceSurfaceDataCache::FLAG_PASS_OPAQUE))) {
if (!force_alpha && (surf->flags & GeometryInstanceSurfaceDataCache::FLAG_PASS_OPAQUE)) {
rl->add_element(surf);
}
if (force_alpha || (surf->flags & GeometryInstanceSurfaceDataCache::FLAG_PASS_ALPHA)) {

View file

@ -292,7 +292,8 @@ protected:
float roughness_limiter_amount;
float roughness_limiter_limit;
uint32_t roughness_limiter_pad[2];
float opaque_prepass_threshold;
uint32_t roughness_limiter_pad;
// Fog
uint32_t fog_enabled;

View file

@ -637,6 +637,7 @@ void SceneShaderForwardMobile::init(RendererStorageRD *p_storage, const String p
actions.render_mode_defines["cull_front"] = "#define DO_SIDE_CHECK\n";
actions.render_mode_defines["cull_disabled"] = "#define DO_SIDE_CHECK\n";
actions.render_mode_defines["particle_trails"] = "#define USE_PARTICLE_TRAILS\n";
actions.render_mode_defines["depth_draw_opaque"] = "#define USE_OPAQUE_PREPASS\n";
bool force_lambert = GLOBAL_GET("rendering/shading/overrides/force_lambert_over_burley");
if (!force_lambert) {

View file

@ -695,7 +695,7 @@ void main() {
#endif // ALPHA_ANTIALIASING_EDGE_USED
#ifdef USE_OPAQUE_PREPASS
if (alpha < opaque_prepass_threshold) {
if (alpha < scene_data.opaque_prepass_threshold) {
discard;
}
#endif // USE_OPAQUE_PREPASS
@ -1711,7 +1711,7 @@ void main() {
#ifdef USE_OPAQUE_PREPASS
if (alpha < opaque_prepass_threshold) {
if (alpha < scene_data.opaque_prepass_threshold) {
discard;
}

View file

@ -208,7 +208,8 @@ layout(set = 1, binding = 0, std140) uniform SceneData {
float roughness_limiter_amount;
float roughness_limiter_limit;
uvec2 roughness_limiter_pad;
float opaque_prepass_threshold;
uint roughness_limiter_pad;
mat4 sdf_to_bounds;

View file

@ -705,7 +705,7 @@ void main() {
#endif // ALPHA_ANTIALIASING_EDGE_USED
#ifdef USE_OPAQUE_PREPASS
if (alpha < opaque_prepass_threshold) {
if (alpha < scene_data.opaque_prepass_threshold) {
discard;
}
#endif // USE_OPAQUE_PREPASS
@ -1476,7 +1476,7 @@ void main() {
#ifdef USE_OPAQUE_PREPASS
if (alpha < opaque_prepass_threshold) {
if (alpha < scene_data.opaque_prepass_threshold) {
discard;
}

View file

@ -168,7 +168,8 @@ layout(set = 1, binding = 0, std140) uniform SceneData {
mediump float roughness_limiter_amount;
mediump float roughness_limiter_limit;
uvec2 roughness_limiter_pad;
mediump float opaque_prepass_threshold;
uint roughness_limiter_pad;
bool fog_enabled;
highp float fog_density;