Skip to content

Commit 5787f6f

Browse files
committed
Merge pull request #108044 from apples/107935-stencil-fixes
Fix opaque stencil rendering
2 parents c68213f + 62a5cd9 commit 5787f6f

File tree

6 files changed

+36
-8
lines changed

6 files changed

+36
-8
lines changed

drivers/gles3/rasterizer_scene_gles3.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2529,7 +2529,6 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_
25292529
scene_state.set_gl_depth_func(GL_GEQUAL);
25302530
scene_state.enable_gl_scissor_test(false);
25312531
scene_state.enable_gl_stencil_test(false);
2532-
scene_state.set_gl_stencil_write_mask(255);
25332532

25342533
glColorMask(0, 0, 0, 0);
25352534
RasterizerGLES3::clear_depth(0.0);
@@ -3084,7 +3083,7 @@ void RasterizerSceneGLES3::_render_list_template(RenderListParameters *p_params,
30843083
}
30853084

30863085
// Stencil.
3087-
if (shader->stencil_enabled) {
3086+
if (p_pass_mode != PASS_MODE_DEPTH && shader->stencil_enabled) {
30883087
static const GLenum stencil_compare_table[GLES3::SceneShaderData::STENCIL_COMPARE_MAX] = {
30893088
GL_LESS,
30903089
GL_EQUAL,
@@ -3121,7 +3120,6 @@ void RasterizerSceneGLES3::_render_list_template(RenderListParameters *p_params,
31213120
scene_state.set_gl_stencil_op(GL_KEEP, stencil_op_dpfail, stencil_op_dppass);
31223121
} else {
31233122
scene_state.enable_gl_stencil_test(false);
3124-
scene_state.set_gl_stencil_write_mask(255);
31253123
}
31263124

31273125
if constexpr (p_pass_mode == PASS_MODE_COLOR || p_pass_mode == PASS_MODE_COLOR_TRANSPARENT) {

servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -359,8 +359,9 @@ void SceneShaderForwardClustered::ShaderData::_create_pipeline(PipelineKey p_pip
359359
}
360360
}
361361

362-
depth_stencil_state.enable_stencil = stencil_enabled;
363-
if (stencil_enabled) {
362+
bool use_stencil = stencil_enabled && p_pipeline_key.version == PIPELINE_VERSION_COLOR_PASS;
363+
depth_stencil_state.enable_stencil = use_stencil;
364+
if (use_stencil) {
364365
static const RD::CompareOperator stencil_compare_rd_table[STENCIL_COMPARE_MAX] = {
365366
RD::COMPARE_OP_LESS,
366367
RD::COMPARE_OP_EQUAL,

servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ class SceneShaderForwardClustered {
293293

294294
_FORCE_INLINE_ bool uses_shared_shadow_material() const {
295295
bool backface_culling = cull_mode == RS::CULL_MODE_BACK;
296-
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;
296+
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;
297297
}
298298

299299
virtual void set_code(const String &p_Code);

servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -889,7 +889,11 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
889889

890890
// fill our render lists early so we can find out if we use various features
891891
_fill_render_list(RENDER_LIST_OPAQUE, p_render_data, PASS_MODE_COLOR);
892-
render_list[RENDER_LIST_OPAQUE].sort_by_key();
892+
if (scene_state.used_opaque_stencil) {
893+
render_list[RENDER_LIST_OPAQUE].sort_by_key_and_stencil();
894+
} else {
895+
render_list[RENDER_LIST_OPAQUE].sort_by_key();
896+
}
893897
render_list[RENDER_LIST_ALPHA].sort_by_reverse_depth_and_priority();
894898
_fill_instance_data(RENDER_LIST_OPAQUE);
895899
_fill_instance_data(RENDER_LIST_ALPHA);
@@ -2149,6 +2153,9 @@ void RenderForwardMobile::_fill_render_list(RenderListType p_render_list, const
21492153
if (surf->flags & GeometryInstanceSurfaceDataCache::FLAG_USES_DEPTH_TEXTURE) {
21502154
scene_state.used_depth_texture = true;
21512155
}
2156+
if ((surf->flags & GeometryInstanceSurfaceDataCache::FLAG_USES_STENCIL) && !force_alpha && (surf->flags & (GeometryInstanceSurfaceDataCache::FLAG_PASS_DEPTH | GeometryInstanceSurfaceDataCache::FLAG_PASS_OPAQUE))) {
2157+
scene_state.used_opaque_stencil = true;
2158+
}
21522159

21532160
} else if (p_pass_mode == PASS_MODE_SHADOW || p_pass_mode == PASS_MODE_SHADOW_DP) {
21542161
if (surf->flags & GeometryInstanceSurfaceDataCache::FLAG_PASS_SHADOW) {
@@ -2672,6 +2679,10 @@ void RenderForwardMobile::_geometry_instance_add_surface_with_material(GeometryI
26722679
flags |= GeometryInstanceSurfaceDataCache::FLAG_USES_DOUBLE_SIDED_SHADOWS;
26732680
}
26742681

2682+
if (p_material->shader_data->stencil_enabled) {
2683+
flags |= GeometryInstanceSurfaceDataCache::FLAG_USES_STENCIL;
2684+
}
2685+
26752686
if (p_material->shader_data->uses_alpha_pass()) {
26762687
flags |= GeometryInstanceSurfaceDataCache::FLAG_PASS_ALPHA;
26772688
if (p_material->shader_data->uses_depth_in_alpha_pass()) {

servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,7 @@ class RenderForwardMobile : public RendererSceneRenderRD {
289289
bool used_screen_texture = false;
290290
bool used_depth_texture = false;
291291
bool used_lightmap = false;
292+
bool used_opaque_stencil = false;
292293

293294
struct ShadowPass {
294295
uint32_t element_from;
@@ -338,6 +339,22 @@ class RenderForwardMobile : public RendererSceneRenderRD {
338339
sorter.sort(elements.ptr() + p_from, p_size);
339340
}
340341

342+
struct SortByKeyAndStencil {
343+
_FORCE_INLINE_ bool operator()(const GeometryInstanceSurfaceDataCache *A, const GeometryInstanceSurfaceDataCache *B) const {
344+
bool a_stencil = A->flags & GeometryInstanceSurfaceDataCache::FLAG_USES_STENCIL;
345+
bool b_stencil = B->flags & GeometryInstanceSurfaceDataCache::FLAG_USES_STENCIL;
346+
if (a_stencil != b_stencil) {
347+
return a_stencil < b_stencil;
348+
}
349+
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);
350+
}
351+
};
352+
353+
void sort_by_key_and_stencil() {
354+
SortArray<GeometryInstanceSurfaceDataCache *, SortByKeyAndStencil> sorter;
355+
sorter.sort(elements.ptr(), elements.size());
356+
}
357+
341358
struct SortByDepth {
342359
_FORCE_INLINE_ bool operator()(const GeometryInstanceSurfaceDataCache *A, const GeometryInstanceSurfaceDataCache *B) const {
343360
return (A->owner->depth < B->owner->depth);
@@ -448,6 +465,7 @@ class RenderForwardMobile : public RendererSceneRenderRD {
448465
FLAG_USES_NORMAL_TEXTURE = 16384,
449466
FLAG_USES_DOUBLE_SIDED_SHADOWS = 32768,
450467
FLAG_USES_PARTICLE_TRAILS = 65536,
468+
FLAG_USES_STENCIL = 131072,
451469
};
452470

453471
union {

servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ class SceneShaderForwardMobile {
290290
}
291291

292292
_FORCE_INLINE_ bool uses_shared_shadow_material() const {
293-
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;
293+
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;
294294
}
295295

296296
virtual void set_code(const String &p_Code);

0 commit comments

Comments
 (0)