Merge pull request #102399 from clayjohn/cull-mask-overhaul
Overhaul the cull mask internals for Lights, Decals, and Particle Colliders
This commit is contained in:
commit
19bb18716e
@ -209,7 +209,7 @@ void LightStorage::light_set_cull_mask(RID p_light, uint32_t p_mask) {
|
|||||||
light->cull_mask = p_mask;
|
light->cull_mask = p_mask;
|
||||||
|
|
||||||
light->version++;
|
light->version++;
|
||||||
light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT);
|
light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_CULL_MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LightStorage::light_set_shadow_caster_mask(RID p_light, uint32_t p_caster_mask) {
|
void LightStorage::light_set_shadow_caster_mask(RID p_light, uint32_t p_caster_mask) {
|
||||||
|
@ -1319,6 +1319,13 @@ void ParticlesStorage::particles_collision_set_cull_mask(RID p_particles_collisi
|
|||||||
ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_particles_collision);
|
ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_particles_collision);
|
||||||
ERR_FAIL_NULL(particles_collision);
|
ERR_FAIL_NULL(particles_collision);
|
||||||
particles_collision->cull_mask = p_cull_mask;
|
particles_collision->cull_mask = p_cull_mask;
|
||||||
|
particles_collision->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_CULL_MASK);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t ParticlesStorage::particles_collision_get_cull_mask(RID p_particles_collision) const {
|
||||||
|
ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_particles_collision);
|
||||||
|
ERR_FAIL_NULL_V(particles_collision, 0);
|
||||||
|
return particles_collision->cull_mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ParticlesStorage::particles_collision_set_sphere_radius(RID p_particles_collision, real_t p_radius) {
|
void ParticlesStorage::particles_collision_set_sphere_radius(RID p_particles_collision, real_t p_radius) {
|
||||||
|
@ -436,6 +436,7 @@ public:
|
|||||||
GLuint particles_collision_get_heightfield_framebuffer(RID p_particles_collision) const;
|
GLuint particles_collision_get_heightfield_framebuffer(RID p_particles_collision) const;
|
||||||
virtual uint32_t particles_collision_get_height_field_mask(RID p_particles_collision) const override;
|
virtual uint32_t particles_collision_get_height_field_mask(RID p_particles_collision) const override;
|
||||||
virtual void particles_collision_set_height_field_mask(RID p_particles_collision, uint32_t p_heightfield_mask) override;
|
virtual void particles_collision_set_height_field_mask(RID p_particles_collision, uint32_t p_heightfield_mask) override;
|
||||||
|
virtual uint32_t particles_collision_get_cull_mask(RID p_particles_collision) const override;
|
||||||
|
|
||||||
_FORCE_INLINE_ Size2i particles_collision_get_heightfield_size(RID p_particles_collision) const {
|
_FORCE_INLINE_ Size2i particles_collision_get_heightfield_size(RID p_particles_collision) const {
|
||||||
ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_particles_collision);
|
ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_particles_collision);
|
||||||
|
@ -115,6 +115,7 @@ public:
|
|||||||
virtual bool particles_collision_is_heightfield(RID p_particles_collision) const override { return false; }
|
virtual bool particles_collision_is_heightfield(RID p_particles_collision) const override { return false; }
|
||||||
virtual uint32_t particles_collision_get_height_field_mask(RID p_particles_collision) const override { return 0; }
|
virtual uint32_t particles_collision_get_height_field_mask(RID p_particles_collision) const override { return 0; }
|
||||||
virtual void particles_collision_set_height_field_mask(RID p_particles_collision, uint32_t p_heightfield_mask) override {}
|
virtual void particles_collision_set_height_field_mask(RID p_particles_collision, uint32_t p_heightfield_mask) override {}
|
||||||
|
virtual uint32_t particles_collision_get_cull_mask(RID p_particles_collision) const override { return 0; }
|
||||||
|
|
||||||
virtual RID particles_collision_instance_create(RID p_collision) override { return RID(); }
|
virtual RID particles_collision_instance_create(RID p_collision) override { return RID(); }
|
||||||
virtual void particles_collision_instance_free(RID p_rid) override {}
|
virtual void particles_collision_instance_free(RID p_rid) override {}
|
||||||
|
@ -1120,9 +1120,6 @@ void main() {
|
|||||||
uvec2 decal_indices = instances.data[draw_call.instance_index].decals;
|
uvec2 decal_indices = instances.data[draw_call.instance_index].decals;
|
||||||
for (uint i = 0; i < sc_decals(); i++) {
|
for (uint i = 0; i < sc_decals(); i++) {
|
||||||
uint decal_index = (i > 3) ? ((decal_indices.y >> ((i - 4) * 8)) & 0xFF) : ((decal_indices.x >> (i * 8)) & 0xFF);
|
uint decal_index = (i > 3) ? ((decal_indices.y >> ((i - 4) * 8)) & 0xFF) : ((decal_indices.x >> (i * 8)) & 0xFF);
|
||||||
if (!bool(decals.data[decal_index].mask & instances.data[draw_call.instance_index].layer_mask)) {
|
|
||||||
continue; //not masked
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 uv_local = (decals.data[decal_index].xform * vec4(vertex, 1.0)).xyz;
|
vec3 uv_local = (decals.data[decal_index].xform * vec4(vertex, 1.0)).xyz;
|
||||||
if (any(lessThan(uv_local, vec3(0.0, -1.0, 0.0))) || any(greaterThan(uv_local, vec3(1.0)))) {
|
if (any(lessThan(uv_local, vec3(0.0, -1.0, 0.0))) || any(greaterThan(uv_local, vec3(1.0)))) {
|
||||||
|
@ -268,7 +268,7 @@ void LightStorage::light_set_cull_mask(RID p_light, uint32_t p_mask) {
|
|||||||
light->cull_mask = p_mask;
|
light->cull_mask = p_mask;
|
||||||
|
|
||||||
light->version++;
|
light->version++;
|
||||||
light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT);
|
light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_CULL_MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LightStorage::light_set_distance_fade(RID p_light, bool p_enabled, float p_begin, float p_shadow, float p_length) {
|
void LightStorage::light_set_distance_fade(RID p_light, bool p_enabled, float p_begin, float p_shadow, float p_length) {
|
||||||
|
@ -1850,6 +1850,13 @@ void ParticlesStorage::particles_collision_set_cull_mask(RID p_particles_collisi
|
|||||||
ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_particles_collision);
|
ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_particles_collision);
|
||||||
ERR_FAIL_NULL(particles_collision);
|
ERR_FAIL_NULL(particles_collision);
|
||||||
particles_collision->cull_mask = p_cull_mask;
|
particles_collision->cull_mask = p_cull_mask;
|
||||||
|
particles_collision->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_CULL_MASK);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t ParticlesStorage::particles_collision_get_cull_mask(RID p_particles_collision) const {
|
||||||
|
ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_particles_collision);
|
||||||
|
ERR_FAIL_NULL_V(particles_collision, 0);
|
||||||
|
return particles_collision->cull_mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t ParticlesStorage::particles_collision_get_height_field_mask(RID p_particles_collision) const {
|
uint32_t ParticlesStorage::particles_collision_get_height_field_mask(RID p_particles_collision) const {
|
||||||
|
@ -583,6 +583,7 @@ public:
|
|||||||
RID particles_collision_get_heightfield_framebuffer(RID p_particles_collision) const;
|
RID particles_collision_get_heightfield_framebuffer(RID p_particles_collision) const;
|
||||||
virtual uint32_t particles_collision_get_height_field_mask(RID p_particles_collision) const override;
|
virtual uint32_t particles_collision_get_height_field_mask(RID p_particles_collision) const override;
|
||||||
virtual void particles_collision_set_height_field_mask(RID p_particles_collision, uint32_t p_heightfield_mask) override;
|
virtual void particles_collision_set_height_field_mask(RID p_particles_collision, uint32_t p_heightfield_mask) override;
|
||||||
|
virtual uint32_t particles_collision_get_cull_mask(RID p_particles_collision) const override;
|
||||||
|
|
||||||
Dependency *particles_collision_get_dependency(RID p_particles) const;
|
Dependency *particles_collision_get_dependency(RID p_particles) const;
|
||||||
|
|
||||||
|
@ -2744,7 +2744,7 @@ void TextureStorage::decal_set_cull_mask(RID p_decal, uint32_t p_layers) {
|
|||||||
Decal *decal = decal_owner.get_or_null(p_decal);
|
Decal *decal = decal_owner.get_or_null(p_decal);
|
||||||
ERR_FAIL_NULL(decal);
|
ERR_FAIL_NULL(decal);
|
||||||
decal->cull_mask = p_layers;
|
decal->cull_mask = p_layers;
|
||||||
decal->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_DECAL);
|
decal->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_CULL_MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureStorage::decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) {
|
void TextureStorage::decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) {
|
||||||
|
@ -178,6 +178,11 @@ void RendererSceneCull::_instance_pair(Instance *p_A, Instance *p_B) {
|
|||||||
InstanceLightData *light = static_cast<InstanceLightData *>(B->base_data);
|
InstanceLightData *light = static_cast<InstanceLightData *>(B->base_data);
|
||||||
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
|
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
|
||||||
|
|
||||||
|
if (!(light->cull_mask & A->layer_mask)) {
|
||||||
|
// Early return if the object's layer mask doesn't match the light's cull mask.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
geom->lights.insert(B);
|
geom->lights.insert(B);
|
||||||
light->geometries.insert(A);
|
light->geometries.insert(A);
|
||||||
|
|
||||||
@ -222,6 +227,11 @@ void RendererSceneCull::_instance_pair(Instance *p_A, Instance *p_B) {
|
|||||||
InstanceDecalData *decal = static_cast<InstanceDecalData *>(B->base_data);
|
InstanceDecalData *decal = static_cast<InstanceDecalData *>(B->base_data);
|
||||||
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
|
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
|
||||||
|
|
||||||
|
if (!(decal->cull_mask & A->layer_mask)) {
|
||||||
|
// Early return if the object's layer mask doesn't match the decal's cull mask.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
geom->decals.insert(B);
|
geom->decals.insert(B);
|
||||||
decal->geometries.insert(A);
|
decal->geometries.insert(A);
|
||||||
|
|
||||||
@ -267,7 +277,10 @@ void RendererSceneCull::_instance_pair(Instance *p_A, Instance *p_B) {
|
|||||||
voxel_gi->lights.insert(A);
|
voxel_gi->lights.insert(A);
|
||||||
} else if (B->base_type == RS::INSTANCE_PARTICLES_COLLISION && A->base_type == RS::INSTANCE_PARTICLES) {
|
} else if (B->base_type == RS::INSTANCE_PARTICLES_COLLISION && A->base_type == RS::INSTANCE_PARTICLES) {
|
||||||
InstanceParticlesCollisionData *collision = static_cast<InstanceParticlesCollisionData *>(B->base_data);
|
InstanceParticlesCollisionData *collision = static_cast<InstanceParticlesCollisionData *>(B->base_data);
|
||||||
RSG::particles_storage->particles_add_collision(A->base, collision->instance);
|
|
||||||
|
if ((collision->cull_mask & A->layer_mask)) {
|
||||||
|
RSG::particles_storage->particles_add_collision(A->base, collision->instance);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -285,6 +298,11 @@ void RendererSceneCull::_instance_unpair(Instance *p_A, Instance *p_B) {
|
|||||||
InstanceLightData *light = static_cast<InstanceLightData *>(B->base_data);
|
InstanceLightData *light = static_cast<InstanceLightData *>(B->base_data);
|
||||||
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
|
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
|
||||||
|
|
||||||
|
if (!(light->cull_mask & A->layer_mask)) {
|
||||||
|
// Early return if the object's layer mask doesn't match the light's cull mask.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
geom->lights.erase(B);
|
geom->lights.erase(B);
|
||||||
light->geometries.erase(A);
|
light->geometries.erase(A);
|
||||||
|
|
||||||
@ -339,6 +357,11 @@ void RendererSceneCull::_instance_unpair(Instance *p_A, Instance *p_B) {
|
|||||||
InstanceDecalData *decal = static_cast<InstanceDecalData *>(B->base_data);
|
InstanceDecalData *decal = static_cast<InstanceDecalData *>(B->base_data);
|
||||||
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
|
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
|
||||||
|
|
||||||
|
if (!(decal->cull_mask & A->layer_mask)) {
|
||||||
|
// Early return if the object's layer mask doesn't match the decal's cull mask.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
geom->decals.erase(B);
|
geom->decals.erase(B);
|
||||||
decal->geometries.erase(A);
|
decal->geometries.erase(A);
|
||||||
|
|
||||||
@ -383,7 +406,10 @@ void RendererSceneCull::_instance_unpair(Instance *p_A, Instance *p_B) {
|
|||||||
voxel_gi->lights.erase(A);
|
voxel_gi->lights.erase(A);
|
||||||
} else if (B->base_type == RS::INSTANCE_PARTICLES_COLLISION && A->base_type == RS::INSTANCE_PARTICLES) {
|
} else if (B->base_type == RS::INSTANCE_PARTICLES_COLLISION && A->base_type == RS::INSTANCE_PARTICLES) {
|
||||||
InstanceParticlesCollisionData *collision = static_cast<InstanceParticlesCollisionData *>(B->base_data);
|
InstanceParticlesCollisionData *collision = static_cast<InstanceParticlesCollisionData *>(B->base_data);
|
||||||
RSG::particles_storage->particles_remove_collision(A->base, collision->instance);
|
|
||||||
|
if ((collision->cull_mask & A->layer_mask)) {
|
||||||
|
RSG::particles_storage->particles_remove_collision(A->base, collision->instance);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -888,6 +914,14 @@ void RendererSceneCull::instance_set_layer_mask(RID p_instance, uint32_t p_mask)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Particles always need to be unpaired. Geometry may need to be unpaired, but only if lights or decals use pairing.
|
||||||
|
// Needs to happen before layer mask changes so we can avoid attempting to unpair something that was never paired.
|
||||||
|
if (instance->base_type == RS::INSTANCE_PARTICLES ||
|
||||||
|
(((geometry_instance_pair_mask & (1 << RS::INSTANCE_LIGHT)) || (geometry_instance_pair_mask & (1 << RS::INSTANCE_DECAL))) && ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK))) {
|
||||||
|
_unpair_instance(instance);
|
||||||
|
singleton->_instance_queue_update(instance, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
instance->layer_mask = p_mask;
|
instance->layer_mask = p_mask;
|
||||||
if (instance->scenario && instance->array_index >= 0) {
|
if (instance->scenario && instance->array_index >= 0) {
|
||||||
instance->scenario->instance_data[instance->array_index].layer_mask = p_mask;
|
instance->scenario->instance_data[instance->array_index].layer_mask = p_mask;
|
||||||
@ -1592,6 +1626,7 @@ void RendererSceneCull::_update_instance(Instance *p_instance) const {
|
|||||||
if (light->max_sdfgi_cascade != max_sdfgi_cascade) {
|
if (light->max_sdfgi_cascade != max_sdfgi_cascade) {
|
||||||
light->max_sdfgi_cascade = max_sdfgi_cascade; //should most likely make sdfgi dirty in scenario
|
light->max_sdfgi_cascade = max_sdfgi_cascade; //should most likely make sdfgi dirty in scenario
|
||||||
}
|
}
|
||||||
|
light->cull_mask = RSG::light_storage->light_get_cull_mask(p_instance->base);
|
||||||
} else if (p_instance->base_type == RS::INSTANCE_REFLECTION_PROBE) {
|
} else if (p_instance->base_type == RS::INSTANCE_REFLECTION_PROBE) {
|
||||||
InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(p_instance->base_data);
|
InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(p_instance->base_data);
|
||||||
|
|
||||||
@ -1605,6 +1640,7 @@ void RendererSceneCull::_update_instance(Instance *p_instance) const {
|
|||||||
InstanceDecalData *decal = static_cast<InstanceDecalData *>(p_instance->base_data);
|
InstanceDecalData *decal = static_cast<InstanceDecalData *>(p_instance->base_data);
|
||||||
|
|
||||||
RSG::texture_storage->decal_instance_set_transform(decal->instance, *instance_xform);
|
RSG::texture_storage->decal_instance_set_transform(decal->instance, *instance_xform);
|
||||||
|
decal->cull_mask = RSG::texture_storage->decal_get_cull_mask(p_instance->base);
|
||||||
} else if (p_instance->base_type == RS::INSTANCE_LIGHTMAP) {
|
} else if (p_instance->base_type == RS::INSTANCE_LIGHTMAP) {
|
||||||
InstanceLightmapData *lightmap = static_cast<InstanceLightmapData *>(p_instance->base_data);
|
InstanceLightmapData *lightmap = static_cast<InstanceLightmapData *>(p_instance->base_data);
|
||||||
|
|
||||||
@ -1623,6 +1659,7 @@ void RendererSceneCull::_update_instance(Instance *p_instance) const {
|
|||||||
heightfield_particle_colliders_update_list.insert(p_instance);
|
heightfield_particle_colliders_update_list.insert(p_instance);
|
||||||
}
|
}
|
||||||
RSG::particles_storage->particles_collision_instance_set_transform(collision->instance, *instance_xform);
|
RSG::particles_storage->particles_collision_instance_set_transform(collision->instance, *instance_xform);
|
||||||
|
collision->cull_mask = RSG::particles_storage->particles_collision_get_cull_mask(p_instance->base);
|
||||||
} else if (p_instance->base_type == RS::INSTANCE_FOG_VOLUME) {
|
} else if (p_instance->base_type == RS::INSTANCE_FOG_VOLUME) {
|
||||||
InstanceFogVolumeData *volume = static_cast<InstanceFogVolumeData *>(p_instance->base_data);
|
InstanceFogVolumeData *volume = static_cast<InstanceFogVolumeData *>(p_instance->base_data);
|
||||||
scene_render->fog_volume_instance_set_transform(volume->instance, *instance_xform);
|
scene_render->fog_volume_instance_set_transform(volume->instance, *instance_xform);
|
||||||
@ -1818,7 +1855,6 @@ void RendererSceneCull::_update_instance(Instance *p_instance) const {
|
|||||||
pair.pair_allocator = &pair_allocator;
|
pair.pair_allocator = &pair_allocator;
|
||||||
pair.pair_pass = pair_pass;
|
pair.pair_pass = pair_pass;
|
||||||
pair.pair_mask = 0;
|
pair.pair_mask = 0;
|
||||||
pair.cull_mask = 0xFFFFFFFF;
|
|
||||||
|
|
||||||
if ((1 << p_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) {
|
if ((1 << p_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) {
|
||||||
pair.pair_mask |= 1 << RS::INSTANCE_LIGHT;
|
pair.pair_mask |= 1 << RS::INSTANCE_LIGHT;
|
||||||
@ -1840,7 +1876,6 @@ void RendererSceneCull::_update_instance(Instance *p_instance) const {
|
|||||||
pair.pair_mask |= (1 << RS::INSTANCE_VOXEL_GI);
|
pair.pair_mask |= (1 << RS::INSTANCE_VOXEL_GI);
|
||||||
pair.bvh2 = &p_instance->scenario->indexers[Scenario::INDEXER_VOLUMES];
|
pair.bvh2 = &p_instance->scenario->indexers[Scenario::INDEXER_VOLUMES];
|
||||||
}
|
}
|
||||||
pair.cull_mask = RSG::light_storage->light_get_cull_mask(p_instance->base);
|
|
||||||
} else if (p_instance->base_type == RS::INSTANCE_LIGHTMAP) {
|
} else if (p_instance->base_type == RS::INSTANCE_LIGHTMAP) {
|
||||||
pair.pair_mask = RS::INSTANCE_GEOMETRY_MASK;
|
pair.pair_mask = RS::INSTANCE_GEOMETRY_MASK;
|
||||||
pair.bvh = &p_instance->scenario->indexers[Scenario::INDEXER_GEOMETRY];
|
pair.bvh = &p_instance->scenario->indexers[Scenario::INDEXER_GEOMETRY];
|
||||||
@ -1850,7 +1885,6 @@ void RendererSceneCull::_update_instance(Instance *p_instance) const {
|
|||||||
} else if (geometry_instance_pair_mask & (1 << RS::INSTANCE_DECAL) && (p_instance->base_type == RS::INSTANCE_DECAL)) {
|
} else if (geometry_instance_pair_mask & (1 << RS::INSTANCE_DECAL) && (p_instance->base_type == RS::INSTANCE_DECAL)) {
|
||||||
pair.pair_mask = RS::INSTANCE_GEOMETRY_MASK;
|
pair.pair_mask = RS::INSTANCE_GEOMETRY_MASK;
|
||||||
pair.bvh = &p_instance->scenario->indexers[Scenario::INDEXER_GEOMETRY];
|
pair.bvh = &p_instance->scenario->indexers[Scenario::INDEXER_GEOMETRY];
|
||||||
pair.cull_mask = RSG::texture_storage->decal_get_cull_mask(p_instance->base);
|
|
||||||
} else if (p_instance->base_type == RS::INSTANCE_PARTICLES_COLLISION) {
|
} else if (p_instance->base_type == RS::INSTANCE_PARTICLES_COLLISION) {
|
||||||
pair.pair_mask = (1 << RS::INSTANCE_PARTICLES);
|
pair.pair_mask = (1 << RS::INSTANCE_PARTICLES);
|
||||||
pair.bvh = &p_instance->scenario->indexers[Scenario::INDEXER_GEOMETRY];
|
pair.bvh = &p_instance->scenario->indexers[Scenario::INDEXER_GEOMETRY];
|
||||||
|
@ -508,7 +508,8 @@ public:
|
|||||||
case Dependency::DEPENDENCY_CHANGED_REFLECTION_PROBE: {
|
case Dependency::DEPENDENCY_CHANGED_REFLECTION_PROBE: {
|
||||||
singleton->_instance_queue_update(instance, true, true);
|
singleton->_instance_queue_update(instance, true, true);
|
||||||
} break;
|
} break;
|
||||||
case Dependency::DEPENDENCY_CHANGED_LIGHT_SOFT_SHADOW_AND_PROJECTOR: {
|
case Dependency::DEPENDENCY_CHANGED_LIGHT_SOFT_SHADOW_AND_PROJECTOR:
|
||||||
|
case Dependency::DEPENDENCY_CHANGED_CULL_MASK: {
|
||||||
//requires repairing
|
//requires repairing
|
||||||
if (instance->indexer_id.is_valid()) {
|
if (instance->indexer_id.is_valid()) {
|
||||||
singleton->_unpair_instance(instance);
|
singleton->_unpair_instance(instance);
|
||||||
@ -655,6 +656,7 @@ public:
|
|||||||
struct InstanceDecalData : public InstanceBaseData {
|
struct InstanceDecalData : public InstanceBaseData {
|
||||||
Instance *owner = nullptr;
|
Instance *owner = nullptr;
|
||||||
RID instance;
|
RID instance;
|
||||||
|
uint32_t cull_mask = 0xFFFFFFFF;
|
||||||
|
|
||||||
HashSet<Instance *> geometries;
|
HashSet<Instance *> geometries;
|
||||||
|
|
||||||
@ -666,6 +668,7 @@ public:
|
|||||||
|
|
||||||
struct InstanceParticlesCollisionData : public InstanceBaseData {
|
struct InstanceParticlesCollisionData : public InstanceBaseData {
|
||||||
RID instance;
|
RID instance;
|
||||||
|
uint32_t cull_mask = 0xFFFFFFFF;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct InstanceFogVolumeData : public InstanceBaseData {
|
struct InstanceFogVolumeData : public InstanceBaseData {
|
||||||
@ -699,6 +702,7 @@ public:
|
|||||||
|
|
||||||
RS::LightBakeMode bake_mode;
|
RS::LightBakeMode bake_mode;
|
||||||
uint32_t max_sdfgi_cascade = 2;
|
uint32_t max_sdfgi_cascade = 2;
|
||||||
|
uint32_t cull_mask = 0xFFFFFFFF;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Instead of a single dirty flag, we maintain a count
|
// Instead of a single dirty flag, we maintain a count
|
||||||
@ -817,12 +821,11 @@ public:
|
|||||||
DynamicBVH *bvh2 = nullptr; //some may need to cull in two
|
DynamicBVH *bvh2 = nullptr; //some may need to cull in two
|
||||||
uint32_t pair_mask;
|
uint32_t pair_mask;
|
||||||
uint64_t pair_pass;
|
uint64_t pair_pass;
|
||||||
uint32_t cull_mask = 0xFFFFFFFF; // Needed for decals and lights in the mobile and compatibility renderers.
|
|
||||||
|
|
||||||
_FORCE_INLINE_ bool operator()(void *p_data) {
|
_FORCE_INLINE_ bool operator()(void *p_data) {
|
||||||
Instance *p_instance = (Instance *)p_data;
|
Instance *p_instance = (Instance *)p_data;
|
||||||
|
|
||||||
if (instance != p_instance && instance->transformed_aabb.intersects(p_instance->transformed_aabb) && (pair_mask & (1 << p_instance->base_type)) && (cull_mask & p_instance->layer_mask)) {
|
if (instance != p_instance && instance->transformed_aabb.intersects(p_instance->transformed_aabb) && (pair_mask & (1 << p_instance->base_type))) {
|
||||||
//test is more coarse in indexer
|
//test is more coarse in indexer
|
||||||
p_instance->pair_check = pair_pass;
|
p_instance->pair_check = pair_pass;
|
||||||
InstancePair *pair = pair_allocator->alloc();
|
InstancePair *pair = pair_allocator->alloc();
|
||||||
|
@ -121,6 +121,7 @@ public:
|
|||||||
virtual bool particles_collision_is_heightfield(RID p_particles_collision) const = 0;
|
virtual bool particles_collision_is_heightfield(RID p_particles_collision) const = 0;
|
||||||
virtual uint32_t particles_collision_get_height_field_mask(RID p_particles_collision) const = 0;
|
virtual uint32_t particles_collision_get_height_field_mask(RID p_particles_collision) const = 0;
|
||||||
virtual void particles_collision_set_height_field_mask(RID p_particles_collision, uint32_t p_heightfield_mask) = 0;
|
virtual void particles_collision_set_height_field_mask(RID p_particles_collision, uint32_t p_heightfield_mask) = 0;
|
||||||
|
virtual uint32_t particles_collision_get_cull_mask(RID p_particles_collision) const = 0;
|
||||||
|
|
||||||
//used from 2D and 3D
|
//used from 2D and 3D
|
||||||
virtual RID particles_collision_instance_create(RID p_collision) = 0;
|
virtual RID particles_collision_instance_create(RID p_collision) = 0;
|
||||||
|
@ -50,6 +50,7 @@ public:
|
|||||||
DEPENDENCY_CHANGED_LIGHT,
|
DEPENDENCY_CHANGED_LIGHT,
|
||||||
DEPENDENCY_CHANGED_LIGHT_SOFT_SHADOW_AND_PROJECTOR,
|
DEPENDENCY_CHANGED_LIGHT_SOFT_SHADOW_AND_PROJECTOR,
|
||||||
DEPENDENCY_CHANGED_REFLECTION_PROBE,
|
DEPENDENCY_CHANGED_REFLECTION_PROBE,
|
||||||
|
DEPENDENCY_CHANGED_CULL_MASK,
|
||||||
};
|
};
|
||||||
|
|
||||||
void changed_notify(DependencyChangedNotification p_notification);
|
void changed_notify(DependencyChangedNotification p_notification);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user