mirror of
https://github.com/godotengine/godot.git
synced 2025-10-19 16:03:29 +00:00
Merge pull request #108044 from apples/107935-stencil-fixes
Fix opaque stencil rendering
This commit is contained in:
commit
5787f6fb6a
6 changed files with 36 additions and 8 deletions
|
@ -2529,7 +2529,6 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_
|
|||
scene_state.set_gl_depth_func(GL_GEQUAL);
|
||||
scene_state.enable_gl_scissor_test(false);
|
||||
scene_state.enable_gl_stencil_test(false);
|
||||
scene_state.set_gl_stencil_write_mask(255);
|
||||
|
||||
glColorMask(0, 0, 0, 0);
|
||||
RasterizerGLES3::clear_depth(0.0);
|
||||
|
@ -3084,7 +3083,7 @@ void RasterizerSceneGLES3::_render_list_template(RenderListParameters *p_params,
|
|||
}
|
||||
|
||||
// Stencil.
|
||||
if (shader->stencil_enabled) {
|
||||
if (p_pass_mode != PASS_MODE_DEPTH && shader->stencil_enabled) {
|
||||
static const GLenum stencil_compare_table[GLES3::SceneShaderData::STENCIL_COMPARE_MAX] = {
|
||||
GL_LESS,
|
||||
GL_EQUAL,
|
||||
|
@ -3121,7 +3120,6 @@ void RasterizerSceneGLES3::_render_list_template(RenderListParameters *p_params,
|
|||
scene_state.set_gl_stencil_op(GL_KEEP, stencil_op_dpfail, stencil_op_dppass);
|
||||
} else {
|
||||
scene_state.enable_gl_stencil_test(false);
|
||||
scene_state.set_gl_stencil_write_mask(255);
|
||||
}
|
||||
|
||||
if constexpr (p_pass_mode == PASS_MODE_COLOR || p_pass_mode == PASS_MODE_COLOR_TRANSPARENT) {
|
||||
|
|
|
@ -359,8 +359,9 @@ void SceneShaderForwardClustered::ShaderData::_create_pipeline(PipelineKey p_pip
|
|||
}
|
||||
}
|
||||
|
||||
depth_stencil_state.enable_stencil = stencil_enabled;
|
||||
if (stencil_enabled) {
|
||||
bool use_stencil = stencil_enabled && p_pipeline_key.version == PIPELINE_VERSION_COLOR_PASS;
|
||||
depth_stencil_state.enable_stencil = use_stencil;
|
||||
if (use_stencil) {
|
||||
static const RD::CompareOperator stencil_compare_rd_table[STENCIL_COMPARE_MAX] = {
|
||||
RD::COMPARE_OP_LESS,
|
||||
RD::COMPARE_OP_EQUAL,
|
||||
|
|
|
@ -293,7 +293,7 @@ public:
|
|||
|
||||
_FORCE_INLINE_ bool uses_shared_shadow_material() const {
|
||||
bool backface_culling = cull_mode == RS::CULL_MODE_BACK;
|
||||
return !uses_particle_trails && !writes_modelview_or_projection && !uses_vertex && !uses_position && !uses_discard && !uses_depth_prepass_alpha && !uses_alpha_clip && !uses_alpha_antialiasing && backface_culling && !uses_point_size && !uses_world_coordinates && !wireframe && !uses_z_clip_scale;
|
||||
return !uses_particle_trails && !writes_modelview_or_projection && !uses_vertex && !uses_position && !uses_discard && !uses_depth_prepass_alpha && !uses_alpha_clip && !uses_alpha_antialiasing && backface_culling && !uses_point_size && !uses_world_coordinates && !wireframe && !uses_z_clip_scale && !stencil_enabled;
|
||||
}
|
||||
|
||||
virtual void set_code(const String &p_Code);
|
||||
|
|
|
@ -889,7 +889,11 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
|
|||
|
||||
// fill our render lists early so we can find out if we use various features
|
||||
_fill_render_list(RENDER_LIST_OPAQUE, p_render_data, PASS_MODE_COLOR);
|
||||
render_list[RENDER_LIST_OPAQUE].sort_by_key();
|
||||
if (scene_state.used_opaque_stencil) {
|
||||
render_list[RENDER_LIST_OPAQUE].sort_by_key_and_stencil();
|
||||
} else {
|
||||
render_list[RENDER_LIST_OPAQUE].sort_by_key();
|
||||
}
|
||||
render_list[RENDER_LIST_ALPHA].sort_by_reverse_depth_and_priority();
|
||||
_fill_instance_data(RENDER_LIST_OPAQUE);
|
||||
_fill_instance_data(RENDER_LIST_ALPHA);
|
||||
|
@ -2149,6 +2153,9 @@ void RenderForwardMobile::_fill_render_list(RenderListType p_render_list, const
|
|||
if (surf->flags & GeometryInstanceSurfaceDataCache::FLAG_USES_DEPTH_TEXTURE) {
|
||||
scene_state.used_depth_texture = true;
|
||||
}
|
||||
if ((surf->flags & GeometryInstanceSurfaceDataCache::FLAG_USES_STENCIL) && !force_alpha && (surf->flags & (GeometryInstanceSurfaceDataCache::FLAG_PASS_DEPTH | GeometryInstanceSurfaceDataCache::FLAG_PASS_OPAQUE))) {
|
||||
scene_state.used_opaque_stencil = true;
|
||||
}
|
||||
|
||||
} else if (p_pass_mode == PASS_MODE_SHADOW || p_pass_mode == PASS_MODE_SHADOW_DP) {
|
||||
if (surf->flags & GeometryInstanceSurfaceDataCache::FLAG_PASS_SHADOW) {
|
||||
|
@ -2672,6 +2679,10 @@ void RenderForwardMobile::_geometry_instance_add_surface_with_material(GeometryI
|
|||
flags |= GeometryInstanceSurfaceDataCache::FLAG_USES_DOUBLE_SIDED_SHADOWS;
|
||||
}
|
||||
|
||||
if (p_material->shader_data->stencil_enabled) {
|
||||
flags |= GeometryInstanceSurfaceDataCache::FLAG_USES_STENCIL;
|
||||
}
|
||||
|
||||
if (p_material->shader_data->uses_alpha_pass()) {
|
||||
flags |= GeometryInstanceSurfaceDataCache::FLAG_PASS_ALPHA;
|
||||
if (p_material->shader_data->uses_depth_in_alpha_pass()) {
|
||||
|
|
|
@ -289,6 +289,7 @@ private:
|
|||
bool used_screen_texture = false;
|
||||
bool used_depth_texture = false;
|
||||
bool used_lightmap = false;
|
||||
bool used_opaque_stencil = false;
|
||||
|
||||
struct ShadowPass {
|
||||
uint32_t element_from;
|
||||
|
@ -338,6 +339,22 @@ private:
|
|||
sorter.sort(elements.ptr() + p_from, p_size);
|
||||
}
|
||||
|
||||
struct SortByKeyAndStencil {
|
||||
_FORCE_INLINE_ bool operator()(const GeometryInstanceSurfaceDataCache *A, const GeometryInstanceSurfaceDataCache *B) const {
|
||||
bool a_stencil = A->flags & GeometryInstanceSurfaceDataCache::FLAG_USES_STENCIL;
|
||||
bool b_stencil = B->flags & GeometryInstanceSurfaceDataCache::FLAG_USES_STENCIL;
|
||||
if (a_stencil != b_stencil) {
|
||||
return a_stencil < b_stencil;
|
||||
}
|
||||
return (A->sort.sort_key2 == B->sort.sort_key2) ? (A->sort.sort_key1 < B->sort.sort_key1) : (A->sort.sort_key2 < B->sort.sort_key2);
|
||||
}
|
||||
};
|
||||
|
||||
void sort_by_key_and_stencil() {
|
||||
SortArray<GeometryInstanceSurfaceDataCache *, SortByKeyAndStencil> sorter;
|
||||
sorter.sort(elements.ptr(), elements.size());
|
||||
}
|
||||
|
||||
struct SortByDepth {
|
||||
_FORCE_INLINE_ bool operator()(const GeometryInstanceSurfaceDataCache *A, const GeometryInstanceSurfaceDataCache *B) const {
|
||||
return (A->owner->depth < B->owner->depth);
|
||||
|
@ -448,6 +465,7 @@ protected:
|
|||
FLAG_USES_NORMAL_TEXTURE = 16384,
|
||||
FLAG_USES_DOUBLE_SIDED_SHADOWS = 32768,
|
||||
FLAG_USES_PARTICLE_TRAILS = 65536,
|
||||
FLAG_USES_STENCIL = 131072,
|
||||
};
|
||||
|
||||
union {
|
||||
|
|
|
@ -290,7 +290,7 @@ public:
|
|||
}
|
||||
|
||||
_FORCE_INLINE_ bool uses_shared_shadow_material() const {
|
||||
return !uses_particle_trails && !writes_modelview_or_projection && !uses_vertex && !uses_discard && !uses_depth_prepass_alpha && !uses_alpha_clip && !uses_alpha_antialiasing && !uses_world_coordinates && !wireframe;
|
||||
return !uses_particle_trails && !writes_modelview_or_projection && !uses_vertex && !uses_discard && !uses_depth_prepass_alpha && !uses_alpha_clip && !uses_alpha_antialiasing && !uses_world_coordinates && !wireframe && !stencil_enabled;
|
||||
}
|
||||
|
||||
virtual void set_code(const String &p_Code);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue