diff options
Diffstat (limited to 'servers/visual/visual_server_scene.cpp')
-rw-r--r-- | servers/visual/visual_server_scene.cpp | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/servers/visual/visual_server_scene.cpp b/servers/visual/visual_server_scene.cpp index b905b230dc..352daa9655 100644 --- a/servers/visual/visual_server_scene.cpp +++ b/servers/visual/visual_server_scene.cpp @@ -1347,6 +1347,8 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons bool overlap = VSG::storage->light_directional_get_blend_splits(p_instance->base); + float first_radius = 0.0; + for (int i = 0; i < splits; i++) { // setup a camera matrix for that range! @@ -1373,9 +1375,11 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons // obtain the light frustm ranges (given endpoints) - Vector3 x_vec = p_instance->transform.basis.get_axis(Vector3::AXIS_X).normalized(); - Vector3 y_vec = p_instance->transform.basis.get_axis(Vector3::AXIS_Y).normalized(); - Vector3 z_vec = p_instance->transform.basis.get_axis(Vector3::AXIS_Z).normalized(); + Transform transform = p_instance->transform.orthonormalized(); //discard scale and stabilize light + + Vector3 x_vec = transform.basis.get_axis(Vector3::AXIS_X).normalized(); + Vector3 y_vec = transform.basis.get_axis(Vector3::AXIS_Y).normalized(); + Vector3 z_vec = transform.basis.get_axis(Vector3::AXIS_Z).normalized(); //z_vec points agsint the camera, like in default opengl float x_min, x_max; @@ -1386,7 +1390,10 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons float y_min_cam, y_max_cam; float z_min_cam, z_max_cam; + float bias_scale = 1.0; + //used for culling + for (int j = 0; j < 8; j++) { float d_x = x_vec.dot(endpoints[j]); @@ -1435,6 +1442,12 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons radius *= texture_size / (texture_size - 2.0); //add a texel by each side, so stepified texture will always fit + if (i == 0) { + first_radius = radius; + } else { + bias_scale = radius / first_radius; + } + x_max_cam = x_vec.dot(center) + radius; x_min_cam = x_vec.dot(center) - radius; y_max_cam = y_vec.dot(center) + radius; @@ -1493,10 +1506,10 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons ortho_camera.set_orthogonal(-half_x, half_x, -half_y, half_y, 0, (z_max - z_min_cam)); Transform ortho_transform; - ortho_transform.basis = p_instance->transform.basis; + ortho_transform.basis = transform.basis; ortho_transform.origin = x_vec * (x_min_cam + half_x) + y_vec * (y_min_cam + half_y) + z_vec * z_max; - VSG::scene_render->light_instance_set_shadow_transform(light->instance, ortho_camera, ortho_transform, 0, distances[i + 1], i); + VSG::scene_render->light_instance_set_shadow_transform(light->instance, ortho_camera, ortho_transform, 0, distances[i + 1], i, bias_scale); } VSG::scene_render->render_shadow(light->instance, p_shadow_atlas, i, (RasterizerScene::InstanceBase **)instance_shadow_cull_result, cull_count); |