You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-04 12:00:25 +00:00
Ignore depth draw optimization when using depth draw alpha prepass
This is necessary as the scene shader still uses alpha in this case so we can't discard fragments that weren't written to the depth buffer
This commit is contained in:
@@ -3465,7 +3465,7 @@ void RenderForwardClustered::_geometry_instance_add_surface_with_material(Geomet
|
||||
if (has_alpha || has_read_screen_alpha || p_material->shader_data->depth_draw == SceneShaderForwardClustered::ShaderData::DEPTH_DRAW_DISABLED || p_material->shader_data->depth_test == SceneShaderForwardClustered::ShaderData::DEPTH_TEST_DISABLED) {
|
||||
//material is only meant for alpha pass
|
||||
flags |= GeometryInstanceSurfaceDataCache::FLAG_PASS_ALPHA;
|
||||
if (p_material->shader_data->uses_depth_pre_pass && !(p_material->shader_data->depth_draw == SceneShaderForwardClustered::ShaderData::DEPTH_DRAW_DISABLED || p_material->shader_data->depth_test == SceneShaderForwardClustered::ShaderData::DEPTH_TEST_DISABLED)) {
|
||||
if (p_material->shader_data->uses_depth_prepass_alpha && !(p_material->shader_data->depth_draw == SceneShaderForwardClustered::ShaderData::DEPTH_DRAW_DISABLED || p_material->shader_data->depth_test == SceneShaderForwardClustered::ShaderData::DEPTH_TEST_DISABLED)) {
|
||||
flags |= GeometryInstanceSurfaceDataCache::FLAG_PASS_DEPTH;
|
||||
flags |= GeometryInstanceSurfaceDataCache::FLAG_PASS_SHADOW;
|
||||
}
|
||||
@@ -3481,7 +3481,7 @@ void RenderForwardClustered::_geometry_instance_add_surface_with_material(Geomet
|
||||
|
||||
SceneShaderForwardClustered::MaterialData *material_shadow = nullptr;
|
||||
void *surface_shadow = nullptr;
|
||||
if (!p_material->shader_data->uses_particle_trails && !p_material->shader_data->writes_modelview_or_projection && !p_material->shader_data->uses_vertex && !p_material->shader_data->uses_position && !p_material->shader_data->uses_discard && !p_material->shader_data->uses_depth_pre_pass && !p_material->shader_data->uses_alpha_clip && p_material->shader_data->cull_mode == SceneShaderForwardClustered::ShaderData::CULL_BACK && !p_material->shader_data->uses_point_size) {
|
||||
if (!p_material->shader_data->uses_particle_trails && !p_material->shader_data->writes_modelview_or_projection && !p_material->shader_data->uses_vertex && !p_material->shader_data->uses_position && !p_material->shader_data->uses_discard && !p_material->shader_data->uses_depth_prepass_alpha && !p_material->shader_data->uses_alpha_clip && p_material->shader_data->cull_mode == SceneShaderForwardClustered::ShaderData::CULL_BACK && !p_material->shader_data->uses_point_size) {
|
||||
flags |= GeometryInstanceSurfaceDataCache::FLAG_USES_SHARED_SHADOW_MATERIAL;
|
||||
material_shadow = static_cast<SceneShaderForwardClustered::MaterialData *>(RendererRD::MaterialStorage::get_singleton()->material_get_data(scene_shader.default_material, RendererRD::MaterialStorage::SHADER_TYPE_3D));
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
|
||||
uses_alpha = false;
|
||||
uses_alpha_clip = false;
|
||||
uses_blend_alpha = false;
|
||||
uses_depth_pre_pass = false;
|
||||
uses_depth_prepass_alpha = false;
|
||||
uses_discard = false;
|
||||
uses_roughness = false;
|
||||
uses_normal = false;
|
||||
@@ -114,7 +114,7 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
|
||||
// Use alpha clip pipeline for alpha hash/dither.
|
||||
// This prevents sorting issues inherent to alpha blending and allows such materials to cast shadows.
|
||||
actions.usage_flag_pointers["ALPHA_HASH_SCALE"] = &uses_alpha_clip;
|
||||
actions.render_mode_flags["depth_prepass_alpha"] = &uses_depth_pre_pass;
|
||||
actions.render_mode_flags["depth_prepass_alpha"] = &uses_depth_prepass_alpha;
|
||||
|
||||
actions.usage_flag_pointers["SSS_STRENGTH"] = &uses_sss;
|
||||
actions.usage_flag_pointers["SSS_TRANSMITTANCE_DEPTH"] = &uses_transmittance;
|
||||
@@ -309,10 +309,11 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
|
||||
}
|
||||
|
||||
RD::PipelineDepthStencilState depth_stencil = depth_stencil_state;
|
||||
if (depth_pre_pass_enabled && casts_shadows()) {
|
||||
if (depth_pre_pass_enabled && casts_shadows() && !uses_depth_prepass_alpha) {
|
||||
// We already have a depth from the depth pre-pass, there is no need to write it again.
|
||||
// In addition we can use COMPARE_OP_EQUAL instead of COMPARE_OP_LESS_OR_EQUAL.
|
||||
// This way we can use the early depth test to discard transparent fragments before the fragment shader even starts.
|
||||
// This cannot be used with depth_prepass_alpha as it uses a different threshold during the depth-prepass and regular drawing.
|
||||
depth_stencil.depth_compare_operator = RD::COMPARE_OP_EQUAL;
|
||||
depth_stencil.enable_depth_write = false;
|
||||
}
|
||||
@@ -394,7 +395,7 @@ bool SceneShaderForwardClustered::ShaderData::casts_shadows() const {
|
||||
bool has_base_alpha = (uses_alpha && !uses_alpha_clip) || has_read_screen_alpha;
|
||||
bool has_alpha = has_base_alpha || uses_blend_alpha;
|
||||
|
||||
return !has_alpha || (uses_depth_pre_pass && !(depth_draw == DEPTH_DRAW_DISABLED || depth_test == DEPTH_TEST_DISABLED));
|
||||
return !has_alpha || (uses_depth_prepass_alpha && !(depth_draw == DEPTH_DRAW_DISABLED || depth_test == DEPTH_TEST_DISABLED));
|
||||
}
|
||||
|
||||
RS::ShaderNativeSourceCode SceneShaderForwardClustered::ShaderData::get_native_source_code() const {
|
||||
|
||||
@@ -153,7 +153,7 @@ public:
|
||||
bool uses_alpha = false;
|
||||
bool uses_blend_alpha = false;
|
||||
bool uses_alpha_clip = false;
|
||||
bool uses_depth_pre_pass = false;
|
||||
bool uses_depth_prepass_alpha = false;
|
||||
bool uses_discard = false;
|
||||
bool uses_roughness = false;
|
||||
bool uses_normal = false;
|
||||
|
||||
Reference in New Issue
Block a user