Added material_overlay property to MeshInstance3D
Applying overlay materials into multi-surface meshes currently requires adding a next pass material to all the surfaces, which might be cumbersome when the material is to be applied to a range of different geometries. This also makes it not trivial to use AnimationPlayer to control the material in case of visual effects. The material_override property is not an option as it works replacing the active material for the surfaces, not adding a new pass. This commit adds the material_overlay property to GeometryInstance3D (and therefore MeshInstance3D), having the same reach as material_override (that is, all surfaces) but adding a new material pass on top of the active materials, instead of replacing them.
This commit is contained in:
parent
2c7fcdd7f9
commit
ca79373d13
|
@ -47,6 +47,10 @@
|
|||
</member>
|
||||
<member name="lod_bias" type="float" setter="set_lod_bias" getter="get_lod_bias" default="1.0">
|
||||
</member>
|
||||
<member name="material_overlay" type="Material" setter="set_material_overlay" getter="get_material_overlay">
|
||||
The material overlay for the whole geometry.
|
||||
If a material is assigned to this property, it will be rendered on top of any other active material for all the surfaces.
|
||||
</member>
|
||||
<member name="material_override" type="Material" setter="set_material_override" getter="get_material_override">
|
||||
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.
|
||||
|
|
|
@ -1403,6 +1403,14 @@
|
|||
<description>
|
||||
</description>
|
||||
</method>
|
||||
<method name="instance_geometry_set_material_overlay">
|
||||
<return type="void" />
|
||||
<argument index="0" name="instance" type="RID" />
|
||||
<argument index="1" name="material" type="RID" />
|
||||
<description>
|
||||
Sets a material that will be rendered for all surfaces on top of active materials for the mesh associated with this instance. Equivalent to [member GeometryInstance3D.material_overlay].
|
||||
</description>
|
||||
</method>
|
||||
<method name="instance_geometry_set_material_override">
|
||||
<return type="void" />
|
||||
<argument index="0" name="instance" type="RID" />
|
||||
|
|
|
@ -43,6 +43,9 @@ void RasterizerSceneGLES3::geometry_instance_set_skeleton(GeometryInstance *p_ge
|
|||
void RasterizerSceneGLES3::geometry_instance_set_material_override(GeometryInstance *p_geometry_instance, RID p_override) {
|
||||
}
|
||||
|
||||
void RasterizerSceneGLES3::geometry_instance_set_material_overlay(GeometryInstance *p_geometry_instance, RID p_overlay) {
|
||||
}
|
||||
|
||||
void RasterizerSceneGLES3::geometry_instance_set_surface_materials(GeometryInstance *p_geometry_instance, const Vector<RID> &p_material) {
|
||||
}
|
||||
|
||||
|
|
|
@ -52,6 +52,7 @@ public:
|
|||
GeometryInstance *geometry_instance_create(RID p_base) override;
|
||||
void geometry_instance_set_skeleton(GeometryInstance *p_geometry_instance, RID p_skeleton) override;
|
||||
void geometry_instance_set_material_override(GeometryInstance *p_geometry_instance, RID p_override) override;
|
||||
void geometry_instance_set_material_overlay(GeometryInstance *p_geometry_instance, RID p_overlay) override;
|
||||
void geometry_instance_set_surface_materials(GeometryInstance *p_geometry_instance, const Vector<RID> &p_material) override;
|
||||
void geometry_instance_set_mesh_instance(GeometryInstance *p_geometry_instance, RID p_mesh_instance) override;
|
||||
void geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabbb) override;
|
||||
|
|
|
@ -152,6 +152,15 @@ Ref<Material> GeometryInstance3D::get_material_override() const {
|
|||
return material_override;
|
||||
}
|
||||
|
||||
void GeometryInstance3D::set_material_overlay(const Ref<Material> &p_material) {
|
||||
material_overlay = p_material;
|
||||
RS::get_singleton()->instance_geometry_set_material_overlay(get_instance(), p_material.is_valid() ? p_material->get_rid() : RID());
|
||||
}
|
||||
|
||||
Ref<Material> GeometryInstance3D::get_material_overlay() const {
|
||||
return material_overlay;
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -398,6 +407,9 @@ void GeometryInstance3D::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("set_material_override", "material"), &GeometryInstance3D::set_material_override);
|
||||
ClassDB::bind_method(D_METHOD("get_material_override"), &GeometryInstance3D::get_material_override);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_material_overlay", "material"), &GeometryInstance3D::set_material_overlay);
|
||||
ClassDB::bind_method(D_METHOD("get_material_overlay"), &GeometryInstance3D::get_material_overlay);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_cast_shadows_setting", "shadow_casting_setting"), &GeometryInstance3D::set_cast_shadows_setting);
|
||||
ClassDB::bind_method(D_METHOD("get_cast_shadows_setting"), &GeometryInstance3D::get_cast_shadows_setting);
|
||||
|
||||
|
@ -443,6 +455,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::OBJECT, "material_overlay", PROPERTY_HINT_RESOURCE_TYPE, "BaseMaterial3D,ShaderMaterial", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_DEFERRED_SET_RESOURCE), "set_material_overlay", "get_material_overlay");
|
||||
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");
|
||||
|
|
|
@ -110,6 +110,7 @@ public:
|
|||
private:
|
||||
ShadowCastingSetting shadow_casting_setting = SHADOW_CASTING_SETTING_ON;
|
||||
Ref<Material> material_override;
|
||||
Ref<Material> material_overlay;
|
||||
|
||||
float visibility_range_begin = 0.0;
|
||||
float visibility_range_end = 0.0;
|
||||
|
@ -164,6 +165,9 @@ public:
|
|||
void set_material_override(const Ref<Material> &p_material);
|
||||
Ref<Material> get_material_override() const;
|
||||
|
||||
void set_material_overlay(const Ref<Material> &p_material);
|
||||
Ref<Material> get_material_overlay() const;
|
||||
|
||||
void set_extra_cull_margin(float p_margin);
|
||||
float get_extra_cull_margin() const;
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@ public:
|
|||
GeometryInstance *geometry_instance_create(RID p_base) override { return nullptr; }
|
||||
void geometry_instance_set_skeleton(GeometryInstance *p_geometry_instance, RID p_skeleton) override {}
|
||||
void geometry_instance_set_material_override(GeometryInstance *p_geometry_instance, RID p_override) override {}
|
||||
void geometry_instance_set_material_overlay(GeometryInstance *p_geometry_instance, RID p_override) override {}
|
||||
void geometry_instance_set_surface_materials(GeometryInstance *p_geometry_instance, const Vector<RID> &p_material) override {}
|
||||
void geometry_instance_set_mesh_instance(GeometryInstance *p_geometry_instance, RID p_mesh_instance) override {}
|
||||
void geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabbb) override {}
|
||||
|
|
|
@ -2674,6 +2674,24 @@ void RenderForwardClustered::_geometry_instance_add_surface_with_material(Geomet
|
|||
sdcache->sort.uses_softshadow = ginstance->using_softshadows;
|
||||
}
|
||||
|
||||
void RenderForwardClustered::_geometry_instance_add_surface_with_material_chain(GeometryInstanceForwardClustered *ginstance, uint32_t p_surface, SceneShaderForwardClustered::MaterialData *p_material, RID p_mat_src, RID p_mesh) {
|
||||
SceneShaderForwardClustered::MaterialData *material = p_material;
|
||||
|
||||
_geometry_instance_add_surface_with_material(ginstance, p_surface, material, p_mat_src.get_local_index(), storage->material_get_shader_id(p_mat_src), p_mesh);
|
||||
|
||||
while (material->next_pass.is_valid()) {
|
||||
RID next_pass = material->next_pass;
|
||||
material = (SceneShaderForwardClustered::MaterialData *)storage->material_get_data(next_pass, RendererStorageRD::SHADER_TYPE_3D);
|
||||
if (!material || !material->shader_data->valid) {
|
||||
break;
|
||||
}
|
||||
if (ginstance->data->dirty_dependencies) {
|
||||
storage->material_update_dependency(next_pass, &ginstance->data->dependency_tracker);
|
||||
}
|
||||
_geometry_instance_add_surface_with_material(ginstance, p_surface, material, next_pass.get_local_index(), storage->material_get_shader_id(next_pass), p_mesh);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderForwardClustered::_geometry_instance_add_surface(GeometryInstanceForwardClustered *ginstance, uint32_t p_surface, RID p_material, RID p_mesh) {
|
||||
RID m_src;
|
||||
|
||||
|
@ -2699,18 +2717,19 @@ void RenderForwardClustered::_geometry_instance_add_surface(GeometryInstanceForw
|
|||
|
||||
ERR_FAIL_COND(!material);
|
||||
|
||||
_geometry_instance_add_surface_with_material(ginstance, p_surface, material, m_src.get_local_index(), storage->material_get_shader_id(m_src), p_mesh);
|
||||
_geometry_instance_add_surface_with_material_chain(ginstance, p_surface, material, m_src, p_mesh);
|
||||
|
||||
while (material->next_pass.is_valid()) {
|
||||
RID next_pass = material->next_pass;
|
||||
material = (SceneShaderForwardClustered::MaterialData *)storage->material_get_data(next_pass, RendererStorageRD::SHADER_TYPE_3D);
|
||||
if (!material || !material->shader_data->valid) {
|
||||
break;
|
||||
if (ginstance->data->material_overlay.is_valid()) {
|
||||
m_src = ginstance->data->material_overlay;
|
||||
|
||||
material = (SceneShaderForwardClustered::MaterialData *)storage->material_get_data(m_src, RendererStorageRD::SHADER_TYPE_3D);
|
||||
if (material && material->shader_data->valid) {
|
||||
if (ginstance->data->dirty_dependencies) {
|
||||
storage->material_update_dependency(m_src, &ginstance->data->dependency_tracker);
|
||||
}
|
||||
|
||||
_geometry_instance_add_surface_with_material_chain(ginstance, p_surface, material, m_src, p_mesh);
|
||||
}
|
||||
if (ginstance->data->dirty_dependencies) {
|
||||
storage->material_update_dependency(next_pass, &ginstance->data->dependency_tracker);
|
||||
}
|
||||
_geometry_instance_add_surface_with_material(ginstance, p_surface, material, next_pass.get_local_index(), storage->material_get_shader_id(next_pass), p_mesh);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2919,6 +2938,13 @@ void RenderForwardClustered::geometry_instance_set_material_override(GeometryIns
|
|||
_geometry_instance_mark_dirty(ginstance);
|
||||
ginstance->data->dirty_dependencies = true;
|
||||
}
|
||||
void RenderForwardClustered::geometry_instance_set_material_overlay(GeometryInstance *p_geometry_instance, RID p_overlay) {
|
||||
GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance);
|
||||
ERR_FAIL_COND(!ginstance);
|
||||
ginstance->data->material_overlay = p_overlay;
|
||||
_geometry_instance_mark_dirty(ginstance);
|
||||
ginstance->data->dirty_dependencies = true;
|
||||
}
|
||||
void RenderForwardClustered::geometry_instance_set_surface_materials(GeometryInstance *p_geometry_instance, const Vector<RID> &p_materials) {
|
||||
GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance);
|
||||
ERR_FAIL_COND(!ginstance);
|
||||
|
|
|
@ -496,6 +496,7 @@ class RenderForwardClustered : public RendererSceneRenderRD {
|
|||
RID skeleton;
|
||||
Vector<RID> surface_materials;
|
||||
RID material_override;
|
||||
RID material_overlay;
|
||||
AABB aabb;
|
||||
|
||||
bool use_dynamic_gi = false;
|
||||
|
@ -523,6 +524,7 @@ class RenderForwardClustered : public RendererSceneRenderRD {
|
|||
PagedAllocator<GeometryInstanceLightmapSH> geometry_instance_lightmap_sh;
|
||||
|
||||
void _geometry_instance_add_surface_with_material(GeometryInstanceForwardClustered *ginstance, uint32_t p_surface, SceneShaderForwardClustered::MaterialData *p_material, uint32_t p_material_id, uint32_t p_shader_id, RID p_mesh);
|
||||
void _geometry_instance_add_surface_with_material_chain(GeometryInstanceForwardClustered *ginstance, uint32_t p_surface, SceneShaderForwardClustered::MaterialData *p_material, RID p_mat_src, RID p_mesh);
|
||||
void _geometry_instance_add_surface(GeometryInstanceForwardClustered *ginstance, uint32_t p_surface, RID p_material, RID p_mesh);
|
||||
void _geometry_instance_mark_dirty(GeometryInstance *p_geometry_instance);
|
||||
void _geometry_instance_update(GeometryInstance *p_geometry_instance);
|
||||
|
@ -612,6 +614,7 @@ public:
|
|||
virtual GeometryInstance *geometry_instance_create(RID p_base) override;
|
||||
virtual void geometry_instance_set_skeleton(GeometryInstance *p_geometry_instance, RID p_skeleton) override;
|
||||
virtual void geometry_instance_set_material_override(GeometryInstance *p_geometry_instance, RID p_override) override;
|
||||
virtual void geometry_instance_set_material_overlay(GeometryInstance *p_geometry_instance, RID p_override) override;
|
||||
virtual void geometry_instance_set_surface_materials(GeometryInstance *p_geometry_instance, const Vector<RID> &p_materials) override;
|
||||
virtual void geometry_instance_set_mesh_instance(GeometryInstance *p_geometry_instance, RID p_mesh_instance) override;
|
||||
virtual void geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb) override;
|
||||
|
|
|
@ -2033,6 +2033,15 @@ void RenderForwardMobile::geometry_instance_set_material_override(GeometryInstan
|
|||
ginstance->data->dirty_dependencies = true;
|
||||
}
|
||||
|
||||
void RenderForwardMobile::geometry_instance_set_material_overlay(GeometryInstance *p_geometry_instance, RID p_overlay) {
|
||||
GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance);
|
||||
ERR_FAIL_COND(!ginstance);
|
||||
ginstance->data->material_overlay = p_overlay;
|
||||
|
||||
_geometry_instance_mark_dirty(ginstance);
|
||||
ginstance->data->dirty_dependencies = true;
|
||||
}
|
||||
|
||||
void RenderForwardMobile::geometry_instance_set_surface_materials(GeometryInstance *p_geometry_instance, const Vector<RID> &p_materials) {
|
||||
GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance);
|
||||
ERR_FAIL_COND(!ginstance);
|
||||
|
@ -2359,6 +2368,24 @@ void RenderForwardMobile::_geometry_instance_add_surface_with_material(GeometryI
|
|||
sdcache->sort.priority = p_material->priority;
|
||||
}
|
||||
|
||||
void RenderForwardMobile::_geometry_instance_add_surface_with_material_chain(GeometryInstanceForwardMobile *ginstance, uint32_t p_surface, SceneShaderForwardMobile::MaterialData *p_material, RID p_mat_src, RID p_mesh) {
|
||||
SceneShaderForwardMobile::MaterialData *material = p_material;
|
||||
|
||||
_geometry_instance_add_surface_with_material(ginstance, p_surface, material, p_mat_src.get_local_index(), storage->material_get_shader_id(p_mat_src), p_mesh);
|
||||
|
||||
while (material->next_pass.is_valid()) {
|
||||
RID next_pass = material->next_pass;
|
||||
material = (SceneShaderForwardMobile::MaterialData *)storage->material_get_data(next_pass, RendererStorageRD::SHADER_TYPE_3D);
|
||||
if (!material || !material->shader_data->valid) {
|
||||
break;
|
||||
}
|
||||
if (ginstance->data->dirty_dependencies) {
|
||||
storage->material_update_dependency(next_pass, &ginstance->data->dependency_tracker);
|
||||
}
|
||||
_geometry_instance_add_surface_with_material(ginstance, p_surface, material, next_pass.get_local_index(), storage->material_get_shader_id(next_pass), p_mesh);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderForwardMobile::_geometry_instance_add_surface(GeometryInstanceForwardMobile *ginstance, uint32_t p_surface, RID p_material, RID p_mesh) {
|
||||
RID m_src;
|
||||
|
||||
|
@ -2384,18 +2411,19 @@ void RenderForwardMobile::_geometry_instance_add_surface(GeometryInstanceForward
|
|||
|
||||
ERR_FAIL_COND(!material);
|
||||
|
||||
_geometry_instance_add_surface_with_material(ginstance, p_surface, material, m_src.get_local_index(), storage->material_get_shader_id(m_src), p_mesh);
|
||||
_geometry_instance_add_surface_with_material_chain(ginstance, p_surface, material, m_src, p_mesh);
|
||||
|
||||
while (material->next_pass.is_valid()) {
|
||||
RID next_pass = material->next_pass;
|
||||
material = (SceneShaderForwardMobile::MaterialData *)storage->material_get_data(next_pass, RendererStorageRD::SHADER_TYPE_3D);
|
||||
if (!material || !material->shader_data->valid) {
|
||||
break;
|
||||
if (ginstance->data->material_overlay.is_valid()) {
|
||||
m_src = ginstance->data->material_overlay;
|
||||
|
||||
material = (SceneShaderForwardMobile::MaterialData *)storage->material_get_data(m_src, RendererStorageRD::SHADER_TYPE_3D);
|
||||
if (material && material->shader_data->valid) {
|
||||
if (ginstance->data->dirty_dependencies) {
|
||||
storage->material_update_dependency(m_src, &ginstance->data->dependency_tracker);
|
||||
}
|
||||
|
||||
_geometry_instance_add_surface_with_material_chain(ginstance, p_surface, material, m_src, p_mesh);
|
||||
}
|
||||
if (ginstance->data->dirty_dependencies) {
|
||||
storage->material_update_dependency(next_pass, &ginstance->data->dependency_tracker);
|
||||
}
|
||||
_geometry_instance_add_surface_with_material(ginstance, p_surface, material, next_pass.get_local_index(), storage->material_get_shader_id(next_pass), p_mesh);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -586,6 +586,7 @@ protected:
|
|||
RID skeleton;
|
||||
Vector<RID> surface_materials;
|
||||
RID material_override;
|
||||
RID material_overlay;
|
||||
AABB aabb;
|
||||
|
||||
bool use_baked_light = false;
|
||||
|
@ -620,6 +621,7 @@ public:
|
|||
PagedAllocator<GeometryInstanceLightmapSH> geometry_instance_lightmap_sh;
|
||||
|
||||
void _geometry_instance_add_surface_with_material(GeometryInstanceForwardMobile *ginstance, uint32_t p_surface, SceneShaderForwardMobile::MaterialData *p_material, uint32_t p_material_id, uint32_t p_shader_id, RID p_mesh);
|
||||
void _geometry_instance_add_surface_with_material_chain(GeometryInstanceForwardMobile *ginstance, uint32_t p_surface, SceneShaderForwardMobile::MaterialData *p_material, RID p_mat_src, RID p_mesh);
|
||||
void _geometry_instance_add_surface(GeometryInstanceForwardMobile *ginstance, uint32_t p_surface, RID p_material, RID p_mesh);
|
||||
void _geometry_instance_mark_dirty(GeometryInstance *p_geometry_instance);
|
||||
void _geometry_instance_update(GeometryInstance *p_geometry_instance);
|
||||
|
@ -628,6 +630,7 @@ public:
|
|||
virtual GeometryInstance *geometry_instance_create(RID p_base) override;
|
||||
virtual void geometry_instance_set_skeleton(GeometryInstance *p_geometry_instance, RID p_skeleton) override;
|
||||
virtual void geometry_instance_set_material_override(GeometryInstance *p_geometry_instance, RID p_override) override;
|
||||
virtual void geometry_instance_set_material_overlay(GeometryInstance *p_geometry_instance, RID p_overlay) override;
|
||||
virtual void geometry_instance_set_surface_materials(GeometryInstance *p_geometry_instance, const Vector<RID> &p_materials) override;
|
||||
virtual void geometry_instance_set_mesh_instance(GeometryInstance *p_geometry_instance, RID p_mesh_instance) override;
|
||||
virtual void geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb) override;
|
||||
|
|
|
@ -95,6 +95,7 @@ public:
|
|||
virtual void instance_geometry_set_flag(RID p_instance, RS::InstanceFlags p_flags, bool p_enabled) = 0;
|
||||
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_material_overlay(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, 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;
|
||||
|
|
|
@ -636,6 +636,7 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) {
|
|||
|
||||
scene_render->geometry_instance_set_skeleton(geom->geometry_instance, instance->skeleton);
|
||||
scene_render->geometry_instance_set_material_override(geom->geometry_instance, instance->material_override);
|
||||
scene_render->geometry_instance_set_material_overlay(geom->geometry_instance, instance->material_overlay);
|
||||
scene_render->geometry_instance_set_surface_materials(geom->geometry_instance, instance->materials);
|
||||
scene_render->geometry_instance_set_transform(geom->geometry_instance, instance->transform, instance->aabb, instance->transformed_aabb);
|
||||
scene_render->geometry_instance_set_layer_mask(geom->geometry_instance, instance->layer_mask);
|
||||
|
@ -1222,6 +1223,19 @@ void RendererSceneCull::instance_geometry_set_material_override(RID p_instance,
|
|||
}
|
||||
}
|
||||
|
||||
void RendererSceneCull::instance_geometry_set_material_overlay(RID p_instance, RID p_material) {
|
||||
Instance *instance = instance_owner.get_or_null(p_instance);
|
||||
ERR_FAIL_COND(!instance);
|
||||
|
||||
instance->material_overlay = p_material;
|
||||
_instance_queue_update(instance, false, true);
|
||||
|
||||
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_material_overlay(geom->geometry_instance, p_material);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -3656,6 +3670,10 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) {
|
|||
RSG::storage->material_update_dependency(p_instance->material_override, &p_instance->dependency_tracker);
|
||||
}
|
||||
|
||||
if (p_instance->material_overlay.is_valid()) {
|
||||
RSG::storage->material_update_dependency(p_instance->material_overlay, &p_instance->dependency_tracker);
|
||||
}
|
||||
|
||||
if (p_instance->base_type == RS::INSTANCE_MESH) {
|
||||
//remove materials no longer used and un-own them
|
||||
|
||||
|
@ -3785,6 +3803,12 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) {
|
|||
}
|
||||
}
|
||||
|
||||
if (p_instance->material_overlay.is_valid()) {
|
||||
can_cast_shadows = can_cast_shadows || RSG::storage->material_casts_shadows(p_instance->material_overlay);
|
||||
is_animated = is_animated || RSG::storage->material_is_animated(p_instance->material_overlay);
|
||||
_update_instance_shader_parameters_from_material(isparams, p_instance->instance_shader_parameters, p_instance->material_overlay);
|
||||
}
|
||||
|
||||
if (can_cast_shadows != geom->can_cast_shadows) {
|
||||
//ability to cast shadows change, let lights now
|
||||
for (Set<Instance *>::Element *E = geom->lights.front(); E; E = E->next()) {
|
||||
|
@ -3897,6 +3921,7 @@ bool RendererSceneCull::free(RID p_rid) {
|
|||
instance_set_scenario(p_rid, RID());
|
||||
instance_set_base(p_rid, RID());
|
||||
instance_geometry_set_material_override(p_rid, RID());
|
||||
instance_geometry_set_material_overlay(p_rid, RID());
|
||||
instance_attach_skeleton(p_rid, RID());
|
||||
|
||||
if (instance->instance_allocated_shader_parameters) {
|
||||
|
|
|
@ -390,6 +390,7 @@ public:
|
|||
|
||||
RID skeleton;
|
||||
RID material_override;
|
||||
RID material_overlay;
|
||||
|
||||
RID mesh_instance; //only used for meshes and when skeleton/blendshapes exist
|
||||
|
||||
|
@ -961,6 +962,7 @@ public:
|
|||
virtual void instance_geometry_set_flag(RID p_instance, RS::InstanceFlags p_flags, bool p_enabled);
|
||||
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_material_overlay(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, RS::VisibilityRangeFadeMode p_fade_mode);
|
||||
|
||||
|
|
|
@ -51,6 +51,7 @@ public:
|
|||
virtual GeometryInstance *geometry_instance_create(RID p_base) = 0;
|
||||
virtual void geometry_instance_set_skeleton(GeometryInstance *p_geometry_instance, RID p_skeleton) = 0;
|
||||
virtual void geometry_instance_set_material_override(GeometryInstance *p_geometry_instance, RID p_override) = 0;
|
||||
virtual void geometry_instance_set_material_overlay(GeometryInstance *p_geometry_instance, RID p_override) = 0;
|
||||
virtual void geometry_instance_set_surface_materials(GeometryInstance *p_geometry_instance, const Vector<RID> &p_material) = 0;
|
||||
virtual void geometry_instance_set_mesh_instance(GeometryInstance *p_geometry_instance, RID p_mesh_instance) = 0;
|
||||
virtual void geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabbb) = 0;
|
||||
|
|
|
@ -712,6 +712,7 @@ public:
|
|||
FUNC3(instance_geometry_set_flag, RID, InstanceFlags, bool)
|
||||
FUNC2(instance_geometry_set_cast_shadows_setting, RID, ShadowCastingSetting)
|
||||
FUNC2(instance_geometry_set_material_override, RID, RID)
|
||||
FUNC2(instance_geometry_set_material_overlay, RID, RID)
|
||||
|
||||
FUNC6(instance_geometry_set_visibility_range, RID, float, float, float, float, VisibilityRangeFadeMode)
|
||||
FUNC4(instance_geometry_set_lightmap, RID, RID, const Rect2 &, int)
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
|
||||
#include "core/config/project_settings.h"
|
||||
#include "servers/rendering/rendering_server_globals.h"
|
||||
|
||||
RenderingServer *RenderingServer::singleton = nullptr;
|
||||
RenderingServer *(*RenderingServer::create_func)() = nullptr;
|
||||
|
||||
|
@ -2462,6 +2463,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_material_overlay", "instance", "material"), &RenderingServer::instance_geometry_set_material_overlay);
|
||||
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);
|
||||
|
|
|
@ -1220,6 +1220,7 @@ public:
|
|||
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_material_overlay(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, 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;
|
||||
|
|
Loading…
Reference in New Issue