Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement distance fade and transparency #54222

Merged
merged 2 commits into from
Oct 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion doc/classes/GeometryInstance3D.xml
Original file line number Diff line number Diff line change
Expand Up @@ -49,18 +49,24 @@
The material override for the whole geometry.
If a material is assigned to this property, it will be used instead of any material set in any material slot of the mesh.
</member>
<member name="transparency" type="float" setter="set_transparency" getter="get_transparency" default="0.0">
Transparency applied to the whole geometry. In spatial shaders, transparency is set as the default value of the [code]ALPHA[/code] built-in.
</member>
<member name="visibility_range_begin" type="float" setter="set_visibility_range_begin" getter="get_visibility_range_begin" default="0.0">
Starting distance from which the GeometryInstance3D will be visible, taking [member visibility_range_begin_margin] into account as well. The default value of 0 is used to disable the range check.
</member>
<member name="visibility_range_begin_margin" type="float" setter="set_visibility_range_begin_margin" getter="get_visibility_range_begin_margin" default="0.0">
Margin for the [member visibility_range_begin] threshold. The GeometryInstance3D will only change its visibility state when it goes over or under the [member visibility_range_begin] threshold by this amount.
</member>
<member name="visibility_range_end" type="float" setter="set_visibility_range_end" getter="get_visibility_range_end" default="0.0">
Distance from which the GeometryInstance3D will be hidden, taking [member visibility_range_end_margin] into account as well. The default value of 0 is used to disable the range check..
Distance from which the GeometryInstance3D will be hidden, taking [member visibility_range_end_margin] into account as well. The default value of 0 is used to disable the range check.
</member>
<member name="visibility_range_end_margin" type="float" setter="set_visibility_range_end_margin" getter="get_visibility_range_end_margin" default="0.0">
Margin for the [member visibility_range_end] threshold. The GeometryInstance3D will only change its visibility state when it goes over or under the [member visibility_range_end] threshold by this amount.
</member>
<member name="visibility_range_fade_mode" type="int" setter="set_visibility_range_fade_mode" getter="get_visibility_range_fade_mode" enum="GeometryInstance3D.VisibilityRangeFadeMode" default="0">
Controls which instances will be faded when approaching the limits of the visibility range. See [enum VisibilityRangeFadeMode] for possible values.
</member>
</members>
<constants>
<constant name="SHADOW_CASTING_SETTING_OFF" value="0" enum="ShadowCastingSetting">
Expand Down Expand Up @@ -94,5 +100,14 @@
</constant>
<constant name="LIGHTMAP_SCALE_MAX" value="4" enum="LightmapScale">
</constant>
<constant name="VISIBILITY_RANGE_FADE_DISABLED" value="0" enum="VisibilityRangeFadeMode">
Will not fade itself nor its visibility dependencies, hysteresis will be used instead. See [member visibility_range_begin] and [member Node3D.visibility_parent] for more information.
</constant>
<constant name="VISIBILITY_RANGE_FADE_SELF" value="1" enum="VisibilityRangeFadeMode">
Will fade-out itself when reaching the limits of its own visibility range. The fading range is determined by [member visibility_range_begin_margin] and [member visibility_range_end_margin].
</constant>
<constant name="VISIBILITY_RANGE_FADE_DEPENDENCIES" value="2" enum="VisibilityRangeFadeMode">
Will fade-in its visibility dependencies (see [member Node3D.visibility_parent]) when reaching the limits of its own visibility range. The fading range is determined by [member visibility_range_begin_margin] and [member visibility_range_end_margin].
</constant>
</constants>
</class>
18 changes: 18 additions & 0 deletions doc/classes/RenderingServer.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1377,13 +1377,22 @@
<description>
</description>
</method>
<method name="instance_geometry_set_transparency">
<return type="void" />
<argument index="0" name="instance" type="RID" />
<argument index="1" name="transparency" type="float" />
<description>
Sets the transparency for the given geometry instance. Equivalent to [member GeometryInstance3D.transparency].
</description>
</method>
<method name="instance_geometry_set_visibility_range">
<return type="void" />
<argument index="0" name="instance" type="RID" />
<argument index="1" name="min" type="float" />
<argument index="2" name="max" type="float" />
<argument index="3" name="min_margin" type="float" />
<argument index="4" name="max_margin" type="float" />
<argument index="5" name="fade_mode" type="int" enum="RenderingServer.VisibilityRangeFadeMode" />
<description>
Sets the visibility range values for the given geometry instance. Equivalent to [member GeometryInstance3D.visibility_range_begin] and related properties.
</description>
Expand Down Expand Up @@ -4178,6 +4187,15 @@
<constant name="SHADOW_CASTING_SETTING_SHADOWS_ONLY" value="3" enum="ShadowCastingSetting">
Only render the shadows from the object. The object itself will not be drawn.
</constant>
<constant name="VISIBILITY_RANGE_FADE_DISABLED" value="0" enum="VisibilityRangeFadeMode">
Disable visibility range fading for the given instance.
</constant>
<constant name="VISIBILITY_RANGE_FADE_SELF" value="1" enum="VisibilityRangeFadeMode">
Fade-out the given instance when it approaches its visibility range limits.
</constant>
<constant name="VISIBILITY_RANGE_FADE_DEPENDENCIES" value="2" enum="VisibilityRangeFadeMode">
Fade-in the given instance's dependencies when reaching its visibility range limits.
</constant>
<constant name="BAKE_CHANNEL_ALBEDO_ALPHA" value="0" enum="BakeChannels">
</constant>
<constant name="BAKE_CHANNEL_NORMAL" value="1" enum="BakeChannels">
Expand Down
39 changes: 34 additions & 5 deletions scene/3d/visual_instance_3d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,18 @@ Ref<Material> GeometryInstance3D::get_material_override() const {
return material_override;
}

void GeometryInstance3D::set_transparecy(float p_transparency) {
transparency = CLAMP(p_transparency, 0.0f, 1.0f);
RS::get_singleton()->instance_geometry_set_transparency(get_instance(), transparency);
}

float GeometryInstance3D::get_transparency() const {
return transparency;
}

void GeometryInstance3D::set_visibility_range_begin(float p_dist) {
visibility_range_begin = p_dist;
RS::get_singleton()->instance_geometry_set_visibility_range(get_instance(), visibility_range_begin, visibility_range_end, visibility_range_begin_margin, visibility_range_end_margin);
RS::get_singleton()->instance_geometry_set_visibility_range(get_instance(), visibility_range_begin, visibility_range_end, visibility_range_begin_margin, visibility_range_end_margin, (RS::VisibilityRangeFadeMode)visibility_range_fade_mode);
update_configuration_warnings();
}

Expand All @@ -164,7 +173,7 @@ float GeometryInstance3D::get_visibility_range_begin() const {

void GeometryInstance3D::set_visibility_range_end(float p_dist) {
visibility_range_end = p_dist;
RS::get_singleton()->instance_geometry_set_visibility_range(get_instance(), visibility_range_begin, visibility_range_end, visibility_range_begin_margin, visibility_range_end_margin);
RS::get_singleton()->instance_geometry_set_visibility_range(get_instance(), visibility_range_begin, visibility_range_end, visibility_range_begin_margin, visibility_range_end_margin, (RS::VisibilityRangeFadeMode)visibility_range_fade_mode);
update_configuration_warnings();
}

Expand All @@ -174,7 +183,7 @@ float GeometryInstance3D::get_visibility_range_end() const {

void GeometryInstance3D::set_visibility_range_begin_margin(float p_dist) {
visibility_range_begin_margin = p_dist;
RS::get_singleton()->instance_geometry_set_visibility_range(get_instance(), visibility_range_begin, visibility_range_end, visibility_range_begin_margin, visibility_range_end_margin);
RS::get_singleton()->instance_geometry_set_visibility_range(get_instance(), visibility_range_begin, visibility_range_end, visibility_range_begin_margin, visibility_range_end_margin, (RS::VisibilityRangeFadeMode)visibility_range_fade_mode);
}

float GeometryInstance3D::get_visibility_range_begin_margin() const {
Expand All @@ -183,13 +192,22 @@ float GeometryInstance3D::get_visibility_range_begin_margin() const {

void GeometryInstance3D::set_visibility_range_end_margin(float p_dist) {
visibility_range_end_margin = p_dist;
RS::get_singleton()->instance_geometry_set_visibility_range(get_instance(), visibility_range_begin, visibility_range_end, visibility_range_begin_margin, visibility_range_end_margin);
RS::get_singleton()->instance_geometry_set_visibility_range(get_instance(), visibility_range_begin, visibility_range_end, visibility_range_begin_margin, visibility_range_end_margin, (RS::VisibilityRangeFadeMode)visibility_range_fade_mode);
}

float GeometryInstance3D::get_visibility_range_end_margin() const {
return visibility_range_end_margin;
}

void GeometryInstance3D::set_visibility_range_fade_mode(VisibilityRangeFadeMode p_mode) {
visibility_range_fade_mode = p_mode;
RS::get_singleton()->instance_geometry_set_visibility_range(get_instance(), visibility_range_begin, visibility_range_end, visibility_range_begin_margin, visibility_range_end_margin, (RS::VisibilityRangeFadeMode)visibility_range_fade_mode);
}

GeometryInstance3D::VisibilityRangeFadeMode GeometryInstance3D::get_visibility_range_fade_mode() const {
return visibility_range_fade_mode;
}

void GeometryInstance3D::_notification(int p_what) {
}

Expand Down Expand Up @@ -375,6 +393,9 @@ void GeometryInstance3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_lod_bias", "bias"), &GeometryInstance3D::set_lod_bias);
ClassDB::bind_method(D_METHOD("get_lod_bias"), &GeometryInstance3D::get_lod_bias);

ClassDB::bind_method(D_METHOD("set_transparency", "transparency"), &GeometryInstance3D::set_transparecy);
ClassDB::bind_method(D_METHOD("get_transparency"), &GeometryInstance3D::get_transparency);

ClassDB::bind_method(D_METHOD("set_visibility_range_end_margin", "distance"), &GeometryInstance3D::set_visibility_range_end_margin);
ClassDB::bind_method(D_METHOD("get_visibility_range_end_margin"), &GeometryInstance3D::get_visibility_range_end_margin);

Expand All @@ -387,6 +408,9 @@ void GeometryInstance3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_visibility_range_begin", "distance"), &GeometryInstance3D::set_visibility_range_begin);
ClassDB::bind_method(D_METHOD("get_visibility_range_begin"), &GeometryInstance3D::get_visibility_range_begin);

ClassDB::bind_method(D_METHOD("set_visibility_range_fade_mode", "mode"), &GeometryInstance3D::set_visibility_range_fade_mode);
ClassDB::bind_method(D_METHOD("get_visibility_range_fade_mode"), &GeometryInstance3D::get_visibility_range_fade_mode);

ClassDB::bind_method(D_METHOD("set_shader_instance_uniform", "uniform", "value"), &GeometryInstance3D::set_shader_instance_uniform);
ClassDB::bind_method(D_METHOD("get_shader_instance_uniform", "uniform"), &GeometryInstance3D::get_shader_instance_uniform);

Expand All @@ -408,6 +432,7 @@ void GeometryInstance3D::_bind_methods() {

ADD_GROUP("Geometry", "");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material_override", PROPERTY_HINT_RESOURCE_TYPE, "BaseMaterial3D,ShaderMaterial", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_DEFERRED_SET_RESOURCE), "set_material_override", "get_material_override");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "transparency", PROPERTY_HINT_RANGE, "0.0,1.0,0.01"), "set_transparency", "get_transparency");
ADD_PROPERTY(PropertyInfo(Variant::INT, "cast_shadow", PROPERTY_HINT_ENUM, "Off,On,Double-Sided,Shadows Only"), "set_cast_shadows_setting", "get_cast_shadows_setting");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "extra_cull_margin", PROPERTY_HINT_RANGE, "0,16384,0.01"), "set_extra_cull_margin", "get_extra_cull_margin");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lod_bias", PROPERTY_HINT_RANGE, "0.001,128,0.001"), "set_lod_bias", "get_lod_bias");
Expand All @@ -421,7 +446,7 @@ void GeometryInstance3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "visibility_range_begin_margin", PROPERTY_HINT_RANGE, "0.0,4096.0,0.01"), "set_visibility_range_begin_margin", "get_visibility_range_begin_margin");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "visibility_range_end", PROPERTY_HINT_RANGE, "0.0,4096.0,0.01"), "set_visibility_range_end", "get_visibility_range_end");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "visibility_range_end_margin", PROPERTY_HINT_RANGE, "0.0,4096.0,0.01"), "set_visibility_range_end_margin", "get_visibility_range_end_margin");

ADD_PROPERTY(PropertyInfo(Variant::INT, "visibility_range_fade_mode", PROPERTY_HINT_ENUM, "Disabled,Self,Dependencies"), "set_visibility_range_fade_mode", "get_visibility_range_fade_mode");
//ADD_SIGNAL( MethodInfo("visibility_changed"));

BIND_ENUM_CONSTANT(SHADOW_CASTING_SETTING_OFF);
Expand All @@ -438,6 +463,10 @@ void GeometryInstance3D::_bind_methods() {
BIND_ENUM_CONSTANT(LIGHTMAP_SCALE_4X);
BIND_ENUM_CONSTANT(LIGHTMAP_SCALE_8X);
BIND_ENUM_CONSTANT(LIGHTMAP_SCALE_MAX);

BIND_ENUM_CONSTANT(VISIBILITY_RANGE_FADE_DISABLED);
BIND_ENUM_CONSTANT(VISIBILITY_RANGE_FADE_SELF);
BIND_ENUM_CONSTANT(VISIBILITY_RANGE_FADE_DEPENDENCIES);
}

GeometryInstance3D::GeometryInstance3D() {
Expand Down
17 changes: 14 additions & 3 deletions scene/3d/visual_instance_3d.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,12 @@ class GeometryInstance3D : public VisualInstance3D {
LIGHTMAP_SCALE_MAX,
};

enum VisibilityRangeFadeMode {
VISIBILITY_RANGE_FADE_DISABLED = RS::VISIBILITY_RANGE_FADE_DISABLED,
VISIBILITY_RANGE_FADE_SELF = RS::VISIBILITY_RANGE_FADE_SELF,
VISIBILITY_RANGE_FADE_DEPENDENCIES = RS::VISIBILITY_RANGE_FADE_DEPENDENCIES,
};

private:
ShadowCastingSetting shadow_casting_setting = SHADOW_CASTING_SETTING_ON;
Ref<Material> material_override;
Expand All @@ -109,8 +115,9 @@ class GeometryInstance3D : public VisualInstance3D {
float visibility_range_end = 0.0;
float visibility_range_begin_margin = 0.0;
float visibility_range_end_margin = 0.0;
VisibilityRangeFadeMode visibility_range_fade_mode = VISIBILITY_RANGE_FADE_DISABLED;

Vector<NodePath> visibility_range_children;
float transparency = 0.0f;

float lod_bias = 1.0;

Expand All @@ -136,6 +143,9 @@ class GeometryInstance3D : public VisualInstance3D {
void set_cast_shadows_setting(ShadowCastingSetting p_shadow_casting_setting);
ShadowCastingSetting get_cast_shadows_setting() const;

void set_transparecy(float p_transparency);
float get_transparency() const;

void set_visibility_range_begin(float p_dist);
float get_visibility_range_begin() const;

Expand All @@ -148,8 +158,8 @@ class GeometryInstance3D : public VisualInstance3D {
void set_visibility_range_end_margin(float p_dist);
float get_visibility_range_end_margin() const;

void set_visibility_range_parent(const Node *p_parent);
void clear_visibility_range_parent();
void set_visibility_range_fade_mode(VisibilityRangeFadeMode p_mode);
VisibilityRangeFadeMode get_visibility_range_fade_mode() const;

void set_material_override(const Ref<Material> &p_material);
Ref<Material> get_material_override() const;
Expand Down Expand Up @@ -181,5 +191,6 @@ class GeometryInstance3D : public VisualInstance3D {
VARIANT_ENUM_CAST(GeometryInstance3D::ShadowCastingSetting);
VARIANT_ENUM_CAST(GeometryInstance3D::LightmapScale);
VARIANT_ENUM_CAST(GeometryInstance3D::GIMode);
VARIANT_ENUM_CAST(GeometryInstance3D::VisibilityRangeFadeMode);

#endif
2 changes: 1 addition & 1 deletion scene/resources/material.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1086,7 +1086,7 @@ void BaseMaterial3D::_update_shader() {
code += " ALPHA = 1.0;\n";

} else if (transparency != TRANSPARENCY_DISABLED || flags[FLAG_USE_SHADOW_TO_OPACITY] || (distance_fade == DISTANCE_FADE_PIXEL_ALPHA) || proximity_fade_enabled) {
code += " ALPHA = albedo.a * albedo_tex.a;\n";
code += " ALPHA *= albedo.a * albedo_tex.a;\n";
}
if (transparency == TRANSPARENCY_ALPHA_HASH) {
code += " ALPHA_HASH_SCALE = alpha_hash_scale;\n";
Expand Down
3 changes: 3 additions & 0 deletions servers/rendering/rasterizer_dummy.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ class RasterizerSceneDummy : public RendererSceneRender {
void geometry_instance_set_lightmap_capture(GeometryInstance *p_geometry_instance, const Color *p_sh9) override {}
void geometry_instance_set_instance_shader_parameters_offset(GeometryInstance *p_geometry_instance, int32_t p_offset) override {}
void geometry_instance_set_cast_double_sided_shadows(GeometryInstance *p_geometry_instance, bool p_enable) override {}
void geometry_instance_set_fade_range(GeometryInstance *p_geometry_instance, bool p_enable_near, float p_near_begin, float p_near_end, bool p_enable_far, float p_far_begin, float p_far_end) override {}
void geometry_instance_set_parent_fade_alpha(GeometryInstance *p_geometry_instance, float p_alpha) override {}
void geometry_instance_set_transparency(GeometryInstance *p_geometry_instance, float p_transparency) override {}

uint32_t geometry_instance_get_pair_mask() override { return 0; }
void geometry_instance_pair_light_instances(GeometryInstance *p_geometry_instance, const RID *p_light_instances, uint32_t p_light_instance_count) override {}
Expand Down
Loading