mirror of
https://github.com/godotengine/godot.git
synced 2025-11-01 06:01:14 +00:00
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
18 changed files with 147 additions and 20 deletions
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue