Skip to content

Commit 7574a5d

Browse files
committed
Add depth function for spatial materials
1 parent 52ecb5a commit 7574a5d

File tree

14 files changed

+197
-34
lines changed

14 files changed

+197
-34
lines changed

doc/classes/BaseMaterial3D.xml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,10 @@
159159
<member name="depth_draw_mode" type="int" setter="set_depth_draw_mode" getter="get_depth_draw_mode" enum="BaseMaterial3D.DepthDrawMode" default="0">
160160
Determines when depth rendering takes place. See also [member transparency].
161161
</member>
162+
<member name="depth_test" type="int" setter="set_depth_test" getter="get_depth_test" enum="BaseMaterial3D.DepthTest" default="0" experimental="May be affected by future rendering pipeline changes.">
163+
Determines which comparison operator is used when testing depth. See [enum DepthTest].
164+
[b]Note:[/b] Changing [member depth_test] to a non-default value only has a visible effect when used on a transparent material, or a material that has [member depth_draw_mode] set to [constant DEPTH_DRAW_DISABLED].
165+
</member>
162166
<member name="detail_albedo" type="Texture2D" setter="set_texture" getter="get_texture">
163167
Texture that specifies the color of the detail overlay. [member detail_albedo]'s alpha channel is used as a mask, even when the material is opaque. To use a dedicated texture as a mask, see [member detail_mask].
164168
[b]Note:[/b] [member detail_albedo] is [i]not[/i] modulated by [member albedo_color].
@@ -661,6 +665,12 @@
661665
<constant name="DEPTH_DRAW_DISABLED" value="2" enum="DepthDrawMode">
662666
Objects will not write their depth to the depth buffer, even during the depth prepass (if enabled).
663667
</constant>
668+
<constant name="DEPTH_TEST_DEFAULT" value="0" enum="DepthTest">
669+
Depth test will discard the pixel if it is behind other pixels.
670+
</constant>
671+
<constant name="DEPTH_TEST_INVERTED" value="1" enum="DepthTest">
672+
Depth test will discard the pixel if it is in front of other pixels. Useful for stencil effects.
673+
</constant>
664674
<constant name="CULL_BACK" value="0" enum="CullMode">
665675
Default cull mode. The back of the object is culled when not visible. Back face triangles will be culled when facing the camera. This results in only the front side of triangles being drawn. For closed-surface meshes, this means that only the exterior of the mesh will be visible.
666676
</constant>

drivers/gles3/rasterizer_scene_gles3.cpp

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232

3333
#include "drivers/gles3/effects/copy_effects.h"
3434
#include "drivers/gles3/effects/feed_effects.h"
35+
#include "drivers/gles3/storage/material_storage.h"
3536
#include "rasterizer_gles3.h"
3637
#include "storage/config.h"
3738
#include "storage/mesh_storage.h"
@@ -223,10 +224,10 @@ void RasterizerSceneGLES3::_geometry_instance_add_surface_with_material(Geometry
223224
flags |= GeometryInstanceSurface::FLAG_USES_DOUBLE_SIDED_SHADOWS;
224225
}
225226

226-
if (has_alpha || has_read_screen_alpha || p_material->shader_data->depth_draw == GLES3::SceneShaderData::DEPTH_DRAW_DISABLED || p_material->shader_data->depth_test == GLES3::SceneShaderData::DEPTH_TEST_DISABLED) {
227+
if (has_alpha || has_read_screen_alpha || p_material->shader_data->depth_draw == GLES3::SceneShaderData::DEPTH_DRAW_DISABLED || p_material->shader_data->depth_test != GLES3::SceneShaderData::DEPTH_TEST_ENABLED) {
227228
//material is only meant for alpha pass
228229
flags |= GeometryInstanceSurface::FLAG_PASS_ALPHA;
229-
if (p_material->shader_data->uses_depth_prepass_alpha && !(p_material->shader_data->depth_draw == GLES3::SceneShaderData::DEPTH_DRAW_DISABLED || p_material->shader_data->depth_test == GLES3::SceneShaderData::DEPTH_TEST_DISABLED)) {
230+
if (p_material->shader_data->uses_depth_prepass_alpha && !(p_material->shader_data->depth_draw == GLES3::SceneShaderData::DEPTH_DRAW_DISABLED || p_material->shader_data->depth_test != GLES3::SceneShaderData::DEPTH_TEST_ENABLED)) {
230231
flags |= GeometryInstanceSurface::FLAG_PASS_DEPTH;
231232
flags |= GeometryInstanceSurface::FLAG_PASS_SHADOW;
232233
}
@@ -2184,7 +2185,7 @@ void RasterizerSceneGLES3::_render_shadow_pass(RID p_light, RID p_shadow_atlas,
21842185
scene_state.reset_gl_state();
21852186
scene_state.enable_gl_depth_test(true);
21862187
scene_state.enable_gl_depth_draw(true);
2187-
glDepthFunc(GL_GREATER);
2188+
scene_state.set_gl_depth_func(GL_GREATER);
21882189

21892190
glColorMask(0, 0, 0, 0);
21902191
glDrawBuffers(0, nullptr);
@@ -2503,7 +2504,7 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_
25032504
scene_state.enable_gl_depth_test(true);
25042505
scene_state.enable_gl_depth_draw(true);
25052506
scene_state.enable_gl_blend(false);
2506-
glDepthFunc(GL_GEQUAL);
2507+
scene_state.set_gl_depth_func(GL_GEQUAL);
25072508
scene_state.enable_gl_scissor_test(false);
25082509

25092510
glColorMask(0, 0, 0, 0);
@@ -2541,7 +2542,7 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_
25412542
scene_state.enable_gl_scissor_test(false);
25422543
scene_state.enable_gl_depth_test(true);
25432544
scene_state.enable_gl_depth_draw(true);
2544-
glDepthFunc(GL_GEQUAL);
2545+
scene_state.set_gl_depth_func(GL_GEQUAL);
25452546

25462547
{
25472548
GLuint db = GL_COLOR_ATTACHMENT0;
@@ -2635,6 +2636,7 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_
26352636
RENDER_TIMESTAMP("Render Sky");
26362637

26372638
scene_state.enable_gl_depth_test(true);
2639+
scene_state.set_gl_depth_func(GL_GEQUAL);
26382640
scene_state.enable_gl_blend(false);
26392641
scene_state.set_gl_cull_mode(RS::CULL_MODE_BACK);
26402642

@@ -3016,7 +3018,13 @@ void RasterizerSceneGLES3::_render_list_template(RenderListParameters *p_params,
30163018
}
30173019

30183020
if constexpr (p_pass_mode == PASS_MODE_COLOR_TRANSPARENT) {
3019-
scene_state.enable_gl_depth_test(shader->depth_test == GLES3::SceneShaderData::DEPTH_TEST_ENABLED);
3021+
scene_state.enable_gl_depth_test(shader->depth_test != GLES3::SceneShaderData::DEPTH_TEST_DISABLED);
3022+
}
3023+
3024+
if (shader->depth_test == GLES3::SceneShaderData::DEPTH_TEST_ENABLED_INVERTED) {
3025+
scene_state.set_gl_depth_func(GL_LESS);
3026+
} else {
3027+
scene_state.set_gl_depth_func(GL_GEQUAL);
30203028
}
30213029

30223030
if constexpr (p_pass_mode != PASS_MODE_SHADOW) {
@@ -3713,7 +3721,7 @@ void RasterizerSceneGLES3::render_particle_collider_heightfield(RID p_collider,
37133721
scene_state.reset_gl_state();
37143722
scene_state.enable_gl_depth_test(true);
37153723
scene_state.enable_gl_depth_draw(true);
3716-
glDepthFunc(GL_GREATER);
3724+
scene_state.set_gl_depth_func(GL_GREATER);
37173725

37183726
glDrawBuffers(0, nullptr);
37193727

@@ -3759,7 +3767,7 @@ void RasterizerSceneGLES3::_render_uv2(const PagedArray<RenderGeometryInstance *
37593767
scene_state.reset_gl_state();
37603768
scene_state.enable_gl_depth_test(true);
37613769
scene_state.enable_gl_depth_draw(true);
3762-
glDepthFunc(GL_GREATER);
3770+
scene_state.set_gl_depth_func(GL_GREATER);
37633771

37643772
TightLocalVector<GLenum> draw_buffers;
37653773
draw_buffers.push_back(GL_COLOR_ATTACHMENT0);
@@ -3852,7 +3860,7 @@ void RasterizerSceneGLES3::_render_buffers_debug_draw(Ref<RenderSceneBuffersGLES
38523860
glViewport(0, 0, shadow_atlas_size, shadow_atlas_size);
38533861
glActiveTexture(GL_TEXTURE0);
38543862
scene_state.enable_gl_depth_draw(true);
3855-
glDepthFunc(GL_ALWAYS);
3863+
scene_state.set_gl_depth_func(GL_ALWAYS);
38563864
scene_state.set_gl_cull_mode(RS::CULL_MODE_DISABLED);
38573865

38583866
// Loop through quadrants and copy shadows over.

drivers/gles3/rasterizer_scene_gles3.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030

3131
#pragma once
3232

33+
#include "platform_gl.h"
3334
#ifdef GLES3_ENABLED
3435

3536
#include "core/math/projection.h"
@@ -462,6 +463,7 @@ class RasterizerSceneGLES3 : public RendererSceneRender {
462463

463464
GLES3::SceneShaderData::BlendMode current_blend_mode = GLES3::SceneShaderData::BLEND_MODE_MIX;
464465
RS::CullMode cull_mode = RS::CULL_MODE_BACK;
466+
GLenum current_depth_function = GL_GEQUAL;
465467

466468
bool current_blend_enabled = false;
467469
bool current_depth_draw_enabled = false;
@@ -483,6 +485,9 @@ class RasterizerSceneGLES3 : public RendererSceneRender {
483485
current_depth_draw_enabled = false;
484486
glDisable(GL_DEPTH_TEST);
485487
current_depth_test_enabled = false;
488+
489+
glDepthFunc(GL_GEQUAL);
490+
current_depth_function = GL_GEQUAL;
486491
}
487492

488493
void set_gl_cull_mode(RS::CullMode p_mode) {
@@ -540,6 +545,13 @@ class RasterizerSceneGLES3 : public RendererSceneRender {
540545
}
541546
}
542547

548+
void set_gl_depth_func(GLenum p_depth_func) {
549+
if (current_depth_function != p_depth_func) {
550+
glDepthFunc(p_depth_func);
551+
current_depth_function = p_depth_func;
552+
}
553+
}
554+
543555
bool texscreen_copied = false;
544556
bool used_screen_texture = false;
545557
bool used_normal_texture = false;

drivers/gles3/storage/material_storage.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2941,7 +2941,8 @@ void SceneShaderData::set_code(const String &p_code) {
29412941

29422942
// Actual enums set further down after compilation.
29432943
int blend_modei = BLEND_MODE_MIX;
2944-
int depth_testi = DEPTH_TEST_ENABLED;
2944+
int depth_test_disabledi = 0;
2945+
int depth_test_invertedi = 0;
29452946
int alpha_antialiasing_modei = ALPHA_ANTIALIASING_OFF;
29462947
int cull_modei = RS::CULL_MODE_BACK;
29472948
int depth_drawi = DEPTH_DRAW_OPAQUE;
@@ -2964,7 +2965,8 @@ void SceneShaderData::set_code(const String &p_code) {
29642965
actions.render_mode_values["depth_draw_opaque"] = Pair<int *, int>(&depth_drawi, DEPTH_DRAW_OPAQUE);
29652966
actions.render_mode_values["depth_draw_always"] = Pair<int *, int>(&depth_drawi, DEPTH_DRAW_ALWAYS);
29662967

2967-
actions.render_mode_values["depth_test_disabled"] = Pair<int *, int>(&depth_testi, DEPTH_TEST_DISABLED);
2968+
actions.render_mode_values["depth_test_disabled"] = Pair<int *, int>(&depth_test_disabledi, 1);
2969+
actions.render_mode_values["depth_test_inverted"] = Pair<int *, int>(&depth_test_invertedi, 1);
29682970

29692971
actions.render_mode_values["cull_disabled"] = Pair<int *, int>(&cull_modei, RS::CULL_MODE_DISABLED);
29702972
actions.render_mode_values["cull_front"] = Pair<int *, int>(&cull_modei, RS::CULL_MODE_FRONT);
@@ -3026,7 +3028,13 @@ void SceneShaderData::set_code(const String &p_code) {
30263028
blend_mode = BlendMode(blend_modei);
30273029
alpha_antialiasing_mode = AlphaAntiAliasing(alpha_antialiasing_modei);
30283030
depth_draw = DepthDraw(depth_drawi);
3029-
depth_test = DepthTest(depth_testi);
3031+
if (depth_test_disabledi) {
3032+
depth_test = DEPTH_TEST_DISABLED;
3033+
} else if (depth_test_invertedi) {
3034+
depth_test = DEPTH_TEST_ENABLED_INVERTED;
3035+
} else {
3036+
depth_test = DEPTH_TEST_ENABLED;
3037+
}
30303038
cull_mode = RS::CullMode(cull_modei);
30313039

30323040
vertex_input_mask = RS::ARRAY_FORMAT_VERTEX | RS::ARRAY_FORMAT_NORMAL; // We can always read vertices and normals.
@@ -3114,7 +3122,7 @@ bool SceneShaderData::casts_shadows() const {
31143122
bool has_base_alpha = (uses_alpha && !uses_alpha_clip) || has_read_screen_alpha;
31153123
bool has_alpha = has_base_alpha || uses_blend_alpha;
31163124

3117-
return !has_alpha || (uses_depth_prepass_alpha && !(depth_draw == DEPTH_DRAW_DISABLED || depth_test == DEPTH_TEST_DISABLED));
3125+
return !has_alpha || (uses_depth_prepass_alpha && !(depth_draw == DEPTH_DRAW_DISABLED || depth_test != DEPTH_TEST_ENABLED));
31183126
}
31193127

31203128
RS::ShaderNativeSourceCode SceneShaderData::get_native_source_code() const {

drivers/gles3/storage/material_storage.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,8 @@ struct SceneShaderData : public ShaderData {
257257

258258
enum DepthTest {
259259
DEPTH_TEST_DISABLED,
260-
DEPTH_TEST_ENABLED
260+
DEPTH_TEST_ENABLED,
261+
DEPTH_TEST_ENABLED_INVERTED,
261262
};
262263

263264
enum AlphaAntiAliasing {

scene/resources/material.cpp

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -861,6 +861,17 @@ void BaseMaterial3D::_update_shader() {
861861
}
862862
if (flags[FLAG_DISABLE_DEPTH_TEST]) {
863863
code += ", depth_test_disabled";
864+
} else {
865+
switch (depth_test) {
866+
case DEPTH_TEST_DEFAULT:
867+
// depth_test_default is the default behavior, no need to emit it here.
868+
break;
869+
case DEPTH_TEST_INVERTED:
870+
code += ", depth_test_inverted";
871+
break;
872+
case DEPTH_TEST_MAX:
873+
break; // Internal value, skip.
874+
}
864875
}
865876
if (flags[FLAG_PARTICLE_TRAILS_MODE]) {
866877
code += ", particle_trails";
@@ -2354,6 +2365,19 @@ BaseMaterial3D::DepthDrawMode BaseMaterial3D::get_depth_draw_mode() const {
23542365
return depth_draw_mode;
23552366
}
23562367

2368+
void BaseMaterial3D::set_depth_test(DepthTest p_func) {
2369+
if (depth_test == p_func) {
2370+
return;
2371+
}
2372+
2373+
depth_test = p_func;
2374+
_queue_shader_change();
2375+
}
2376+
2377+
BaseMaterial3D::DepthTest BaseMaterial3D::get_depth_test() const {
2378+
return depth_test;
2379+
}
2380+
23572381
void BaseMaterial3D::set_cull_mode(CullMode p_mode) {
23582382
if (cull_mode == p_mode) {
23592383
return;
@@ -2410,7 +2434,8 @@ void BaseMaterial3D::set_flag(Flags p_flag, bool p_enabled) {
24102434
p_flag == FLAG_UV1_USE_TRIPLANAR ||
24112435
p_flag == FLAG_UV2_USE_TRIPLANAR ||
24122436
p_flag == FLAG_USE_Z_CLIP_SCALE ||
2413-
p_flag == FLAG_USE_FOV_OVERRIDE) {
2437+
p_flag == FLAG_USE_FOV_OVERRIDE ||
2438+
p_flag == FLAG_DISABLE_DEPTH_TEST) {
24142439
notify_property_list_changed();
24152440
}
24162441

@@ -2565,6 +2590,10 @@ void BaseMaterial3D::_validate_property(PropertyInfo &p_property) const {
25652590
p_property.usage = PROPERTY_USAGE_NONE;
25662591
}
25672592

2593+
if (p_property.name == "depth_test" && flags[FLAG_DISABLE_DEPTH_TEST]) {
2594+
p_property.usage = PROPERTY_USAGE_NONE;
2595+
}
2596+
25682597
if (flags[FLAG_SUBSURFACE_MODE_SKIN] && (p_property.name == "subsurf_scatter_transmittance_color" || p_property.name == "subsurf_scatter_transmittance_texture")) {
25692598
p_property.usage = PROPERTY_USAGE_NONE;
25702599
}
@@ -3133,6 +3162,9 @@ void BaseMaterial3D::_bind_methods() {
31333162
ClassDB::bind_method(D_METHOD("set_depth_draw_mode", "depth_draw_mode"), &BaseMaterial3D::set_depth_draw_mode);
31343163
ClassDB::bind_method(D_METHOD("get_depth_draw_mode"), &BaseMaterial3D::get_depth_draw_mode);
31353164

3165+
ClassDB::bind_method(D_METHOD("set_depth_test", "depth_test"), &BaseMaterial3D::set_depth_test);
3166+
ClassDB::bind_method(D_METHOD("get_depth_test"), &BaseMaterial3D::get_depth_test);
3167+
31363168
ClassDB::bind_method(D_METHOD("set_cull_mode", "cull_mode"), &BaseMaterial3D::set_cull_mode);
31373169
ClassDB::bind_method(D_METHOD("get_cull_mode"), &BaseMaterial3D::get_cull_mode);
31383170

@@ -3269,6 +3301,7 @@ void BaseMaterial3D::_bind_methods() {
32693301
ADD_PROPERTY(PropertyInfo(Variant::INT, "cull_mode", PROPERTY_HINT_ENUM, "Back,Front,Disabled"), "set_cull_mode", "get_cull_mode");
32703302
ADD_PROPERTY(PropertyInfo(Variant::INT, "depth_draw_mode", PROPERTY_HINT_ENUM, "Opaque Only,Always,Never"), "set_depth_draw_mode", "get_depth_draw_mode");
32713303
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "no_depth_test"), "set_flag", "get_flag", FLAG_DISABLE_DEPTH_TEST);
3304+
ADD_PROPERTY(PropertyInfo(Variant::INT, "depth_test", PROPERTY_HINT_ENUM, "Default,Inverted"), "set_depth_test", "get_depth_test");
32723305

32733306
ADD_GROUP("Shading", "");
32743307
ADD_PROPERTY(PropertyInfo(Variant::INT, "shading_mode", PROPERTY_HINT_ENUM, "Unshaded,Per-Pixel,Per-Vertex"), "set_shading_mode", "get_shading_mode");
@@ -3518,6 +3551,9 @@ void BaseMaterial3D::_bind_methods() {
35183551
BIND_ENUM_CONSTANT(DEPTH_DRAW_ALWAYS);
35193552
BIND_ENUM_CONSTANT(DEPTH_DRAW_DISABLED);
35203553

3554+
BIND_ENUM_CONSTANT(DEPTH_TEST_DEFAULT);
3555+
BIND_ENUM_CONSTANT(DEPTH_TEST_INVERTED);
3556+
35213557
BIND_ENUM_CONSTANT(CULL_BACK);
35223558
BIND_ENUM_CONSTANT(CULL_FRONT);
35233559
BIND_ENUM_CONSTANT(CULL_DISABLED);

scene/resources/material.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,12 @@ class BaseMaterial3D : public Material {
238238
DEPTH_DRAW_MAX
239239
};
240240

241+
enum DepthTest {
242+
DEPTH_TEST_DEFAULT,
243+
DEPTH_TEST_INVERTED,
244+
DEPTH_TEST_MAX
245+
};
246+
241247
enum CullMode {
242248
CULL_BACK,
243249
CULL_FRONT,
@@ -330,6 +336,7 @@ class BaseMaterial3D : public Material {
330336
uint64_t shading_mode : get_num_bits(SHADING_MODE_MAX - 1);
331337
uint64_t blend_mode : get_num_bits(BLEND_MODE_MAX - 1);
332338
uint64_t depth_draw_mode : get_num_bits(DEPTH_DRAW_MAX - 1);
339+
uint64_t depth_test : get_num_bits(DEPTH_TEST_MAX - 1);
333340
uint64_t cull_mode : get_num_bits(CULL_MAX - 1);
334341
uint64_t diffuse_mode : get_num_bits(DIFFUSE_MAX - 1);
335342
uint64_t specular_mode : get_num_bits(SPECULAR_MAX - 1);
@@ -381,6 +388,7 @@ class BaseMaterial3D : public Material {
381388
mk.detail_uv = detail_uv;
382389
mk.blend_mode = blend_mode;
383390
mk.depth_draw_mode = depth_draw_mode;
391+
mk.depth_test = depth_test;
384392
mk.cull_mode = cull_mode;
385393
mk.texture_filter = texture_filter;
386394
mk.transparency = transparency;
@@ -553,6 +561,7 @@ class BaseMaterial3D : public Material {
553561
BlendMode blend_mode = BLEND_MODE_MIX;
554562
BlendMode detail_blend_mode = BLEND_MODE_MIX;
555563
DepthDrawMode depth_draw_mode = DEPTH_DRAW_OPAQUE_ONLY;
564+
DepthTest depth_test = DEPTH_TEST_DEFAULT;
556565
CullMode cull_mode = CULL_BACK;
557566
bool flags[FLAG_MAX] = {};
558567
SpecularMode specular_mode = SPECULAR_SCHLICK_GGX;
@@ -688,6 +697,9 @@ class BaseMaterial3D : public Material {
688697
void set_depth_draw_mode(DepthDrawMode p_mode);
689698
DepthDrawMode get_depth_draw_mode() const;
690699

700+
void set_depth_test(DepthTest p_func);
701+
DepthTest get_depth_test() const;
702+
691703
void set_cull_mode(CullMode p_mode);
692704
CullMode get_cull_mode() const;
693705

@@ -816,6 +828,7 @@ VARIANT_ENUM_CAST(BaseMaterial3D::DetailUV)
816828
VARIANT_ENUM_CAST(BaseMaterial3D::Feature)
817829
VARIANT_ENUM_CAST(BaseMaterial3D::BlendMode)
818830
VARIANT_ENUM_CAST(BaseMaterial3D::DepthDrawMode)
831+
VARIANT_ENUM_CAST(BaseMaterial3D::DepthTest)
819832
VARIANT_ENUM_CAST(BaseMaterial3D::CullMode)
820833
VARIANT_ENUM_CAST(BaseMaterial3D::Flags)
821834
VARIANT_ENUM_CAST(BaseMaterial3D::DiffuseMode)

0 commit comments

Comments
 (0)