| 914 | } |
| 915 | |
| 916 | LightmapperRD::BakeError LightmapperRD::_denoise_oidn(RenderingDevice *p_rd, RID p_source_light_tex, RID p_source_normal_tex, RID p_dest_light_tex, const Size2i &p_atlas_size, int p_atlas_slices, bool p_bake_sh, bool p_shadowmask, const String &p_exe) { |
| 917 | Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); |
| 918 | |
| 919 | for (int i = 0; i < p_atlas_slices; i++) { |
| 920 | String fname_norm_in = EditorPaths::get_singleton()->get_cache_dir().path_join(vformat("temp_norm_%d.pfm", i)); |
| 921 | _store_pfm(p_rd, p_source_normal_tex, i, p_atlas_size, fname_norm_in, false); |
| 922 | |
| 923 | for (int j = 0; j < (p_bake_sh ? 4 : 1); j++) { |
| 924 | int index = i * (p_bake_sh ? 4 : 1) + j; |
| 925 | String fname_light_in = EditorPaths::get_singleton()->get_cache_dir().path_join(vformat("temp_light_%d.pfm", index)); |
| 926 | String fname_out = EditorPaths::get_singleton()->get_cache_dir().path_join(vformat("temp_denoised_%d.pfm", index)); |
| 927 | |
| 928 | _store_pfm(p_rd, p_source_light_tex, index, p_atlas_size, fname_light_in, p_shadowmask); |
| 929 | |
| 930 | List<String> args; |
| 931 | args.push_back("--device"); |
| 932 | args.push_back("default"); |
| 933 | |
| 934 | args.push_back("--filter"); |
| 935 | args.push_back("RTLightmap"); |
| 936 | |
| 937 | args.push_back(p_shadowmask ? "--ldr" : "--hdr"); |
| 938 | args.push_back(fname_light_in); |
| 939 | |
| 940 | args.push_back("--nrm"); |
| 941 | args.push_back(fname_norm_in); |
| 942 | |
| 943 | args.push_back("--output"); |
| 944 | args.push_back(fname_out); |
| 945 | |
| 946 | String str; |
| 947 | int exitcode = 0; |
| 948 | |
| 949 | Error err = OS::get_singleton()->execute(p_exe, args, &str, &exitcode, true); |
| 950 | |
| 951 | da->remove(fname_light_in); |
| 952 | |
| 953 | if (err != OK || exitcode != 0) { |
| 954 | da->remove(fname_out); |
| 955 | print_verbose(str); |
| 956 | ERR_FAIL_V_MSG(BAKE_ERROR_LIGHTMAP_CANT_PRE_BAKE_MESHES, vformat("OIDN denoiser failed, return code: %d", exitcode)); |
| 957 | } |
| 958 | |
| 959 | Ref<Image> img = _read_pfm(fname_out, p_shadowmask); |
| 960 | da->remove(fname_out); |
| 961 | |
| 962 | ERR_FAIL_COND_V(img.is_null(), BAKE_ERROR_LIGHTMAP_CANT_PRE_BAKE_MESHES); |
| 963 | |
| 964 | Vector<uint8_t> old_data = p_rd->texture_get_data(p_source_light_tex, index); |
| 965 | Vector<uint8_t> new_data = img->get_data(); |
| 966 | img.unref(); // Avoid copy on write. |
| 967 | |
| 968 | uint32_t count = old_data.size() / 2; |
| 969 | const uint16_t *src = (const uint16_t *)old_data.ptr(); |
| 970 | uint16_t *dst = (uint16_t *)new_data.ptrw(); |
| 971 | for (uint32_t k = 0; k < count; k += 4) { |
| 972 | dst[k + 3] = src[k + 3]; |
| 973 | } |
nothing calls this directly
no test coverage detected