From 8c0ae744dd5da540a71d925397e41aa5bf1e34b0 Mon Sep 17 00:00:00 2001 From: korenkonder Date: Thu, 4 Jan 2024 00:44:27 +0300 Subject: [PATCH] Better Autofocus DoF code --- src/CRE/auth_3d.cpp | 12 +- src/CRE/pv_param.cpp | 118 +++++-------------- src/CRE/render.cpp | 32 +++++ src/CRE/render.hpp | 6 + src/CRE/renderer/dof.cpp | 13 +- src/CRE/renderer/dof.hpp | 6 +- src/KKdLib/interpolation.cpp | 20 ++++ src/ReDIVA/classes/graphics/post_process.cpp | 7 +- src/ReDIVA/pv_game/pv_game.cpp | 4 +- src/ReDIVA/x_pv_game.cpp | 46 +++++--- src/ReDIVA/x_pv_game.hpp | 3 + 11 files changed, 136 insertions(+), 131 deletions(-) diff --git a/src/CRE/auth_3d.cpp b/src/CRE/auth_3d.cpp index f454c198..a688e898 100644 --- a/src/CRE/auth_3d.cpp +++ b/src/CRE/auth_3d.cpp @@ -4242,7 +4242,7 @@ static void auth_3d_dof_restore_prev_value(auth_3d_dof* d, render_context* rctx) if (!d->has_dof) return; - dof_pv_set(0); + rctx->render.set_dof_enable(false); } static void auth_3d_dof_set(auth_3d_dof* d, render_context* rctx) { @@ -4254,13 +4254,9 @@ static void auth_3d_dof_set(auth_3d_dof* d, render_context* rctx) { float_t focus = vec3::distance(d->model_transform.translation_value, view_point); - dof_pv pv; - pv.enable = fabsf(d->model_transform.rotation_value.z) > 0.000001f; - pv.f2.focus = focus; - pv.f2.focus_range = d->model_transform.scale_value.x; - pv.f2.fuzzing_range = d->model_transform.rotation_value.x; - pv.f2.ratio = d->model_transform.rotation_value.y; - dof_pv_set(&pv); + rctx->render.set_dof_enable(fabsf(d->model_transform.translation_value.x) > 0.000001f); + rctx->render.set_dof_data(focus, d->model_transform.scale_value.x, + d->model_transform.rotation_value.x, d->model_transform.rotation_value.y); } static void auth_3d_dof_store(auth_3d* auth, auth_3d_dof* d, auth_3d_dof_file* df) { diff --git a/src/CRE/pv_param.cpp b/src/CRE/pv_param.cpp index b1645cde..caea4103 100644 --- a/src/CRE/pv_param.cpp +++ b/src/CRE/pv_param.cpp @@ -1097,29 +1097,25 @@ namespace pv_param_task { float_t& focus, float_t& focus_range, float_t& fuzzing_range, float_t& ratio) { float_t v5 = tanf(fov * DEG_TO_RAD_FLOAT * 0.5f); float_t v6 = distance * 1000.0f; - float_t v7 = 36.0f / (v5 * 2.0f); - v7 *= v7; + float_t v7 = (36.0f / (v5 * 2.0f)) * (36.0f / (v5 * 2.0f)); float_t _focus_range = (v6 * 0.36608f * v6) / (v7 - v6 * 0.36608f) * 0.001f; if (_focus_range >= 0.0f) { - float_t _ratio = (v7 * 20000.0f) / (v6 * 220000.0f + v6 * 11.0f * v6) * 3.0048077f; - float_t range; - if (_ratio >= 1.0f) { + float_t _ratio; + float_t v11 = (v7 * 20000.0f) / (v6 * 220000.0f + v6 * 11.0f * v6); + if (v11 >= 0.3328f) { range = (v6 * 3.6608f * v6) / (v7 - v6 * 3.6608f) * 0.001f; - if (range < 0.2f) - range = 0.2f; _ratio = 1.0f; } - else + else { range = 20.0f; + _ratio = v11 * 3.0048077f; + } - if (_focus_range < 0.2f) - _focus_range = 0.2f; - - float_t _fuzzing_range = range - _focus_range; - if (_fuzzing_range < 0.01f) - _fuzzing_range = 0.01f; + range = max_def(range, 0.2f); + _focus_range = max_def(_focus_range, 0.2f); + float_t _fuzzing_range = max_def(range - _focus_range, 0.01f); enable = true; focus = distance; @@ -1127,35 +1123,18 @@ namespace pv_param_task { fuzzing_range = _fuzzing_range; ratio = _ratio; } - else { + else enable = false; - focus = 0.0f; - focus_range = 0.0f; - fuzzing_range = 0.0f; - ratio = 0.0f; - } } -#define DOF_FIX 1 - void PostProcessCtrlDof::Set() { - float_t focus; - float_t focus_range; - float_t fuzzing_range; - float_t ratio; -#if DOF_FIX - float_t auto_focus; - float_t auto_focus_range; -#endif - bool enable = true; bool autofocus = data.data.chara_id != -1; -#if DOF_FIX - if (true) { -#else if (autofocus) { -#endif + if (!rctx_ptr->render.get_dof_update()) + return; + vec3 trans = 0.0f; - rob_chara* rob_chr = rob_chara_array_get(autofocus ? data.data.chara_id : 0); + rob_chara* rob_chr = rob_chara_array_get(data.data.chara_id); if (rob_chr) { motion_blend_mot* mot = rob_chr->bone_data->motion_loaded.front(); ::bone_data* bone_data = mot->bone_data.bones.data(); @@ -1165,32 +1144,22 @@ namespace pv_param_task { camera* cam = rctx_ptr->camera; + bool enable = true; vec3 view_point; cam->get_view_point(view_point); - float_t fov = (float_t)cam->get_fov(); - - float_t distance = vec3::distance(trans, view_point); - - get_autofocus_data(distance, fov, enable, focus, focus_range, fuzzing_range, ratio); - - if (autofocus) { - data.data.focus = focus; - data.data.focus_range = focus_range; - data.data.fuzzing_range = fuzzing_range; - data.data.ratio = ratio; - } - -#if DOF_FIX - auto_focus = focus; - auto_focus_range = focus_range; - } -#else + get_autofocus_data(vec3::distance(trans, view_point), cam->get_fov(), + enable, data.data.focus, data.data.focus_range, + data.data.fuzzing_range, data.data.ratio); + rctx_ptr->render.set_dof_enable(enable); } else if (frame < 0.0f) return; -#endif - if (fabsf(duration) <= 0.000001f || autofocus && duration < 0.0f) { + float_t focus; + float_t focus_range; + float_t fuzzing_range; + float_t ratio; + if (fabsf(duration) <= 0.000001f || autofocus) { focus = data.data.focus; focus_range = data.data.focus_range; fuzzing_range = data.data.fuzzing_range; @@ -1210,31 +1179,7 @@ namespace pv_param_task { ratio = lerp_def(data.data_prev.ratio, data.data.ratio, t); } -#if DOF_FIX - bool ret = true; - if (ratio > 0.0f) { - if (focus == 0.0f && auto_focus >= 0.0f) { - focus = auto_focus; - ret = false; - } - if (focus_range == 0.0f && auto_focus_range >= 0.0f) { - focus_range = auto_focus_range; - ret = false; - } - } - - if (!autofocus && ret && frame < 0.0f) - return; -#endif - - dof_pv pv; - dof_pv_get(&pv); - pv.enable = enable; - pv.f2.focus = focus; - pv.f2.focus_range = focus_range; - pv.f2.fuzzing_range = fuzzing_range; - pv.f2.ratio = ratio; - dof_pv_set(&pv); + rctx_ptr->render.set_dof_data(focus, focus_range, fuzzing_range, ratio); frame += get_delta_frame(); if (frame > duration) { @@ -1249,14 +1194,9 @@ namespace pv_param_task { this->duration = duration; data.data = *dof; - if (fabsf(duration) > 0.000001f) { - dof_pv pv; - dof_pv_get(&pv); - data.data_prev.focus = pv.f2.focus; - data.data_prev.focus_range = pv.f2.focus_range; - data.data_prev.fuzzing_range = pv.f2.fuzzing_range; - data.data_prev.ratio = pv.f2.ratio; - } + if (fabsf(duration) > 0.000001f) + rctx_ptr->render.get_dof_data(data.data_prev.focus, + data.data_prev.focus_range, data.data_prev.fuzzing_range, data.data_prev.ratio); else data.data_prev = data.data; } diff --git a/src/CRE/render.cpp b/src/CRE/render.cpp index f203f8b0..b9dd7f8c 100644 --- a/src/CRE/render.cpp +++ b/src/CRE/render.cpp @@ -17,6 +17,8 @@ extern bool task_stage_is_modern; extern render_context* rctx_ptr; +extern dof_pv dof_pv_data; + #define MLAA_MAX_EDGE_DETECTION_LEN (3) #define MLAA_GRID_SIDE_LEN (2 * MLAA_MAX_EDGE_DETECTION_LEN + 1) #define MLAA_SIDE_LEN (5 * MLAA_GRID_SIDE_LEN) @@ -736,6 +738,21 @@ namespace rndr { return cam_blur; } + void Render::get_dof_data(float_t& focus, float_t& focus_range, float_t& fuzzing_range, float_t& ratio) { + focus = dof_pv_data.f2.focus; + focus_range = dof_pv_data.f2.focus_range; + fuzzing_range = dof_pv_data.f2.fuzzing_range; + ratio = dof_pv_data.f2.ratio; + } + + bool Render::get_dof_enable() { + return dof_pv_data.enable; + } + + bool Render::get_dof_update() { + return dof_pv_data.update; + } + float_t Render::get_exposure() { return exposure; } @@ -1138,6 +1155,21 @@ namespace rndr { update = 1; } + void Render::set_dof_data(float_t focus, float_t focus_range, float_t fuzzing_range, float_t ratio) { + dof_pv_data.f2.focus = focus; + dof_pv_data.f2.focus_range = focus_range; + dof_pv_data.f2.ratio = ratio; + dof_pv_data.f2.fuzzing_range = fuzzing_range; + } + + void Render::set_dof_enable(bool value) { + dof_pv_data.enable = value; + } + + void Render::set_dof_update(bool value) { + dof_pv_data.update = value; + } + void Render::set_exposure(float_t value) { exposure = value; update = 1; diff --git a/src/CRE/render.hpp b/src/CRE/render.hpp index 2040af14..9bad52b8 100644 --- a/src/CRE/render.hpp +++ b/src/CRE/render.hpp @@ -197,6 +197,9 @@ namespace rndr { void free(); bool get_auto_exposure(); int32_t get_cam_blur(); + void get_dof_data(float_t& focus, float_t& focus_range, float_t& fuzzing_range, float_t& ratio); + bool get_dof_enable(); + bool get_dof_update(); float_t get_exposure(); float_t get_exposure_rate(); float_t get_gamma(); @@ -229,6 +232,9 @@ namespace rndr { void resize(int32_t width, int32_t height); void set_auto_exposure(bool value); void set_cam_blur(int32_t value); + void set_dof_data(float_t focus, float_t focus_range, float_t fuzzing_range, float_t ratio); + void set_dof_enable(bool value); + void set_dof_update(bool value); void set_exposure(float_t value); void set_exposure_rate(float_t value); void set_gamma(float_t value); diff --git a/src/CRE/renderer/dof.cpp b/src/CRE/renderer/dof.cpp index 7b91cfc1..0dd9af31 100644 --- a/src/CRE/renderer/dof.cpp +++ b/src/CRE/renderer/dof.cpp @@ -30,6 +30,7 @@ static const dof_debug dof_debug_default = { }; static const dof_pv dof_pv_default = { + false, false, { 10.0f, @@ -422,15 +423,3 @@ void dof_debug_set(dof_debug* debug) { else dof_debug_data = dof_debug_default; } - -void dof_pv_get(dof_pv* pv) { - if (pv) - *pv = dof_pv_data; -} - -void dof_pv_set(dof_pv* pv) { - if (pv) - dof_pv_data = *pv; - else - dof_pv_data = dof_pv_default; -} diff --git a/src/CRE/renderer/dof.hpp b/src/CRE/renderer/dof.hpp index b10774c7..1263c5fc 100644 --- a/src/CRE/renderer/dof.hpp +++ b/src/CRE/renderer/dof.hpp @@ -35,6 +35,7 @@ struct dof_debug { struct dof_pv { bool enable; + bool update; dof_f2 f2; }; @@ -80,10 +81,5 @@ namespace renderer { }; } -extern dof_debug dof_debug_data; -extern dof_pv dof_pv_data; - extern void dof_debug_get(dof_debug* debug); extern void dof_debug_set(dof_debug* debug = 0); -extern void dof_pv_get(dof_pv* pv); -extern void dof_pv_set(dof_pv* pv = 0); diff --git a/src/KKdLib/interpolation.cpp b/src/KKdLib/interpolation.cpp index 5edef84f..dfb89158 100644 --- a/src/KKdLib/interpolation.cpp +++ b/src/KKdLib/interpolation.cpp @@ -254,6 +254,26 @@ int32_t interpolate_chs_reverse_sequence( values.push_back({ (float_t)(int64_t)(count - 1), arr[count - 1], t2_old, 0.0f }); + if (values.size() > 2) { + kft3* keys = values.data(); + size_t length = values.size(); + for (size_t i = 0; i < length - 3; i++) + if (*(uint32_t*)&keys[i + 0].value == *(uint32_t*)&keys[i + 1].value + && *(uint32_t*)&keys[i + 1].value == *(uint32_t*)&keys[i + 2].value + && *(uint32_t*)&keys[i + 0].tangent2 == 0 + && *(uint32_t*)&keys[i + 1].tangent1 == 0 + && *(uint32_t*)&keys[i + 1].tangent2 == 0 + && *(uint32_t*)&keys[i + 2].tangent1 == 0) { + keys[i + 1].frame = keys[i + 2].frame; + keys[i + 1].tangent2 = keys[i + 2].tangent2; + values.erase(values.begin() + (i + 2)); + keys = values.data(); + length = values.size(); + if (length < 3) + break; + } + } + kft3* keys = values.data(); size_t length = values.size(); for (size_t i = 0; i < count; i++) { diff --git a/src/ReDIVA/classes/graphics/post_process.cpp b/src/ReDIVA/classes/graphics/post_process.cpp index 9ca4b0d7..2b36a351 100644 --- a/src/ReDIVA/classes/graphics/post_process.cpp +++ b/src/ReDIVA/classes/graphics/post_process.cpp @@ -4,6 +4,7 @@ */ #include "post_process.hpp" +#include "../../../CRE/render_context.hpp" #include "../../../CRE/stage.hpp" #include "../../imgui_helper.hpp" @@ -171,6 +172,8 @@ void graphics_post_process_imgui(class_data* data) { ImGui::SetDefaultColumnSpace(); if (ImGui::TreeNodeEx("DOF", ImGuiTreeNodeFlags_DefaultOpen)) { + dof_debug dof_debug_data; + dof_debug_get(&dof_debug_data); bool use_ui_params = dof_debug_data.flags & DOF_DEBUG_USE_UI_PARAMS; bool phys = use_ui_params && dof_debug_data.flags & DOF_DEBUG_ENABLE_PHYS_DOF; bool f2 = use_ui_params && ~dof_debug_data.flags & DOF_DEBUG_ENABLE_PHYS_DOF; @@ -240,6 +243,7 @@ void graphics_post_process_imgui(class_data* data) { ImGui::PopItemFlag(); ImGui::PopStyleVar(); } + dof_debug_set(&dof_debug_data); ImGui::SetDefaultColumnSpace(); ImGui::TreePop(); } @@ -249,7 +253,8 @@ void graphics_post_process_imgui(class_data* data) { if (stg) light_param_data_storage_data_set_stage(stg->index); dof_debug_set(); - dof_pv_set(); + extern render_context* rctx_ptr; + rctx_ptr->render.set_dof_enable(false); } data->imgui_focus |= ImGui::IsWindowFocused(); diff --git a/src/ReDIVA/pv_game/pv_game.cpp b/src/ReDIVA/pv_game/pv_game.cpp index 9ea72cab..f5181fbf 100644 --- a/src/ReDIVA/pv_game/pv_game.cpp +++ b/src/ReDIVA/pv_game/pv_game.cpp @@ -4380,6 +4380,8 @@ bool pv_game::set_pv_param_post_process_color_correction_data(bool set, int32_t } bool pv_game::set_pv_param_post_process_dof_data(bool set, int32_t id, float_t duration) { + rctx_ptr->render.set_dof_enable(set); + pv_param::dof& dof = pv_param::post_process_data_get_dof_data(id); if (set) pv_param_task::post_process_task_set_dof_data(dof, duration); @@ -4674,7 +4676,7 @@ bool pv_game::unload() { rndr::Render& rend = rctx_ptr->render; rend.reset_saturate_coeff(0, true); - dof_pv_set(); + rend.set_dof_enable(false); rend.reset_scene_fade(0); rend.set_taa(1); diff --git a/src/ReDIVA/x_pv_game.cpp b/src/ReDIVA/x_pv_game.cpp index 2445ef3c..2e31641b 100644 --- a/src/ReDIVA/x_pv_game.cpp +++ b/src/ReDIVA/x_pv_game.cpp @@ -2950,27 +2950,21 @@ bool x_pv_game_pv_data::dsc_ctrl(float_t delta_time, int64_t curr_time, int32_t id = data[0]; float_t duration = (float_t)data[1]; - pv_param_task::post_process_task_set_bloom_data( - pv_param::post_process_data_get_bloom_data(id), duration); + set_pv_param_post_process_bloom_data(true, id, duration); } break; case DSC_X_COLOR_CORRECTION: { int32_t enable = data[0]; int32_t id = data[1]; float_t duration = (float_t)data[2]; - if (enable == 1) - pv_param_task::post_process_task_set_color_correction_data( - pv_param::post_process_data_get_color_correction_data(id), duration); + set_pv_param_post_process_color_correction_data(enable == 1, id, duration); } break; case DSC_X_DOF: { int32_t enable = data[0]; int32_t id = data[1]; float_t duration = (float_t)data[2]; - dof_pv_data.enable = enable == 1; - if (enable == 1) - pv_param_task::post_process_task_set_dof_data( - pv_param::post_process_data_get_dof_data(id), duration); + set_pv_param_post_process_dof_data(enable == 1, id, duration); } break; case DSC_X_CHARA_ALPHA: { chara_id = data[0]; @@ -3606,6 +3600,30 @@ void x_pv_game_pv_data::reset() { dsc_time = -1; } +bool x_pv_game_pv_data::set_pv_param_post_process_bloom_data(bool set, int32_t id, float_t duration) { + pv_param::bloom& bloom = pv_param::post_process_data_get_bloom_data(id); + if (set) + pv_param_task::post_process_task_set_bloom_data(bloom, duration); + return true; +} + +bool x_pv_game_pv_data::set_pv_param_post_process_color_correction_data(bool set, int32_t id, float_t duration) { + pv_param::color_correction& color_correction = pv_param::post_process_data_get_color_correction_data(id); + if (set) + pv_param_task::post_process_task_set_color_correction_data(color_correction, duration); + return true; +} + +bool x_pv_game_pv_data::set_pv_param_post_process_dof_data(bool set, int32_t id, float_t duration) { + rctx_ptr->render.set_dof_enable(set); + rctx_ptr->render.set_dof_update(set); + + pv_param::dof& dof = pv_param::post_process_data_get_dof_data(id); + if (set) + pv_param_task::post_process_task_set_dof_data(dof, duration); + return true; +} + void x_pv_game_pv_data::set_motion_max_frame(int32_t chara_id, int32_t motion_index, int64_t time) { if (chara_id < 0 || chara_id >= ROB_CHARA_COUNT || motion_index < 0) return; @@ -6577,9 +6595,6 @@ bool x_pv_game::ctrl() { a3da_key_rev(a.dof.model_transform.translation.x, dof_cam_data.position_x); a3da_key_rev(a.dof.model_transform.translation.y, dof_cam_data.position_y); a3da_key_rev(a.dof.model_transform.translation.z, dof_cam_data.position_z); - a.dof.model_transform.translation.x.raw_data = true; - a.dof.model_transform.translation.y.raw_data = true; - a.dof.model_transform.translation.z.raw_data = true; a3da_key_rev(a.dof.model_transform.scale.x, dof_cam_data.focus_range); a3da_key_rev(a.dof.model_transform.rotation.x, dof_cam_data.fuzzing_range); a3da_key_rev(a.dof.model_transform.rotation.y, dof_cam_data.ratio); @@ -6654,8 +6669,8 @@ void x_pv_game::basic() { camera* cam = rctx_ptr->camera; renderer::DOF3* dof = rctx_ptr->render.dof; - dof_pv pv; - dof_pv_get(&dof_pv_data); + dof_pv pv = {}; + dof_pv_get(&pv); vec3 interest; vec3 view_point; @@ -7383,7 +7398,8 @@ bool x_pv_game::unload() { rndr::Render& rend = rctx_ptr->render; rend.reset_saturate_coeff(0, true); - dof_pv_set(); + rend.set_dof_enable(false); + rend.set_dof_update(false); rend.reset_scene_fade(0); rend.set_taa(1); diff --git a/src/ReDIVA/x_pv_game.hpp b/src/ReDIVA/x_pv_game.hpp index 749c9b78..50eafde6 100644 --- a/src/ReDIVA/x_pv_game.hpp +++ b/src/ReDIVA/x_pv_game.hpp @@ -485,6 +485,9 @@ struct x_pv_game_pv_data { void find_stage_effects(prj::vector_pair& stage_effects); void init(class x_pv_game* pv_game, bool music_play); void reset(); + bool set_pv_param_post_process_bloom_data(bool set, int32_t id, float_t duration); + bool set_pv_param_post_process_color_correction_data(bool set, int32_t id, float_t duration); + bool set_pv_param_post_process_dof_data(bool set, int32_t id, float_t duration); void set_motion_max_frame(int32_t chara_id, int32_t motion_index, int64_t time); void unload(); };