diff options
-rw-r--r-- | drivers/gles3/rasterizer_storage_gles3.cpp | 19 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_storage_gles3.h | 3 | ||||
-rw-r--r-- | servers/visual/rasterizer.h | 3 | ||||
-rw-r--r-- | servers/visual/visual_server_scene.cpp | 30 |
4 files changed, 55 insertions, 0 deletions
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp index 0da9e38769..509b14a22e 100644 --- a/drivers/gles3/rasterizer_storage_gles3.cpp +++ b/drivers/gles3/rasterizer_storage_gles3.cpp @@ -5258,6 +5258,23 @@ void RasterizerStorageGLES3::particles_set_emission_transform(RID p_particles, c particles->emission_transform = p_transform; } +int RasterizerStorageGLES3::particles_get_draw_passes(RID p_particles) const { + + const Particles *particles = particles_owner.getornull(p_particles); + ERR_FAIL_COND_V(!particles, 0); + + return particles->draw_passes.size(); +} + +RID RasterizerStorageGLES3::particles_get_draw_pass_mesh(RID p_particles, int p_pass) const { + + const Particles *particles = particles_owner.getornull(p_particles); + ERR_FAIL_COND_V(!particles, RID()); + ERR_FAIL_INDEX_V(p_pass, particles->draw_passes.size(), RID()); + + return particles->draw_passes[p_pass]; +} + void RasterizerStorageGLES3::_particles_process(Particles *particles, float p_delta) { float new_phase = Math::fmod((float)particles->phase + (p_delta / particles->lifetime) * particles->speed_scale, (float)1.0); @@ -5452,6 +5469,8 @@ void RasterizerStorageGLES3::update_particles() { particles->particle_valid_histories[0] = true; } + + particles->instance_change_notify(); //make sure shadows are updated } glDisable(GL_RASTERIZER_DISCARD); diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h index 643554e55d..a53c3d7dd2 100644 --- a/drivers/gles3/rasterizer_storage_gles3.h +++ b/drivers/gles3/rasterizer_storage_gles3.h @@ -1149,6 +1149,9 @@ public: virtual void particles_set_emission_transform(RID p_particles, const Transform &p_transform); void _particles_process(Particles *p_particles, float p_delta); + virtual int particles_get_draw_passes(RID p_particles) const; + virtual RID particles_get_draw_pass_mesh(RID p_particles, int p_pass) const; + /* INSTANCE */ virtual void instance_add_skeleton(RID p_skeleton, RasterizerScene::InstanceBase *p_instance); diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h index 44cfbf74ce..75434c5fc5 100644 --- a/servers/visual/rasterizer.h +++ b/servers/visual/rasterizer.h @@ -465,6 +465,9 @@ public: virtual void particles_set_emission_transform(RID p_particles, const Transform &p_transform) = 0; + virtual int particles_get_draw_passes(RID p_particles) const = 0; + virtual RID particles_get_draw_pass_mesh(RID p_particles, int p_pass) const = 0; + /* RENDER TARGET */ enum RenderTargetFlags { diff --git a/servers/visual/visual_server_scene.cpp b/servers/visual/visual_server_scene.cpp index 352daa9655..6d1f698a5c 100644 --- a/servers/visual/visual_server_scene.cpp +++ b/servers/visual/visual_server_scene.cpp @@ -3323,6 +3323,36 @@ void VisualServerScene::_update_dirty_instance(Instance *p_instance) { } else { can_cast_shadows = false; } + } else if (p_instance->base_type == VS::INSTANCE_PARTICLES) { + + bool cast_shadows = false; + + int dp = VSG::storage->particles_get_draw_passes(p_instance->base); + + for (int i = 0; i < dp; i++) { + + RID mesh = VSG::storage->particles_get_draw_pass_mesh(p_instance->base, i); + + int sc = VSG::storage->mesh_get_surface_count(mesh); + for (int j = 0; j < sc; j++) { + + RID mat = VSG::storage->mesh_surface_get_material(mesh, j); + + if (!mat.is_valid()) { + cast_shadows = true; + break; + } + + if (VSG::storage->material_casts_shadows(mat)) { + cast_shadows = true; + break; + } + } + } + + if (!cast_shadows) { + can_cast_shadows = false; + } } } |