Implement distance fade and transparency
The built-in ALPHA in spatial shaders comes pre-set with a per-instance transparency value. Multiply by it if you want to keep it. The transparency value of any given GeometryInstance3D is affected by: - Its new "transparency" property. - Its own visiblity range when the new "visibility_range_fade_mode" property is set to "Self". - Its parent visibility range when the parent's fade mode is set to "Dependencies". The "Self" mode will fade-out the instance when reaching the visibility range limits, while the "Dependencies" mode will fade-in its dependencies. Per-instance transparency is only implemented in the forward clustered renderer, support for mobile should be added in the future. Co-authored-by: reduz <reduzio@gmail.com>
This commit is contained in:
parent
88d9914519
commit
c571e4a7f4
|
@ -49,6 +49,9 @@
|
|||
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>
|
||||
|
@ -56,11 +59,14 @@
|
|||
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">
|
||||
|
@ -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>
|
||||
|
|
|
@ -1377,6 +1377,14 @@
|
|||
<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" />
|
||||
|
@ -1384,6 +1392,7 @@
|
|||
<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>
|
||||
|
@ -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">
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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) {
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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");
|
||||
|
@ -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);
|
||||
|
@ -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() {
|
||||
|
|
|
@ -101,6 +101,12 @@ public:
|
|||
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;
|
||||
|
@ -109,8 +115,9 @@ private:
|
|||
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;
|
||||
|
||||
|
@ -136,6 +143,9 @@ public:
|
|||
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;
|
||||
|
||||
|
@ -148,8 +158,8 @@ public:
|
|||
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;
|
||||
|
@ -181,5 +191,6 @@ public:
|
|||
VARIANT_ENUM_CAST(GeometryInstance3D::ShadowCastingSetting);
|
||||
VARIANT_ENUM_CAST(GeometryInstance3D::LightmapScale);
|
||||
VARIANT_ENUM_CAST(GeometryInstance3D::GIMode);
|
||||
VARIANT_ENUM_CAST(GeometryInstance3D::VisibilityRangeFadeMode);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -55,6 +55,9 @@ public:
|
|||
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 {}
|
||||
|
|
|
@ -388,7 +388,7 @@ void RenderForwardClustered::_render_list_template(RenderingDevice::DrawListID p
|
|||
RS::PrimitiveType primitive = surf->primitive;
|
||||
RID xforms_uniform_set = surf->owner->transforms_uniform_set;
|
||||
|
||||
SceneShaderForwardClustered::ShaderVersion shader_version = SceneShaderForwardClustered::SHADER_VERSION_MAX; // Assigned to silence wrong -Wmaybe-initialized.
|
||||
SceneShaderForwardClustered::PipelineVersion pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_MAX; // Assigned to silence wrong -Wmaybe-initialized.
|
||||
|
||||
uint32_t pipeline_specialization = 0;
|
||||
|
||||
|
@ -406,48 +406,54 @@ void RenderForwardClustered::_render_list_template(RenderingDevice::DrawListID p
|
|||
}
|
||||
|
||||
switch (p_pass_mode) {
|
||||
case PASS_MODE_COLOR:
|
||||
case PASS_MODE_COLOR: {
|
||||
if (element_info.uses_lightmap) {
|
||||
pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_LIGHTMAP_OPAQUE_PASS;
|
||||
} else {
|
||||
pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_OPAQUE_PASS;
|
||||
}
|
||||
} break;
|
||||
case PASS_MODE_COLOR_TRANSPARENT: {
|
||||
if (element_info.uses_lightmap) {
|
||||
shader_version = SceneShaderForwardClustered::SHADER_VERSION_LIGHTMAP_COLOR_PASS;
|
||||
pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_LIGHTMAP_TRANSPARENT_PASS;
|
||||
} else {
|
||||
if (element_info.uses_forward_gi) {
|
||||
pipeline_specialization |= SceneShaderForwardClustered::SHADER_SPECIALIZATION_FORWARD_GI;
|
||||
}
|
||||
shader_version = SceneShaderForwardClustered::SHADER_VERSION_COLOR_PASS;
|
||||
pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_TRANSPARENT_PASS;
|
||||
}
|
||||
} break;
|
||||
case PASS_MODE_COLOR_SPECULAR: {
|
||||
if (element_info.uses_lightmap) {
|
||||
shader_version = SceneShaderForwardClustered::SHADER_VERSION_LIGHTMAP_COLOR_PASS_WITH_SEPARATE_SPECULAR;
|
||||
pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_LIGHTMAP_OPAQUE_PASS_WITH_SEPARATE_SPECULAR;
|
||||
} else {
|
||||
shader_version = SceneShaderForwardClustered::SHADER_VERSION_COLOR_PASS_WITH_SEPARATE_SPECULAR;
|
||||
pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_OPAQUE_PASS_WITH_SEPARATE_SPECULAR;
|
||||
}
|
||||
} break;
|
||||
case PASS_MODE_SHADOW:
|
||||
case PASS_MODE_DEPTH: {
|
||||
shader_version = SceneShaderForwardClustered::SHADER_VERSION_DEPTH_PASS;
|
||||
pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_DEPTH_PASS;
|
||||
} break;
|
||||
case PASS_MODE_SHADOW_DP: {
|
||||
shader_version = SceneShaderForwardClustered::SHADER_VERSION_DEPTH_PASS_DP;
|
||||
pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_DEPTH_PASS_DP;
|
||||
} break;
|
||||
case PASS_MODE_DEPTH_NORMAL_ROUGHNESS: {
|
||||
shader_version = SceneShaderForwardClustered::SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS;
|
||||
pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS;
|
||||
} break;
|
||||
case PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI: {
|
||||
shader_version = SceneShaderForwardClustered::SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI;
|
||||
pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI;
|
||||
} break;
|
||||
case PASS_MODE_DEPTH_MATERIAL: {
|
||||
shader_version = SceneShaderForwardClustered::SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL;
|
||||
pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_DEPTH_PASS_WITH_MATERIAL;
|
||||
} break;
|
||||
case PASS_MODE_SDF: {
|
||||
shader_version = SceneShaderForwardClustered::SHADER_VERSION_DEPTH_PASS_WITH_SDF;
|
||||
pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_DEPTH_PASS_WITH_SDF;
|
||||
} break;
|
||||
}
|
||||
|
||||
PipelineCacheRD *pipeline = nullptr;
|
||||
|
||||
pipeline = &shader->pipelines[cull_variant][primitive][shader_version];
|
||||
pipeline = &shader->pipelines[cull_variant][primitive][pipeline_version];
|
||||
|
||||
RD::VertexFormatID vertex_format = -1;
|
||||
RID vertex_array_rd;
|
||||
|
@ -946,10 +952,23 @@ void RenderForwardClustered::_fill_render_list(RenderListType p_render_list, con
|
|||
}
|
||||
bool uses_lightmap = false;
|
||||
bool uses_gi = false;
|
||||
float fade_alpha = 1.0;
|
||||
|
||||
if (p_render_list == RENDER_LIST_OPAQUE) {
|
||||
//setup GI
|
||||
if (inst->fade_near || inst->fade_far) {
|
||||
float fade_dist = inst->transform.origin.distance_to(p_render_data->cam_transform.origin);
|
||||
if (inst->fade_far && fade_dist > inst->fade_far_begin) {
|
||||
fade_alpha = MAX(0.0, 1.0 - (fade_dist - inst->fade_far_begin) / (inst->fade_far_end - inst->fade_far_begin));
|
||||
} else if (inst->fade_near && fade_dist < inst->fade_near_end) {
|
||||
fade_alpha = MAX(0.0, (fade_dist - inst->fade_near_begin) / (inst->fade_near_end - inst->fade_near_begin));
|
||||
}
|
||||
}
|
||||
|
||||
fade_alpha *= inst->force_alpha * inst->parent_fade_alpha;
|
||||
|
||||
flags = (flags & ~INSTANCE_DATA_FLAGS_FADE_MASK) | (uint32_t(fade_alpha * 255.0) << INSTANCE_DATA_FLAGS_FADE_SHIFT);
|
||||
|
||||
// Setup GI
|
||||
if (inst->lightmap_instance.is_valid()) {
|
||||
int32_t lightmap_cull_index = -1;
|
||||
for (uint32_t j = 0; j < scene_state.lightmaps_used; j++) {
|
||||
|
@ -1080,6 +1099,11 @@ void RenderForwardClustered::_fill_render_list(RenderListType p_render_list, con
|
|||
#else
|
||||
bool force_alpha = false;
|
||||
#endif
|
||||
|
||||
if (fade_alpha < 0.999) {
|
||||
force_alpha = true;
|
||||
}
|
||||
|
||||
if (!force_alpha && (surf->flags & (GeometryInstanceSurfaceDataCache::FLAG_PASS_DEPTH | GeometryInstanceSurfaceDataCache::FLAG_PASS_OPAQUE))) {
|
||||
rl->add_element(surf);
|
||||
}
|
||||
|
@ -1554,7 +1578,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
|
|||
_setup_environment(p_render_data, p_render_data->reflection_probe.is_valid(), screen_size, !p_render_data->reflection_probe.is_valid(), p_default_bg_color, false);
|
||||
|
||||
{
|
||||
RenderListParameters render_list_params(render_list[RENDER_LIST_ALPHA].elements.ptr(), render_list[RENDER_LIST_ALPHA].element_info.ptr(), render_list[RENDER_LIST_ALPHA].elements.size(), false, PASS_MODE_COLOR, render_buffer == nullptr, p_render_data->directional_light_soft_shadows, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_lod_threshold);
|
||||
RenderListParameters render_list_params(render_list[RENDER_LIST_ALPHA].elements.ptr(), render_list[RENDER_LIST_ALPHA].element_info.ptr(), render_list[RENDER_LIST_ALPHA].elements.size(), false, PASS_MODE_COLOR_TRANSPARENT, render_buffer == nullptr, p_render_data->directional_light_soft_shadows, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_lod_threshold);
|
||||
_render_list_with_threads(&render_list_params, alpha_framebuffer, can_continue_color ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, can_continue_depth ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ);
|
||||
}
|
||||
|
||||
|
@ -2890,6 +2914,29 @@ void RenderForwardClustered::geometry_instance_set_lod_bias(GeometryInstance *p_
|
|||
ERR_FAIL_COND(!ginstance);
|
||||
ginstance->lod_bias = p_lod_bias;
|
||||
}
|
||||
void RenderForwardClustered::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) {
|
||||
GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance);
|
||||
ERR_FAIL_COND(!ginstance);
|
||||
ginstance->fade_near = p_enable_near;
|
||||
ginstance->fade_near_begin = p_near_begin;
|
||||
ginstance->fade_near_end = p_near_end;
|
||||
ginstance->fade_far = p_enable_far;
|
||||
ginstance->fade_far_begin = p_far_begin;
|
||||
ginstance->fade_far_end = p_far_end;
|
||||
}
|
||||
|
||||
void RenderForwardClustered::geometry_instance_set_parent_fade_alpha(GeometryInstance *p_geometry_instance, float p_alpha) {
|
||||
GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance);
|
||||
ERR_FAIL_COND(!ginstance);
|
||||
ginstance->parent_fade_alpha = p_alpha;
|
||||
}
|
||||
|
||||
void RenderForwardClustered::geometry_instance_set_transparency(GeometryInstance *p_geometry_instance, float p_transparency) {
|
||||
GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance);
|
||||
ERR_FAIL_COND(!ginstance);
|
||||
ginstance->force_alpha = CLAMP(1.0 - p_transparency, 0, 1);
|
||||
}
|
||||
|
||||
void RenderForwardClustered::geometry_instance_set_use_baked_light(GeometryInstance *p_geometry_instance, bool p_enable) {
|
||||
GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance);
|
||||
ERR_FAIL_COND(!ginstance);
|
||||
|
|
|
@ -208,6 +208,8 @@ class RenderForwardClustered : public RendererSceneRenderRD {
|
|||
INSTANCE_DATA_FLAG_MULTIMESH_HAS_CUSTOM_DATA = 1 << 15,
|
||||
INSTANCE_DATA_FLAGS_PARTICLE_TRAIL_SHIFT = 16,
|
||||
INSTANCE_DATA_FLAGS_PARTICLE_TRAIL_MASK = 0xFF,
|
||||
INSTANCE_DATA_FLAGS_FADE_SHIFT = 24,
|
||||
INSTANCE_DATA_FLAGS_FADE_MASK = 0xFF << INSTANCE_DATA_FLAGS_FADE_SHIFT
|
||||
};
|
||||
|
||||
struct SceneState {
|
||||
|
@ -466,6 +468,15 @@ class RenderForwardClustered : public RendererSceneRenderRD {
|
|||
bool can_sdfgi = false;
|
||||
bool using_projectors = false;
|
||||
bool using_softshadows = false;
|
||||
bool fade_near = false;
|
||||
float fade_near_begin = 0;
|
||||
float fade_near_end = 0;
|
||||
bool fade_far = false;
|
||||
float fade_far_begin = 0;
|
||||
float fade_far_end = 0;
|
||||
float force_alpha = 1.0;
|
||||
float parent_fade_alpha = 1.0;
|
||||
|
||||
//used during setup
|
||||
uint32_t base_flags = 0;
|
||||
Transform3D transform;
|
||||
|
@ -599,6 +610,9 @@ public:
|
|||
virtual void geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb) override;
|
||||
virtual void geometry_instance_set_layer_mask(GeometryInstance *p_geometry_instance, uint32_t p_layer_mask) override;
|
||||
virtual void geometry_instance_set_lod_bias(GeometryInstance *p_geometry_instance, float p_lod_bias) override;
|
||||
virtual 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;
|
||||
virtual void geometry_instance_set_parent_fade_alpha(GeometryInstance *p_geometry_instance, float p_alpha) override;
|
||||
virtual void geometry_instance_set_transparency(GeometryInstance *p_geometry_instance, float p_transparency) override;
|
||||
virtual void geometry_instance_set_use_baked_light(GeometryInstance *p_geometry_instance, bool p_enable) override;
|
||||
virtual void geometry_instance_set_use_dynamic_gi(GeometryInstance *p_geometry_instance, bool p_enable) override;
|
||||
virtual void geometry_instance_set_use_lightmap(GeometryInstance *p_geometry_instance, RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) override;
|
||||
|
|
|
@ -267,8 +267,26 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
|
|||
|
||||
RD::RenderPrimitive primitive_rd = uses_point_size ? RD::RENDER_PRIMITIVE_POINTS : primitive_rd_table[j];
|
||||
|
||||
for (int k = 0; k < SHADER_VERSION_MAX; k++) {
|
||||
if (!static_cast<SceneShaderForwardClustered *>(singleton)->shader.is_variant_enabled(k)) {
|
||||
for (int k = 0; k < PIPELINE_VERSION_MAX; k++) {
|
||||
ShaderVersion shader_version;
|
||||
static const ShaderVersion shader_version_table[PIPELINE_VERSION_MAX] = {
|
||||
SHADER_VERSION_DEPTH_PASS,
|
||||
SHADER_VERSION_DEPTH_PASS_DP,
|
||||
SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS,
|
||||
SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI,
|
||||
SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL,
|
||||
SHADER_VERSION_DEPTH_PASS_WITH_SDF,
|
||||
SHADER_VERSION_COLOR_PASS,
|
||||
SHADER_VERSION_COLOR_PASS_WITH_SEPARATE_SPECULAR,
|
||||
SHADER_VERSION_COLOR_PASS,
|
||||
SHADER_VERSION_LIGHTMAP_COLOR_PASS,
|
||||
SHADER_VERSION_LIGHTMAP_COLOR_PASS_WITH_SEPARATE_SPECULAR,
|
||||
SHADER_VERSION_LIGHTMAP_COLOR_PASS,
|
||||
};
|
||||
|
||||
shader_version = shader_version_table[k];
|
||||
|
||||
if (!static_cast<SceneShaderForwardClustered *>(singleton)->shader.is_variant_enabled(shader_version)) {
|
||||
continue;
|
||||
}
|
||||
RD::PipelineRasterizationState raster_state;
|
||||
|
@ -279,8 +297,7 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
|
|||
RD::PipelineDepthStencilState depth_stencil = depth_stencil_state;
|
||||
RD::PipelineMultisampleState multisample_state;
|
||||
|
||||
if (uses_alpha || uses_blend_alpha) {
|
||||
// only allow these flags to go through if we have some form of msaa
|
||||
if (k == PIPELINE_VERSION_TRANSPARENT_PASS || k == PIPELINE_VERSION_LIGHTMAP_TRANSPARENT_PASS) {
|
||||
if (alpha_antialiasing_mode == ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE) {
|
||||
multisample_state.enable_alpha_to_coverage = true;
|
||||
} else if (alpha_antialiasing_mode == ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE_AND_TO_ONE) {
|
||||
|
@ -288,43 +305,29 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
|
|||
multisample_state.enable_alpha_to_one = true;
|
||||
}
|
||||
|
||||
if (k == SHADER_VERSION_COLOR_PASS || k == SHADER_VERSION_LIGHTMAP_COLOR_PASS) {
|
||||
blend_state = blend_state_blend;
|
||||
|
||||
if (depth_draw == DEPTH_DRAW_OPAQUE) {
|
||||
depth_stencil.enable_depth_write = false; //alpha does not draw depth
|
||||
}
|
||||
} else if (uses_depth_pre_pass && (k == SHADER_VERSION_DEPTH_PASS || k == SHADER_VERSION_DEPTH_PASS_DP || k == SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS || k == SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL)) {
|
||||
if (k == SHADER_VERSION_DEPTH_PASS || k == SHADER_VERSION_DEPTH_PASS_DP) {
|
||||
//none, blend state contains nothing
|
||||
} else if (k == SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL) {
|
||||
blend_state = RD::PipelineColorBlendState::create_disabled(5); //writes to normal and roughness in opaque way
|
||||
} else {
|
||||
blend_state = blend_state_opaque; //writes to normal and roughness in opaque way
|
||||
}
|
||||
} else {
|
||||
pipelines[i][j][k].clear();
|
||||
continue; // do not use this version (will error if using it is attempted)
|
||||
}
|
||||
} else {
|
||||
if (k == SHADER_VERSION_COLOR_PASS || k == SHADER_VERSION_LIGHTMAP_COLOR_PASS) {
|
||||
} else if (k == PIPELINE_VERSION_OPAQUE_PASS || k == PIPELINE_VERSION_LIGHTMAP_OPAQUE_PASS) {
|
||||
blend_state = blend_state_opaque;
|
||||
} else if (k == SHADER_VERSION_DEPTH_PASS || k == SHADER_VERSION_DEPTH_PASS_DP) {
|
||||
} else if (k == PIPELINE_VERSION_DEPTH_PASS || k == PIPELINE_VERSION_DEPTH_PASS_DP) {
|
||||
//none, leave empty
|
||||
} else if (k == SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS) {
|
||||
} else if (k == PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS) {
|
||||
blend_state = blend_state_depth_normal_roughness;
|
||||
} else if (k == SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI) {
|
||||
} else if (k == PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI) {
|
||||
blend_state = blend_state_depth_normal_roughness_giprobe;
|
||||
} else if (k == SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL) {
|
||||
} else if (k == PIPELINE_VERSION_DEPTH_PASS_WITH_MATERIAL) {
|
||||
blend_state = RD::PipelineColorBlendState::create_disabled(5); //writes to normal and roughness in opaque way
|
||||
} else if (k == SHADER_VERSION_DEPTH_PASS_WITH_SDF) {
|
||||
} else if (k == PIPELINE_VERSION_DEPTH_PASS_WITH_SDF) {
|
||||
blend_state = RD::PipelineColorBlendState(); //no color targets for SDF
|
||||
} else {
|
||||
//specular write
|
||||
blend_state = blend_state_opaque_specular;
|
||||
}
|
||||
}
|
||||
|
||||
RID shader_variant = shader_singleton->shader.version_get_shader(version, k);
|
||||
RID shader_variant = shader_singleton->shader.version_get_shader(version, shader_version);
|
||||
pipelines[i][j][k].setup(shader_variant, primitive_rd, raster_state, multisample_state, depth_stencil, blend_state, 0, singleton->default_specialization_constants);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,10 +55,25 @@ public:
|
|||
SHADER_VERSION_COLOR_PASS_WITH_SEPARATE_SPECULAR,
|
||||
SHADER_VERSION_LIGHTMAP_COLOR_PASS,
|
||||
SHADER_VERSION_LIGHTMAP_COLOR_PASS_WITH_SEPARATE_SPECULAR,
|
||||
|
||||
SHADER_VERSION_MAX
|
||||
};
|
||||
|
||||
enum PipelineVersion {
|
||||
PIPELINE_VERSION_DEPTH_PASS,
|
||||
PIPELINE_VERSION_DEPTH_PASS_DP,
|
||||
PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS,
|
||||
PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI,
|
||||
PIPELINE_VERSION_DEPTH_PASS_WITH_MATERIAL,
|
||||
PIPELINE_VERSION_DEPTH_PASS_WITH_SDF,
|
||||
PIPELINE_VERSION_OPAQUE_PASS,
|
||||
PIPELINE_VERSION_OPAQUE_PASS_WITH_SEPARATE_SPECULAR,
|
||||
PIPELINE_VERSION_TRANSPARENT_PASS,
|
||||
PIPELINE_VERSION_LIGHTMAP_OPAQUE_PASS,
|
||||
PIPELINE_VERSION_LIGHTMAP_OPAQUE_PASS_WITH_SEPARATE_SPECULAR,
|
||||
PIPELINE_VERSION_LIGHTMAP_TRANSPARENT_PASS,
|
||||
PIPELINE_VERSION_MAX
|
||||
};
|
||||
|
||||
enum ShaderSpecializations {
|
||||
SHADER_SPECIALIZATION_FORWARD_GI = 1 << 0,
|
||||
SHADER_SPECIALIZATION_PROJECTOR = 1 << 1,
|
||||
|
@ -109,7 +124,7 @@ public:
|
|||
bool valid;
|
||||
RID version;
|
||||
uint32_t vertex_input_mask;
|
||||
PipelineCacheRD pipelines[CULL_VARIANT_MAX][RS::PRIMITIVE_MAX][SHADER_VERSION_MAX];
|
||||
PipelineCacheRD pipelines[CULL_VARIANT_MAX][RS::PRIMITIVE_MAX][PIPELINE_VERSION_MAX];
|
||||
|
||||
String path;
|
||||
|
||||
|
|
|
@ -2072,6 +2072,15 @@ void RenderForwardMobile::geometry_instance_set_lod_bias(GeometryInstance *p_geo
|
|||
ginstance->lod_bias = p_lod_bias;
|
||||
}
|
||||
|
||||
void RenderForwardMobile::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) {
|
||||
}
|
||||
|
||||
void RenderForwardMobile::geometry_instance_set_transparency(GeometryInstance *p_geometry_instance, float p_transparency) {
|
||||
}
|
||||
|
||||
void RenderForwardMobile::geometry_instance_set_parent_fade_alpha(GeometryInstance *p_geometry_instance, float p_alpha) {
|
||||
}
|
||||
|
||||
void RenderForwardMobile::geometry_instance_set_use_baked_light(GeometryInstance *p_geometry_instance, bool p_enable) {
|
||||
GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance);
|
||||
ERR_FAIL_COND(!ginstance);
|
||||
|
|
|
@ -632,6 +632,9 @@ public:
|
|||
virtual void geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb) override;
|
||||
virtual void geometry_instance_set_layer_mask(GeometryInstance *p_geometry_instance, uint32_t p_layer_mask) override;
|
||||
virtual void geometry_instance_set_lod_bias(GeometryInstance *p_geometry_instance, float p_lod_bias) override;
|
||||
virtual 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;
|
||||
virtual void geometry_instance_set_parent_fade_alpha(GeometryInstance *p_geometry_instance, float p_alpha) override;
|
||||
virtual void geometry_instance_set_transparency(GeometryInstance *p_geometry_instance, float p_transparency) override;
|
||||
virtual void geometry_instance_set_use_baked_light(GeometryInstance *p_geometry_instance, bool p_enable) override;
|
||||
virtual void geometry_instance_set_use_dynamic_gi(GeometryInstance *p_geometry_instance, bool p_enable) override;
|
||||
virtual void geometry_instance_set_use_lightmap(GeometryInstance *p_geometry_instance, RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) override;
|
||||
|
|
|
@ -95,7 +95,7 @@ layout(location = 8) out float dp_clip;
|
|||
|
||||
#endif
|
||||
|
||||
layout(location = 9) out flat uint instance_index;
|
||||
layout(location = 9) out flat uint instance_index_interp;
|
||||
|
||||
invariant gl_Position;
|
||||
|
||||
|
@ -107,7 +107,8 @@ void main() {
|
|||
color_interp = color_attrib;
|
||||
#endif
|
||||
|
||||
instance_index = draw_call.instance_index;
|
||||
uint instance_index = draw_call.instance_index;
|
||||
instance_index_interp = instance_index;
|
||||
|
||||
bool is_multimesh = bool(instances.data[instance_index].flags & INSTANCE_FLAGS_MULTIMESH);
|
||||
if (!is_multimesh) {
|
||||
|
@ -410,7 +411,7 @@ layout(location = 8) in float dp_clip;
|
|||
|
||||
#endif
|
||||
|
||||
layout(location = 9) in flat uint instance_index;
|
||||
layout(location = 9) in flat uint instance_index_interp;
|
||||
|
||||
//defines to keep compatibility with vertex
|
||||
|
||||
|
@ -564,6 +565,12 @@ void main() {
|
|||
discard;
|
||||
#endif
|
||||
|
||||
#ifdef USE_SUBGROUPS
|
||||
//ensures instance_index is in sgpr
|
||||
uint instance_index = subgroupBroadcastFirst(instance_index_interp);
|
||||
#else
|
||||
uint instance_index = instance_index_interp;
|
||||
#endif
|
||||
//lay out everything, whathever is unused is optimized away anyway
|
||||
vec3 vertex = vertex_interp;
|
||||
vec3 view = -normalize(vertex_interp);
|
||||
|
@ -593,7 +600,7 @@ void main() {
|
|||
float ao = 1.0;
|
||||
float ao_light_affect = 0.0;
|
||||
|
||||
float alpha = 1.0;
|
||||
float alpha = float(instances.data[instance_index].flags >> INSTANCE_FLAGS_FADE_SHIFT) / float(255.0);
|
||||
|
||||
#if defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED)
|
||||
vec3 binormal = normalize(binormal_interp);
|
||||
|
@ -1897,7 +1904,6 @@ void main() {
|
|||
|
||||
// Draw "fixed" fog before volumetric fog to ensure volumetric fog can appear in front of the sky.
|
||||
frag_color.rgb = mix(frag_color.rgb, fog.rgb, fog.a);
|
||||
;
|
||||
|
||||
#endif //MODE_MULTIPLE_RENDER_TARGETS
|
||||
|
||||
|
|
|
@ -68,6 +68,7 @@ layout(set = 0, binding = 4) uniform sampler light_projector_sampler;
|
|||
#define INSTANCE_FLAGS_MULTIMESH_HAS_COLOR (1 << 14)
|
||||
#define INSTANCE_FLAGS_MULTIMESH_HAS_CUSTOM_DATA (1 << 15)
|
||||
#define INSTANCE_FLAGS_PARTICLE_TRAIL_SHIFT 16
|
||||
#define INSTANCE_FLAGS_FADE_SHIFT 24
|
||||
//3 bits of stride
|
||||
#define INSTANCE_FLAGS_PARTICLE_TRAIL_MASK 0xFF
|
||||
|
||||
|
|
|
@ -76,6 +76,7 @@ public:
|
|||
virtual void instance_set_blend_shape_weight(RID p_instance, int p_shape, float p_weight) = 0;
|
||||
virtual void instance_set_surface_override_material(RID p_instance, int p_surface, RID p_material) = 0;
|
||||
virtual void instance_set_visible(RID p_instance, bool p_visible) = 0;
|
||||
virtual void instance_geometry_set_transparency(RID p_instance, float p_transparency) = 0;
|
||||
|
||||
virtual void instance_set_custom_aabb(RID p_instance, AABB p_aabb) = 0;
|
||||
|
||||
|
@ -93,10 +94,9 @@ public:
|
|||
virtual void instance_geometry_set_cast_shadows_setting(RID p_instance, RS::ShadowCastingSetting p_shadow_casting_setting) = 0;
|
||||
virtual void instance_geometry_set_material_override(RID p_instance, RID p_material) = 0;
|
||||
|
||||
virtual void instance_geometry_set_visibility_range(RID p_instance, float p_min, float p_max, float p_min_margin, float p_max_margin) = 0;
|
||||
virtual void instance_geometry_set_visibility_range(RID p_instance, float p_min, float p_max, float p_min_margin, float p_max_margin, RS::VisibilityRangeFadeMode p_fade_mode) = 0;
|
||||
virtual void instance_geometry_set_lightmap(RID p_instance, RID p_lightmap, const Rect2 &p_lightmap_uv_scale, int p_slice_index) = 0;
|
||||
virtual void instance_geometry_set_lod_bias(RID p_instance, float p_lod_bias) = 0;
|
||||
|
||||
virtual void instance_geometry_set_shader_parameter(RID p_instance, const StringName &p_parameter, const Variant &p_value) = 0;
|
||||
virtual void instance_geometry_get_shader_parameter_list(RID p_instance, List<PropertyInfo> *p_parameters) const = 0;
|
||||
virtual Variant instance_geometry_get_shader_parameter(RID p_instance, const StringName &p_parameter) const = 0;
|
||||
|
|
|
@ -825,6 +825,16 @@ void RendererSceneCull::instance_set_layer_mask(RID p_instance, uint32_t p_mask)
|
|||
}
|
||||
}
|
||||
|
||||
void RendererSceneCull::instance_geometry_set_transparency(RID p_instance, float p_transparency) {
|
||||
Instance *instance = instance_owner.get_or_null(p_instance);
|
||||
ERR_FAIL_COND(!instance);
|
||||
|
||||
if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) {
|
||||
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
|
||||
scene_render->geometry_instance_set_transparency(geom->geometry_instance, p_transparency);
|
||||
}
|
||||
}
|
||||
|
||||
void RendererSceneCull::instance_set_transform(RID p_instance, const Transform3D &p_transform) {
|
||||
Instance *instance = instance_owner.get_or_null(p_instance);
|
||||
ERR_FAIL_COND(!instance);
|
||||
|
@ -1179,7 +1189,7 @@ void RendererSceneCull::instance_geometry_set_material_override(RID p_instance,
|
|||
}
|
||||
}
|
||||
|
||||
void RendererSceneCull::instance_geometry_set_visibility_range(RID p_instance, float p_min, float p_max, float p_min_margin, float p_max_margin) {
|
||||
void RendererSceneCull::instance_geometry_set_visibility_range(RID p_instance, float p_min, float p_max, float p_min_margin, float p_max_margin, RS::VisibilityRangeFadeMode p_fade_mode) {
|
||||
Instance *instance = instance_owner.get_or_null(p_instance);
|
||||
ERR_FAIL_COND(!instance);
|
||||
|
||||
|
@ -1187,6 +1197,7 @@ void RendererSceneCull::instance_geometry_set_visibility_range(RID p_instance, f
|
|||
instance->visibility_range_end = p_max;
|
||||
instance->visibility_range_begin_margin = p_min_margin;
|
||||
instance->visibility_range_end_margin = p_max_margin;
|
||||
instance->visibility_range_fade_mode = p_fade_mode;
|
||||
|
||||
_update_instance_visibility_dependencies(instance);
|
||||
|
||||
|
@ -1196,6 +1207,7 @@ void RendererSceneCull::instance_geometry_set_visibility_range(RID p_instance, f
|
|||
vd.range_end = instance->visibility_range_end;
|
||||
vd.range_begin_margin = instance->visibility_range_begin_margin;
|
||||
vd.range_end_margin = instance->visibility_range_end_margin;
|
||||
vd.fade_mode = p_fade_mode;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1279,23 +1291,42 @@ void RendererSceneCull::_update_instance_visibility_dependencies(Instance *p_ins
|
|||
vd.range_end_margin = p_instance->visibility_range_end_margin;
|
||||
vd.position = p_instance->transformed_aabb.get_center();
|
||||
vd.array_index = p_instance->array_index;
|
||||
vd.fade_mode = p_instance->visibility_range_fade_mode;
|
||||
|
||||
p_instance->scenario->instance_visibility.insert(vd, p_instance->visibility_dependencies_depth);
|
||||
}
|
||||
|
||||
if (p_instance->scenario && p_instance->array_index != -1) {
|
||||
p_instance->scenario->instance_data[p_instance->array_index].visibility_index = p_instance->visibility_index;
|
||||
InstanceData &idata = p_instance->scenario->instance_data[p_instance->array_index];
|
||||
idata.visibility_index = p_instance->visibility_index;
|
||||
|
||||
if (is_geometry_instance) {
|
||||
if (has_visibility_range && p_instance->visibility_range_fade_mode == RS::VISIBILITY_RANGE_FADE_SELF) {
|
||||
bool begin_enabled = p_instance->visibility_range_begin > 0.0f;
|
||||
float begin_min = p_instance->visibility_range_begin - p_instance->visibility_range_begin_margin;
|
||||
float begin_max = p_instance->visibility_range_begin + p_instance->visibility_range_begin_margin;
|
||||
bool end_enabled = p_instance->visibility_range_end > 0.0f;
|
||||
float end_min = p_instance->visibility_range_end - p_instance->visibility_range_end_margin;
|
||||
float end_max = p_instance->visibility_range_end + p_instance->visibility_range_end_margin;
|
||||
scene_render->geometry_instance_set_fade_range(idata.instance_geometry, begin_enabled, begin_min, begin_max, end_enabled, end_min, end_max);
|
||||
} else {
|
||||
scene_render->geometry_instance_set_fade_range(idata.instance_geometry, false, 0.0f, 0.0f, false, 0.0f, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
if ((has_visibility_range || p_instance->visibility_parent) && (p_instance->visibility_index == -1 || p_instance->visibility_dependencies_depth == 0)) {
|
||||
p_instance->scenario->instance_data[p_instance->array_index].flags |= InstanceData::FLAG_VISIBILITY_DEPENDENCY_NEEDS_CHECK;
|
||||
idata.flags |= InstanceData::FLAG_VISIBILITY_DEPENDENCY_NEEDS_CHECK;
|
||||
} else {
|
||||
p_instance->scenario->instance_data[p_instance->array_index].flags &= ~InstanceData::FLAG_VISIBILITY_DEPENDENCY_NEEDS_CHECK;
|
||||
idata.flags &= ~InstanceData::FLAG_VISIBILITY_DEPENDENCY_NEEDS_CHECK;
|
||||
}
|
||||
|
||||
if (p_instance->visibility_parent) {
|
||||
p_instance->scenario->instance_data[p_instance->array_index].parent_array_index = p_instance->visibility_parent->array_index;
|
||||
idata.parent_array_index = p_instance->visibility_parent->array_index;
|
||||
} else {
|
||||
p_instance->scenario->instance_data[p_instance->array_index].parent_array_index = -1;
|
||||
idata.parent_array_index = -1;
|
||||
if (is_geometry_instance) {
|
||||
scene_render->geometry_instance_set_parent_fade_alpha(idata.instance_geometry, 1.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1738,6 +1769,9 @@ void RendererSceneCull::_unpair_instance(Instance *p_instance) {
|
|||
Instance *dep_instance = E->get();
|
||||
if (dep_instance->array_index != -1) {
|
||||
dep_instance->scenario->instance_data[dep_instance->array_index].parent_array_index = -1;
|
||||
if ((1 << dep_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) {
|
||||
scene_render->geometry_instance_set_parent_fade_alpha(dep_instance->scenario->instance_data[dep_instance->array_index].instance_geometry, 1.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2439,34 +2473,49 @@ void RendererSceneCull::_visibility_cull(const VisibilityCullData &cull_data, ui
|
|||
|
||||
if (idata.parent_array_index >= 0) {
|
||||
uint32_t parent_flags = scenario->instance_data[idata.parent_array_index].flags;
|
||||
if ((parent_flags & InstanceData::FLAG_VISIBILITY_DEPENDENCY_HIDDEN) || (parent_flags & InstanceData::FLAG_VISIBILITY_DEPENDENCY_HIDDEN_CLOSE_RANGE) == 0) {
|
||||
|
||||
if ((parent_flags & InstanceData::FLAG_VISIBILITY_DEPENDENCY_HIDDEN) || !(parent_flags & (InstanceData::FLAG_VISIBILITY_DEPENDENCY_HIDDEN_CLOSE_RANGE | InstanceData::FLAG_VISIBILITY_DEPENDENCY_FADE_CHILDREN))) {
|
||||
idata.flags |= InstanceData::FLAG_VISIBILITY_DEPENDENCY_HIDDEN;
|
||||
idata.flags &= ~InstanceData::FLAG_VISIBILITY_DEPENDENCY_HIDDEN_CLOSE_RANGE;
|
||||
idata.flags &= ~InstanceData::FLAG_VISIBILITY_DEPENDENCY_FADE_CHILDREN;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
int range_check = _visibility_range_check(vd, cull_data.camera_position, cull_data.viewport_mask);
|
||||
int range_check = _visibility_range_check<true>(vd, cull_data.camera_position, cull_data.viewport_mask);
|
||||
|
||||
if (range_check == -1) {
|
||||
idata.flags |= InstanceData::FLAG_VISIBILITY_DEPENDENCY_HIDDEN;
|
||||
idata.flags &= ~InstanceData::FLAG_VISIBILITY_DEPENDENCY_HIDDEN_CLOSE_RANGE;
|
||||
idata.flags &= ~InstanceData::FLAG_VISIBILITY_DEPENDENCY_FADE_CHILDREN;
|
||||
} else if (range_check == 1) {
|
||||
idata.flags &= ~InstanceData::FLAG_VISIBILITY_DEPENDENCY_HIDDEN;
|
||||
idata.flags |= InstanceData::FLAG_VISIBILITY_DEPENDENCY_HIDDEN_CLOSE_RANGE;
|
||||
idata.flags &= ~InstanceData::FLAG_VISIBILITY_DEPENDENCY_FADE_CHILDREN;
|
||||
} else {
|
||||
idata.flags &= ~InstanceData::FLAG_VISIBILITY_DEPENDENCY_HIDDEN;
|
||||
idata.flags &= ~InstanceData::FLAG_VISIBILITY_DEPENDENCY_HIDDEN_CLOSE_RANGE;
|
||||
if (range_check == 2) {
|
||||
idata.flags |= InstanceData::FLAG_VISIBILITY_DEPENDENCY_FADE_CHILDREN;
|
||||
} else {
|
||||
idata.flags &= ~InstanceData::FLAG_VISIBILITY_DEPENDENCY_FADE_CHILDREN;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <bool p_fade_check>
|
||||
int RendererSceneCull::_visibility_range_check(InstanceVisibilityData &r_vis_data, const Vector3 &p_camera_pos, uint64_t p_viewport_mask) {
|
||||
float dist = p_camera_pos.distance_to(r_vis_data.position);
|
||||
const RS::VisibilityRangeFadeMode &fade_mode = r_vis_data.fade_mode;
|
||||
|
||||
bool in_range_last_frame = p_viewport_mask & r_vis_data.viewport_state;
|
||||
float begin_offset = in_range_last_frame ? -r_vis_data.range_begin_margin : r_vis_data.range_begin_margin;
|
||||
float end_offset = in_range_last_frame ? r_vis_data.range_end_margin : -r_vis_data.range_end_margin;
|
||||
float begin_offset = -r_vis_data.range_begin_margin;
|
||||
float end_offset = r_vis_data.range_end_margin;
|
||||
|
||||
if (fade_mode == RS::VISIBILITY_RANGE_FADE_DISABLED && !(p_viewport_mask & r_vis_data.viewport_state)) {
|
||||
begin_offset = -begin_offset;
|
||||
end_offset = -end_offset;
|
||||
}
|
||||
|
||||
if (r_vis_data.range_end > 0.0f && dist > r_vis_data.range_end + end_offset) {
|
||||
r_vis_data.viewport_state &= ~p_viewport_mask;
|
||||
|
@ -2476,10 +2525,34 @@ int RendererSceneCull::_visibility_range_check(InstanceVisibilityData &r_vis_dat
|
|||
return 1;
|
||||
} else {
|
||||
r_vis_data.viewport_state |= p_viewport_mask;
|
||||
if (p_fade_check) {
|
||||
if (fade_mode != RS::VISIBILITY_RANGE_FADE_DISABLED) {
|
||||
r_vis_data.children_fade_alpha = 1.0f;
|
||||
if (r_vis_data.range_end > 0.0f && dist > r_vis_data.range_end - end_offset) {
|
||||
if (fade_mode == RS::VISIBILITY_RANGE_FADE_DEPENDENCIES) {
|
||||
r_vis_data.children_fade_alpha = MIN(1.0f, (dist - (r_vis_data.range_end - end_offset)) / (2.0f * r_vis_data.range_end_margin));
|
||||
}
|
||||
return 2;
|
||||
} else if (r_vis_data.range_begin > 0.0f && dist < r_vis_data.range_begin - begin_offset) {
|
||||
if (fade_mode == RS::VISIBILITY_RANGE_FADE_DEPENDENCIES) {
|
||||
r_vis_data.children_fade_alpha = MIN(1.0f, 1.0 - (dist - (r_vis_data.range_begin + begin_offset)) / (2.0f * r_vis_data.range_begin_margin));
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool RendererSceneCull::_visibility_parent_check(const CullData &p_cull_data, const InstanceData &p_instance_data) {
|
||||
if (p_instance_data.parent_array_index == -1) {
|
||||
return true;
|
||||
}
|
||||
const uint32_t &parent_flags = p_cull_data.scenario->instance_data[p_instance_data.parent_array_index].flags;
|
||||
return ((parent_flags & InstanceData::FLAG_VISIBILITY_DEPENDENCY_NEEDS_CHECK) == InstanceData::FLAG_VISIBILITY_DEPENDENCY_HIDDEN_CLOSE_RANGE) || (parent_flags & InstanceData::FLAG_VISIBILITY_DEPENDENCY_FADE_CHILDREN);
|
||||
}
|
||||
|
||||
void RendererSceneCull::_scene_cull_threaded(uint32_t p_thread, CullData *cull_data) {
|
||||
uint32_t cull_total = cull_data->scenario->instance_data.size();
|
||||
uint32_t total_threads = RendererThreadPool::singleton->thread_work_pool.get_thread_count();
|
||||
|
@ -2505,14 +2578,14 @@ void RendererSceneCull::_scene_cull(CullData &cull_data, InstanceCullResult &cul
|
|||
bool mesh_visible = false;
|
||||
|
||||
InstanceData &idata = cull_data.scenario->instance_data[i];
|
||||
uint32_t visibility_flags = idata.flags & (InstanceData::FLAG_VISIBILITY_DEPENDENCY_HIDDEN_CLOSE_RANGE | InstanceData::FLAG_VISIBILITY_DEPENDENCY_HIDDEN);
|
||||
uint32_t visibility_flags = idata.flags & (InstanceData::FLAG_VISIBILITY_DEPENDENCY_HIDDEN_CLOSE_RANGE | InstanceData::FLAG_VISIBILITY_DEPENDENCY_HIDDEN | InstanceData::FLAG_VISIBILITY_DEPENDENCY_FADE_CHILDREN);
|
||||
int32_t visibility_check = -1;
|
||||
|
||||
#define HIDDEN_BY_VISIBILITY_CHECKS (visibility_flags == InstanceData::FLAG_VISIBILITY_DEPENDENCY_HIDDEN_CLOSE_RANGE || visibility_flags == InstanceData::FLAG_VISIBILITY_DEPENDENCY_HIDDEN)
|
||||
#define LAYER_CHECK (cull_data.visible_layers & idata.layer_mask)
|
||||
#define IN_FRUSTUM(f) (cull_data.scenario->instance_aabbs[i].in_frustum(f))
|
||||
#define VIS_RANGE_CHECK ((idata.visibility_index == -1) || _visibility_range_check(cull_data.scenario->instance_visibility[idata.visibility_index], cull_data.cam_transform.origin, cull_data.visibility_viewport_mask) == 0)
|
||||
#define VIS_PARENT_CHECK ((idata.parent_array_index == -1) || ((cull_data.scenario->instance_data[idata.parent_array_index].flags & InstanceData::FLAG_VISIBILITY_DEPENDENCY_NEEDS_CHECK) == InstanceData::FLAG_VISIBILITY_DEPENDENCY_HIDDEN_CLOSE_RANGE))
|
||||
#define VIS_RANGE_CHECK ((idata.visibility_index == -1) || _visibility_range_check<false>(cull_data.scenario->instance_visibility[idata.visibility_index], cull_data.cam_transform.origin, cull_data.visibility_viewport_mask) == 0)
|
||||
#define VIS_PARENT_CHECK (_visibility_parent_check(cull_data, idata))
|
||||
#define VIS_CHECK (visibility_check < 0 ? (visibility_check = (visibility_flags != InstanceData::FLAG_VISIBILITY_DEPENDENCY_NEEDS_CHECK || (VIS_RANGE_CHECK && VIS_PARENT_CHECK))) : visibility_check)
|
||||
#define OCCLUSION_CULLED (cull_data.occlusion_buffer != nullptr && (cull_data.scenario->instance_data[i].flags & InstanceData::FLAG_IGNORE_OCCLUSION_CULLING) == 0 && cull_data.occlusion_buffer->is_occluded(cull_data.scenario->instance_aabbs[i].bounds, cull_data.cam_transform.origin, inv_cam_transform, *cull_data.camera_matrix, z_near))
|
||||
|
||||
|
@ -2593,6 +2666,16 @@ void RendererSceneCull::_scene_cull(CullData &cull_data, InstanceCullResult &cul
|
|||
}
|
||||
}
|
||||
|
||||
if (idata.parent_array_index != -1) {
|
||||
float fade = 1.0f;
|
||||
const uint32_t &parent_flags = cull_data.scenario->instance_data[idata.parent_array_index].flags;
|
||||
if (parent_flags & InstanceData::FLAG_VISIBILITY_DEPENDENCY_FADE_CHILDREN) {
|
||||
const int32_t &parent_idx = cull_data.scenario->instance_data[idata.parent_array_index].visibility_index;
|
||||
fade = cull_data.scenario->instance_visibility[parent_idx].children_fade_alpha;
|
||||
}
|
||||
scene_render->geometry_instance_set_parent_fade_alpha(idata.instance_geometry, fade);
|
||||
}
|
||||
|
||||
if (geometry_instance_pair_mask & (1 << RS::INSTANCE_LIGHT) && (idata.flags & InstanceData::FLAG_GEOM_LIGHTING_DIRTY)) {
|
||||
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(idata.instance->base_data);
|
||||
uint32_t idx = 0;
|
||||
|
|
|
@ -267,7 +267,8 @@ public:
|
|||
FLAG_VISIBILITY_DEPENDENCY_NEEDS_CHECK = (3 << 20), // 2 bits, overlaps with the other vis. dependency flags
|
||||
FLAG_VISIBILITY_DEPENDENCY_HIDDEN_CLOSE_RANGE = (1 << 20),
|
||||
FLAG_VISIBILITY_DEPENDENCY_HIDDEN = (1 << 21),
|
||||
FLAG_GEOM_PROJECTOR_SOFTSHADOW_DIRTY = (1 << 22),
|
||||
FLAG_VISIBILITY_DEPENDENCY_FADE_CHILDREN = (1 << 22),
|
||||
FLAG_GEOM_PROJECTOR_SOFTSHADOW_DIRTY = (1 << 23),
|
||||
};
|
||||
|
||||
uint32_t flags = 0;
|
||||
|
@ -286,12 +287,14 @@ public:
|
|||
struct InstanceVisibilityData {
|
||||
uint64_t viewport_state = 0;
|
||||
int32_t array_index = -1;
|
||||
RS::VisibilityRangeFadeMode fade_mode = RS::VISIBILITY_RANGE_FADE_DISABLED;
|
||||
Vector3 position;
|
||||
Instance *instance = nullptr;
|
||||
float range_begin = 0.0f;
|
||||
float range_end = 0.0f;
|
||||
float range_begin_margin = 0.0f;
|
||||
float range_end_margin = 0.0f;
|
||||
float children_fade_alpha = 1.0f;
|
||||
};
|
||||
|
||||
class VisibilityArray : public BinSortedArray<InstanceVisibilityData> {
|
||||
|
@ -440,6 +443,7 @@ public:
|
|||
float visibility_range_end;
|
||||
float visibility_range_begin_margin;
|
||||
float visibility_range_end_margin;
|
||||
RS::VisibilityRangeFadeMode visibility_range_fade_mode = RS::VISIBILITY_RANGE_FADE_DISABLED;
|
||||
Instance *visibility_parent = nullptr;
|
||||
Set<Instance *> visibility_dependencies;
|
||||
uint32_t visibility_dependencies_depth;
|
||||
|
@ -920,6 +924,7 @@ public:
|
|||
virtual void instance_set_blend_shape_weight(RID p_instance, int p_shape, float p_weight);
|
||||
virtual void instance_set_surface_override_material(RID p_instance, int p_surface, RID p_material);
|
||||
virtual void instance_set_visible(RID p_instance, bool p_visible);
|
||||
virtual void instance_geometry_set_transparency(RID p_instance, float p_transparency);
|
||||
|
||||
virtual void instance_set_custom_aabb(RID p_instance, AABB p_aabb);
|
||||
|
||||
|
@ -941,7 +946,7 @@ public:
|
|||
virtual void instance_geometry_set_cast_shadows_setting(RID p_instance, RS::ShadowCastingSetting p_shadow_casting_setting);
|
||||
virtual void instance_geometry_set_material_override(RID p_instance, RID p_material);
|
||||
|
||||
virtual void instance_geometry_set_visibility_range(RID p_instance, float p_min, float p_max, float p_min_margin, float p_max_margin);
|
||||
virtual void instance_geometry_set_visibility_range(RID p_instance, float p_min, float p_max, float p_min_margin, float p_max_margin, RS::VisibilityRangeFadeMode p_fade_mode);
|
||||
|
||||
virtual void instance_geometry_set_lightmap(RID p_instance, RID p_lightmap, const Rect2 &p_lightmap_uv_scale, int p_slice_index);
|
||||
virtual void instance_geometry_set_lod_bias(RID p_instance, float p_lod_bias);
|
||||
|
@ -1013,7 +1018,7 @@ public:
|
|||
|
||||
void _visibility_cull_threaded(uint32_t p_thread, VisibilityCullData *cull_data);
|
||||
void _visibility_cull(const VisibilityCullData &cull_data, uint64_t p_from, uint64_t p_to);
|
||||
_FORCE_INLINE_ void _visibility_cull(const VisibilityCullData &cull_data, uint64_t p_idx);
|
||||
template <bool p_fade_check>
|
||||
_FORCE_INLINE_ int _visibility_range_check(InstanceVisibilityData &r_vis_data, const Vector3 &p_camera_pos, uint64_t p_viewport_mask);
|
||||
|
||||
struct CullData {
|
||||
|
@ -1030,6 +1035,7 @@ public:
|
|||
|
||||
void _scene_cull_threaded(uint32_t p_thread, CullData *cull_data);
|
||||
void _scene_cull(CullData &cull_data, InstanceCullResult &cull_result, uint64_t p_from, uint64_t p_to);
|
||||
_FORCE_INLINE_ bool _visibility_parent_check(const CullData &p_cull_data, const InstanceData &p_instance_data);
|
||||
|
||||
bool _render_reflection_probe_step(Instance *p_instance, int p_step);
|
||||
void _render_scene(const RendererSceneRender::CameraData *p_camera_data, RID p_render_buffers, RID p_environment, RID p_force_camera_effects, uint32_t p_visible_layers, RID p_scenario, RID p_viewport, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold, bool p_using_shadows = true, RenderInfo *r_render_info = nullptr);
|
||||
|
|
|
@ -56,6 +56,9 @@ public:
|
|||
virtual void geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabbb) = 0;
|
||||
virtual void geometry_instance_set_layer_mask(GeometryInstance *p_geometry_instance, uint32_t p_layer_mask) = 0;
|
||||
virtual void geometry_instance_set_lod_bias(GeometryInstance *p_geometry_instance, float p_lod_bias) = 0;
|
||||
virtual void geometry_instance_set_transparency(GeometryInstance *p_geometry_instance, float p_transparency) = 0;
|
||||
virtual 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) = 0;
|
||||
virtual void geometry_instance_set_parent_fade_alpha(GeometryInstance *p_geometry_instance, float p_alpha) = 0;
|
||||
virtual void geometry_instance_set_use_baked_light(GeometryInstance *p_geometry_instance, bool p_enable) = 0;
|
||||
virtual void geometry_instance_set_use_dynamic_gi(GeometryInstance *p_geometry_instance, bool p_enable) = 0;
|
||||
virtual void geometry_instance_set_use_lightmap(GeometryInstance *p_geometry_instance, RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) = 0;
|
||||
|
|
|
@ -702,10 +702,10 @@ public:
|
|||
FUNC2(instance_geometry_set_cast_shadows_setting, RID, ShadowCastingSetting)
|
||||
FUNC2(instance_geometry_set_material_override, RID, RID)
|
||||
|
||||
FUNC5(instance_geometry_set_visibility_range, RID, float, float, float, float)
|
||||
FUNC6(instance_geometry_set_visibility_range, RID, float, float, float, float, VisibilityRangeFadeMode)
|
||||
FUNC4(instance_geometry_set_lightmap, RID, RID, const Rect2 &, int)
|
||||
FUNC2(instance_geometry_set_lod_bias, RID, float)
|
||||
|
||||
FUNC2(instance_geometry_set_transparency, RID, float)
|
||||
FUNC3(instance_geometry_set_shader_parameter, RID, const StringName &, const Variant &)
|
||||
FUNC2RC(Variant, instance_geometry_get_shader_parameter, RID, const StringName &)
|
||||
FUNC2RC(Variant, instance_geometry_get_shader_parameter_default_value, RID, const StringName &)
|
||||
|
|
|
@ -2433,6 +2433,7 @@ void RenderingServer::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("instance_set_blend_shape_weight", "instance", "shape", "weight"), &RenderingServer::instance_set_blend_shape_weight);
|
||||
ClassDB::bind_method(D_METHOD("instance_set_surface_override_material", "instance", "surface", "material"), &RenderingServer::instance_set_surface_override_material);
|
||||
ClassDB::bind_method(D_METHOD("instance_set_visible", "instance", "visible"), &RenderingServer::instance_set_visible);
|
||||
ClassDB::bind_method(D_METHOD("instance_geometry_set_transparency", "instance", "transparency"), &RenderingServer::instance_geometry_set_transparency);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("instance_set_custom_aabb", "instance", "aabb"), &RenderingServer::instance_set_custom_aabb);
|
||||
|
||||
|
@ -2443,7 +2444,7 @@ void RenderingServer::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("instance_geometry_set_flag", "instance", "flag", "enabled"), &RenderingServer::instance_geometry_set_flag);
|
||||
ClassDB::bind_method(D_METHOD("instance_geometry_set_cast_shadows_setting", "instance", "shadow_casting_setting"), &RenderingServer::instance_geometry_set_cast_shadows_setting);
|
||||
ClassDB::bind_method(D_METHOD("instance_geometry_set_material_override", "instance", "material"), &RenderingServer::instance_geometry_set_material_override);
|
||||
ClassDB::bind_method(D_METHOD("instance_geometry_set_visibility_range", "instance", "min", "max", "min_margin", "max_margin"), &RenderingServer::instance_geometry_set_visibility_range);
|
||||
ClassDB::bind_method(D_METHOD("instance_geometry_set_visibility_range", "instance", "min", "max", "min_margin", "max_margin", "fade_mode"), &RenderingServer::instance_geometry_set_visibility_range);
|
||||
ClassDB::bind_method(D_METHOD("instance_geometry_set_lightmap", "instance", "lightmap", "lightmap_uv_scale", "lightmap_slice"), &RenderingServer::instance_geometry_set_lightmap);
|
||||
ClassDB::bind_method(D_METHOD("instance_geometry_set_lod_bias", "instance", "lod_bias"), &RenderingServer::instance_geometry_set_lod_bias);
|
||||
|
||||
|
@ -2483,6 +2484,10 @@ void RenderingServer::_bind_methods() {
|
|||
BIND_ENUM_CONSTANT(SHADOW_CASTING_SETTING_DOUBLE_SIDED);
|
||||
BIND_ENUM_CONSTANT(SHADOW_CASTING_SETTING_SHADOWS_ONLY);
|
||||
|
||||
BIND_ENUM_CONSTANT(VISIBILITY_RANGE_FADE_DISABLED);
|
||||
BIND_ENUM_CONSTANT(VISIBILITY_RANGE_FADE_SELF);
|
||||
BIND_ENUM_CONSTANT(VISIBILITY_RANGE_FADE_DEPENDENCIES);
|
||||
|
||||
/* Bake 3D Object */
|
||||
|
||||
ClassDB::bind_method(D_METHOD("bake_render_uv2", "base", "material_overrides", "image_size"), &RenderingServer::bake_render_uv2);
|
||||
|
|
|
@ -1167,12 +1167,19 @@ public:
|
|||
SHADOW_CASTING_SETTING_SHADOWS_ONLY,
|
||||
};
|
||||
|
||||
enum VisibilityRangeFadeMode {
|
||||
VISIBILITY_RANGE_FADE_DISABLED,
|
||||
VISIBILITY_RANGE_FADE_SELF,
|
||||
VISIBILITY_RANGE_FADE_DEPENDENCIES,
|
||||
};
|
||||
|
||||
virtual void instance_geometry_set_flag(RID p_instance, InstanceFlags p_flags, bool p_enabled) = 0;
|
||||
virtual void instance_geometry_set_cast_shadows_setting(RID p_instance, ShadowCastingSetting p_shadow_casting_setting) = 0;
|
||||
virtual void instance_geometry_set_material_override(RID p_instance, RID p_material) = 0;
|
||||
virtual void instance_geometry_set_visibility_range(RID p_instance, float p_min, float p_max, float p_min_margin, float p_max_margin) = 0;
|
||||
virtual void instance_geometry_set_visibility_range(RID p_instance, float p_min, float p_max, float p_min_margin, float p_max_margin, VisibilityRangeFadeMode p_fade_mode) = 0;
|
||||
virtual void instance_geometry_set_lightmap(RID p_instance, RID p_lightmap, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice) = 0;
|
||||
virtual void instance_geometry_set_lod_bias(RID p_instance, float p_lod_bias) = 0;
|
||||
virtual void instance_geometry_set_transparency(RID p_instance, float p_transparency) = 0;
|
||||
|
||||
virtual void instance_geometry_set_shader_parameter(RID p_instance, const StringName &, const Variant &p_value) = 0;
|
||||
virtual Variant instance_geometry_get_shader_parameter(RID p_instance, const StringName &) const = 0;
|
||||
|
@ -1565,6 +1572,7 @@ VARIANT_ENUM_CAST(RenderingServer::ShadowQuality);
|
|||
VARIANT_ENUM_CAST(RenderingServer::InstanceType);
|
||||
VARIANT_ENUM_CAST(RenderingServer::InstanceFlags);
|
||||
VARIANT_ENUM_CAST(RenderingServer::ShadowCastingSetting);
|
||||
VARIANT_ENUM_CAST(RenderingServer::VisibilityRangeFadeMode);
|
||||
VARIANT_ENUM_CAST(RenderingServer::NinePatchAxisMode);
|
||||
VARIANT_ENUM_CAST(RenderingServer::CanvasItemTextureFilter);
|
||||
VARIANT_ENUM_CAST(RenderingServer::CanvasItemTextureRepeat);
|
||||
|
|
Loading…
Reference in New Issue