visual instance layers are regarded during shadow culling
Partially cherry-picked from 16517ecb
. Todos:
- setting Camera cull_mask should mark affected shadows dirty somehow
This commit is contained in:
parent
b6e06038f8
commit
041b64ea7e
|
@ -833,6 +833,10 @@ void RendererSceneCull::instance_set_layer_mask(RID p_instance, uint32_t p_mask)
|
||||||
Instance *instance = instance_owner.get_or_null(p_instance);
|
Instance *instance = instance_owner.get_or_null(p_instance);
|
||||||
ERR_FAIL_COND(!instance);
|
ERR_FAIL_COND(!instance);
|
||||||
|
|
||||||
|
if (instance->layer_mask == p_mask) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
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;
|
||||||
|
@ -842,6 +846,13 @@ void RendererSceneCull::instance_set_layer_mask(RID p_instance, uint32_t p_mask)
|
||||||
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
|
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
|
||||||
ERR_FAIL_NULL(geom->geometry_instance);
|
ERR_FAIL_NULL(geom->geometry_instance);
|
||||||
geom->geometry_instance->set_layer_mask(p_mask);
|
geom->geometry_instance->set_layer_mask(p_mask);
|
||||||
|
|
||||||
|
if (geom->can_cast_shadows) {
|
||||||
|
for (HashSet<RendererSceneCull::Instance *>::Iterator I = geom->lights.begin(); I != geom->lights.end(); ++I) {
|
||||||
|
InstanceLightData *light = static_cast<InstanceLightData *>((*I)->base_data);
|
||||||
|
light->shadow_dirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2253,7 +2264,7 @@ void RendererSceneCull::_light_instance_setup_directional_shadow(int p_shadow_in
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, const Transform3D p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_shadow_atlas, Scenario *p_scenario, float p_screen_mesh_lod_threshold) {
|
bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, const Transform3D p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_shadow_atlas, Scenario *p_scenario, float p_screen_mesh_lod_threshold, uint32_t p_visible_layers) {
|
||||||
InstanceLightData *light = static_cast<InstanceLightData *>(p_instance->base_data);
|
InstanceLightData *light = static_cast<InstanceLightData *>(p_instance->base_data);
|
||||||
|
|
||||||
Transform3D light_transform = p_instance->transform;
|
Transform3D light_transform = p_instance->transform;
|
||||||
|
@ -2309,7 +2320,7 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons
|
||||||
|
|
||||||
for (int j = 0; j < (int)instance_shadow_cull_result.size(); j++) {
|
for (int j = 0; j < (int)instance_shadow_cull_result.size(); j++) {
|
||||||
Instance *instance = instance_shadow_cull_result[j];
|
Instance *instance = instance_shadow_cull_result[j];
|
||||||
if (!instance->visible || !((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) || !static_cast<InstanceGeometryData *>(instance->base_data)->can_cast_shadows) {
|
if (!instance->visible || !((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) || !static_cast<InstanceGeometryData *>(instance->base_data)->can_cast_shadows || !(p_visible_layers & instance->layer_mask)) {
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
if (static_cast<InstanceGeometryData *>(instance->base_data)->material_is_animated) {
|
if (static_cast<InstanceGeometryData *>(instance->base_data)->material_is_animated) {
|
||||||
|
@ -2387,7 +2398,7 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons
|
||||||
|
|
||||||
for (int j = 0; j < (int)instance_shadow_cull_result.size(); j++) {
|
for (int j = 0; j < (int)instance_shadow_cull_result.size(); j++) {
|
||||||
Instance *instance = instance_shadow_cull_result[j];
|
Instance *instance = instance_shadow_cull_result[j];
|
||||||
if (!instance->visible || !((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) || !static_cast<InstanceGeometryData *>(instance->base_data)->can_cast_shadows) {
|
if (!instance->visible || !((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) || !static_cast<InstanceGeometryData *>(instance->base_data)->can_cast_shadows || !(p_visible_layers & instance->layer_mask)) {
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
if (static_cast<InstanceGeometryData *>(instance->base_data)->material_is_animated) {
|
if (static_cast<InstanceGeometryData *>(instance->base_data)->material_is_animated) {
|
||||||
|
@ -2450,7 +2461,7 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons
|
||||||
|
|
||||||
for (int j = 0; j < (int)instance_shadow_cull_result.size(); j++) {
|
for (int j = 0; j < (int)instance_shadow_cull_result.size(); j++) {
|
||||||
Instance *instance = instance_shadow_cull_result[j];
|
Instance *instance = instance_shadow_cull_result[j];
|
||||||
if (!instance->visible || !((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) || !static_cast<InstanceGeometryData *>(instance->base_data)->can_cast_shadows) {
|
if (!instance->visible || !((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) || !static_cast<InstanceGeometryData *>(instance->base_data)->can_cast_shadows || !(p_visible_layers & instance->layer_mask)) {
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
if (static_cast<InstanceGeometryData *>(instance->base_data)->material_is_animated) {
|
if (static_cast<InstanceGeometryData *>(instance->base_data)->material_is_animated) {
|
||||||
|
@ -2891,7 +2902,7 @@ void RendererSceneCull::_scene_cull(CullData &cull_data, InstanceCullResult &cul
|
||||||
if (IN_FRUSTUM(cull_data.cull->shadows[j].cascades[k].frustum) && VIS_CHECK) {
|
if (IN_FRUSTUM(cull_data.cull->shadows[j].cascades[k].frustum) && VIS_CHECK) {
|
||||||
uint32_t base_type = idata.flags & InstanceData::FLAG_BASE_TYPE_MASK;
|
uint32_t base_type = idata.flags & InstanceData::FLAG_BASE_TYPE_MASK;
|
||||||
|
|
||||||
if (((1 << base_type) & RS::INSTANCE_GEOMETRY_MASK) && idata.flags & InstanceData::FLAG_CAST_SHADOWS) {
|
if (((1 << base_type) & RS::INSTANCE_GEOMETRY_MASK) && idata.flags & InstanceData::FLAG_CAST_SHADOWS && LAYER_CHECK) {
|
||||||
cull_result.directional_shadows[j].cascade_geometry_instances[k].push_back(idata.instance_geometry);
|
cull_result.directional_shadows[j].cascade_geometry_instances[k].push_back(idata.instance_geometry);
|
||||||
mesh_visible = true;
|
mesh_visible = true;
|
||||||
}
|
}
|
||||||
|
@ -3218,7 +3229,7 @@ void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_c
|
||||||
if (redraw && max_shadows_used < MAX_UPDATE_SHADOWS) {
|
if (redraw && max_shadows_used < MAX_UPDATE_SHADOWS) {
|
||||||
//must redraw!
|
//must redraw!
|
||||||
RENDER_TIMESTAMP("> Render Light3D " + itos(i));
|
RENDER_TIMESTAMP("> Render Light3D " + itos(i));
|
||||||
light->shadow_dirty = _light_instance_update_shadow(ins, p_camera_data->main_transform, p_camera_data->main_projection, p_camera_data->is_orthogonal, p_camera_data->vaspect, p_shadow_atlas, scenario, p_screen_mesh_lod_threshold);
|
light->shadow_dirty = _light_instance_update_shadow(ins, p_camera_data->main_transform, p_camera_data->main_projection, p_camera_data->is_orthogonal, p_camera_data->vaspect, p_shadow_atlas, scenario, p_screen_mesh_lod_threshold, p_visible_layers);
|
||||||
RENDER_TIMESTAMP("< Render Light3D " + itos(i));
|
RENDER_TIMESTAMP("< Render Light3D " + itos(i));
|
||||||
} else {
|
} else {
|
||||||
light->shadow_dirty = redraw;
|
light->shadow_dirty = redraw;
|
||||||
|
|
|
@ -988,7 +988,7 @@ public:
|
||||||
|
|
||||||
void _light_instance_setup_directional_shadow(int p_shadow_index, Instance *p_instance, const Transform3D p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect);
|
void _light_instance_setup_directional_shadow(int p_shadow_index, Instance *p_instance, const Transform3D p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect);
|
||||||
|
|
||||||
_FORCE_INLINE_ bool _light_instance_update_shadow(Instance *p_instance, const Transform3D p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_shadow_atlas, Scenario *p_scenario, float p_scren_mesh_lod_threshold);
|
_FORCE_INLINE_ bool _light_instance_update_shadow(Instance *p_instance, const Transform3D p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_shadow_atlas, Scenario *p_scenario, float p_scren_mesh_lod_threshold, uint32_t p_visible_layers = 0xFFFFFF);
|
||||||
|
|
||||||
RID _render_get_environment(RID p_camera, RID p_scenario);
|
RID _render_get_environment(RID p_camera, RID p_scenario);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue