baked_lightmap.cpp 56 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637
  1. /*************************************************************************/
  2. /* baked_lightmap.cpp */
  3. /*************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* https://godotengine.org */
  7. /*************************************************************************/
  8. /* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
  9. /* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
  10. /* */
  11. /* Permission is hereby granted, free of charge, to any person obtaining */
  12. /* a copy of this software and associated documentation files (the */
  13. /* "Software"), to deal in the Software without restriction, including */
  14. /* without limitation the rights to use, copy, modify, merge, publish, */
  15. /* distribute, sublicense, and/or sell copies of the Software, and to */
  16. /* permit persons to whom the Software is furnished to do so, subject to */
  17. /* the following conditions: */
  18. /* */
  19. /* The above copyright notice and this permission notice shall be */
  20. /* included in all copies or substantial portions of the Software. */
  21. /* */
  22. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
  23. /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
  24. /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
  25. /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
  26. /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
  27. /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
  28. /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  29. /*************************************************************************/
  30. #include "baked_lightmap.h"
  31. #include "core/io/config_file.h"
  32. #include "core/io/resource_saver.h"
  33. #include "core/math/math_defs.h"
  34. #include "core/os/dir_access.h"
  35. #include "core/os/os.h"
  36. #include "voxel_light_baker.h"
  37. void BakedLightmapData::set_bounds(const AABB &p_bounds) {
  38. bounds = p_bounds;
  39. VS::get_singleton()->lightmap_capture_set_bounds(baked_light, p_bounds);
  40. }
  41. AABB BakedLightmapData::get_bounds() const {
  42. return bounds;
  43. }
  44. void BakedLightmapData::set_octree(const PoolVector<uint8_t> &p_octree) {
  45. VS::get_singleton()->lightmap_capture_set_octree(baked_light, p_octree);
  46. }
  47. PoolVector<uint8_t> BakedLightmapData::get_octree() const {
  48. return VS::get_singleton()->lightmap_capture_get_octree(baked_light);
  49. }
  50. void BakedLightmapData::set_cell_space_transform(const Transform &p_xform) {
  51. cell_space_xform = p_xform;
  52. VS::get_singleton()->lightmap_capture_set_octree_cell_transform(baked_light, p_xform);
  53. }
  54. Transform BakedLightmapData::get_cell_space_transform() const {
  55. return cell_space_xform;
  56. }
  57. void BakedLightmapData::set_cell_subdiv(int p_cell_subdiv) {
  58. cell_subdiv = p_cell_subdiv;
  59. VS::get_singleton()->lightmap_capture_set_octree_cell_subdiv(baked_light, p_cell_subdiv);
  60. }
  61. int BakedLightmapData::get_cell_subdiv() const {
  62. return cell_subdiv;
  63. }
  64. void BakedLightmapData::set_energy(float p_energy) {
  65. energy = p_energy;
  66. VS::get_singleton()->lightmap_capture_set_energy(baked_light, energy);
  67. }
  68. float BakedLightmapData::get_energy() const {
  69. return energy;
  70. }
  71. void BakedLightmapData::set_interior(bool p_interior) {
  72. interior = p_interior;
  73. VS::get_singleton()->lightmap_capture_set_interior(baked_light, interior);
  74. }
  75. bool BakedLightmapData::is_interior() const {
  76. return interior;
  77. }
  78. void BakedLightmapData::add_user(const NodePath &p_path, const Ref<Resource> &p_lightmap, int p_lightmap_slice, const Rect2 &p_lightmap_uv_rect, int p_instance) {
  79. ERR_FAIL_COND_MSG(p_lightmap.is_null(), "It's not a reference to a valid Texture object.");
  80. ERR_FAIL_COND(p_lightmap_slice == -1 && !Object::cast_to<Texture>(p_lightmap.ptr()));
  81. ERR_FAIL_COND(p_lightmap_slice != -1 && !Object::cast_to<TextureLayered>(p_lightmap.ptr()));
  82. User user;
  83. user.path = p_path;
  84. if (p_lightmap_slice == -1) {
  85. user.lightmap.single = p_lightmap;
  86. } else {
  87. user.lightmap.layered = p_lightmap;
  88. }
  89. user.lightmap_slice = p_lightmap_slice;
  90. user.lightmap_uv_rect = p_lightmap_uv_rect;
  91. user.instance_index = p_instance;
  92. users.push_back(user);
  93. }
  94. int BakedLightmapData::get_user_count() const {
  95. return users.size();
  96. }
  97. NodePath BakedLightmapData::get_user_path(int p_user) const {
  98. ERR_FAIL_INDEX_V(p_user, users.size(), NodePath());
  99. return users[p_user].path;
  100. }
  101. Ref<Resource> BakedLightmapData::get_user_lightmap(int p_user) const {
  102. ERR_FAIL_INDEX_V(p_user, users.size(), Ref<Resource>());
  103. if (users[p_user].lightmap_slice == -1) {
  104. return users[p_user].lightmap.single;
  105. } else {
  106. return users[p_user].lightmap.layered;
  107. }
  108. }
  109. int BakedLightmapData::get_user_lightmap_slice(int p_user) const {
  110. ERR_FAIL_INDEX_V(p_user, users.size(), -1);
  111. return users[p_user].lightmap_slice;
  112. }
  113. Rect2 BakedLightmapData::get_user_lightmap_uv_rect(int p_user) const {
  114. ERR_FAIL_INDEX_V(p_user, users.size(), Rect2(0, 0, 1, 1));
  115. return users[p_user].lightmap_uv_rect;
  116. }
  117. int BakedLightmapData::get_user_instance(int p_user) const {
  118. ERR_FAIL_INDEX_V(p_user, users.size(), -1);
  119. return users[p_user].instance_index;
  120. }
  121. void BakedLightmapData::clear_users() {
  122. users.clear();
  123. }
  124. void BakedLightmapData::clear_data() {
  125. clear_users();
  126. if (baked_light.is_valid()) {
  127. VS::get_singleton()->free(baked_light);
  128. }
  129. baked_light = VS::get_singleton()->lightmap_capture_create();
  130. }
  131. void BakedLightmapData::_set_user_data(const Array &p_data) {
  132. ERR_FAIL_COND(p_data.size() <= 0);
  133. // Detect old lightmapper format
  134. if (p_data.size() % 3 == 0) {
  135. bool is_old_format = true;
  136. for (int i = 0; i < p_data.size(); i += 3) {
  137. is_old_format = is_old_format && p_data[i + 0].get_type() == Variant::NODE_PATH;
  138. is_old_format = is_old_format && p_data[i + 1].is_ref();
  139. is_old_format = is_old_format && p_data[i + 2].get_type() == Variant::INT;
  140. if (!is_old_format) {
  141. break;
  142. }
  143. }
  144. if (is_old_format) {
  145. #ifdef DEBUG_ENABLED
  146. WARN_PRINT("Geometry at path " + String(p_data[0]) + " is using old lightmapper data. Please re-bake.");
  147. #endif
  148. Array adapted_data;
  149. adapted_data.resize((p_data.size() / 3) * 5);
  150. for (int i = 0; i < p_data.size() / 3; i++) {
  151. adapted_data[i * 5 + 0] = p_data[i * 3 + 0];
  152. adapted_data[i * 5 + 1] = p_data[i * 3 + 1];
  153. adapted_data[i * 5 + 2] = -1;
  154. adapted_data[i * 5 + 3] = Rect2(0, 0, 1, 1);
  155. adapted_data[i * 5 + 4] = p_data[i * 3 + 2];
  156. }
  157. _set_user_data(adapted_data);
  158. return;
  159. }
  160. }
  161. ERR_FAIL_COND((p_data.size() % 5) != 0);
  162. for (int i = 0; i < p_data.size(); i += 5) {
  163. add_user(p_data[i], p_data[i + 1], p_data[i + 2], p_data[i + 3], p_data[i + 4]);
  164. }
  165. }
  166. Array BakedLightmapData::_get_user_data() const {
  167. Array ret;
  168. for (int i = 0; i < users.size(); i++) {
  169. ret.push_back(users[i].path);
  170. ret.push_back(users[i].lightmap_slice == -1 ? Ref<Resource>(users[i].lightmap.single) : Ref<Resource>(users[i].lightmap.layered));
  171. ret.push_back(users[i].lightmap_slice);
  172. ret.push_back(users[i].lightmap_uv_rect);
  173. ret.push_back(users[i].instance_index);
  174. }
  175. return ret;
  176. }
  177. RID BakedLightmapData::get_rid() const {
  178. return baked_light;
  179. }
  180. void BakedLightmapData::_bind_methods() {
  181. ClassDB::bind_method(D_METHOD("_set_user_data", "data"), &BakedLightmapData::_set_user_data);
  182. ClassDB::bind_method(D_METHOD("_get_user_data"), &BakedLightmapData::_get_user_data);
  183. ClassDB::bind_method(D_METHOD("set_bounds", "bounds"), &BakedLightmapData::set_bounds);
  184. ClassDB::bind_method(D_METHOD("get_bounds"), &BakedLightmapData::get_bounds);
  185. ClassDB::bind_method(D_METHOD("set_cell_space_transform", "xform"), &BakedLightmapData::set_cell_space_transform);
  186. ClassDB::bind_method(D_METHOD("get_cell_space_transform"), &BakedLightmapData::get_cell_space_transform);
  187. ClassDB::bind_method(D_METHOD("set_cell_subdiv", "cell_subdiv"), &BakedLightmapData::set_cell_subdiv);
  188. ClassDB::bind_method(D_METHOD("get_cell_subdiv"), &BakedLightmapData::get_cell_subdiv);
  189. ClassDB::bind_method(D_METHOD("set_octree", "octree"), &BakedLightmapData::set_octree);
  190. ClassDB::bind_method(D_METHOD("get_octree"), &BakedLightmapData::get_octree);
  191. ClassDB::bind_method(D_METHOD("set_energy", "energy"), &BakedLightmapData::set_energy);
  192. ClassDB::bind_method(D_METHOD("get_energy"), &BakedLightmapData::get_energy);
  193. ClassDB::bind_method(D_METHOD("set_interior", "interior"), &BakedLightmapData::set_interior);
  194. ClassDB::bind_method(D_METHOD("is_interior"), &BakedLightmapData::is_interior);
  195. ClassDB::bind_method(D_METHOD("add_user", "path", "lightmap", "lightmap_slice", "lightmap_uv_rect", "instance"), &BakedLightmapData::add_user);
  196. ClassDB::bind_method(D_METHOD("get_user_count"), &BakedLightmapData::get_user_count);
  197. ClassDB::bind_method(D_METHOD("get_user_path", "user_idx"), &BakedLightmapData::get_user_path);
  198. ClassDB::bind_method(D_METHOD("get_user_lightmap", "user_idx"), &BakedLightmapData::get_user_lightmap);
  199. ClassDB::bind_method(D_METHOD("clear_users"), &BakedLightmapData::clear_users);
  200. ClassDB::bind_method(D_METHOD("clear_data"), &BakedLightmapData::clear_data);
  201. ADD_PROPERTY(PropertyInfo(Variant::AABB, "bounds", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_bounds", "get_bounds");
  202. ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "cell_space_transform", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_cell_space_transform", "get_cell_space_transform");
  203. ADD_PROPERTY(PropertyInfo(Variant::INT, "cell_subdiv", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_cell_subdiv", "get_cell_subdiv");
  204. ADD_PROPERTY(PropertyInfo(Variant::REAL, "energy", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_energy", "get_energy");
  205. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "interior"), "set_interior", "is_interior");
  206. ADD_PROPERTY(PropertyInfo(Variant::POOL_BYTE_ARRAY, "octree", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_octree", "get_octree");
  207. ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "user_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_user_data", "_get_user_data");
  208. }
  209. BakedLightmapData::BakedLightmapData() {
  210. baked_light = VS::get_singleton()->lightmap_capture_create();
  211. energy = 1;
  212. cell_subdiv = 1;
  213. interior = false;
  214. }
  215. BakedLightmapData::~BakedLightmapData() {
  216. VS::get_singleton()->free(baked_light);
  217. }
  218. ///////////////////////////
  219. Lightmapper::BakeStepFunc BakedLightmap::bake_step_function;
  220. Lightmapper::BakeStepFunc BakedLightmap::bake_substep_function;
  221. Lightmapper::BakeEndFunc BakedLightmap::bake_end_function;
  222. Size2i BakedLightmap::_compute_lightmap_size(const MeshesFound &p_mesh) {
  223. double area = 0;
  224. double uv_area = 0;
  225. for (int i = 0; i < p_mesh.mesh->get_surface_count(); i++) {
  226. Array arrays = p_mesh.mesh->surface_get_arrays(i);
  227. PoolVector<Vector3> vertices = arrays[Mesh::ARRAY_VERTEX];
  228. PoolVector<Vector2> uv2 = arrays[Mesh::ARRAY_TEX_UV2];
  229. PoolVector<int> indices = arrays[Mesh::ARRAY_INDEX];
  230. ERR_FAIL_COND_V(vertices.size() == 0, Vector2());
  231. ERR_FAIL_COND_V(uv2.size() == 0, Vector2());
  232. int vc = vertices.size();
  233. PoolVector<Vector3>::Read vr = vertices.read();
  234. PoolVector<Vector2>::Read u2r = uv2.read();
  235. PoolVector<int>::Read ir;
  236. int ic = 0;
  237. if (indices.size()) {
  238. ic = indices.size();
  239. ir = indices.read();
  240. }
  241. int faces = ic ? ic / 3 : vc / 3;
  242. for (int j = 0; j < faces; j++) {
  243. Vector3 vertex[3];
  244. Vector2 uv[3];
  245. for (int k = 0; k < 3; k++) {
  246. int idx = ic ? ir[j * 3 + k] : j * 3 + k;
  247. vertex[k] = p_mesh.xform.xform(vr[idx]);
  248. uv[k] = u2r[idx];
  249. }
  250. Vector3 p1 = vertex[0];
  251. Vector3 p2 = vertex[1];
  252. Vector3 p3 = vertex[2];
  253. double a = p1.distance_to(p2);
  254. double b = p2.distance_to(p3);
  255. double c = p3.distance_to(p1);
  256. double halfPerimeter = (a + b + c) / 2.0;
  257. area += sqrt(halfPerimeter * (halfPerimeter - a) * (halfPerimeter - b) * (halfPerimeter - c));
  258. Vector2 uv_p1 = uv[0];
  259. Vector2 uv_p2 = uv[1];
  260. Vector2 uv_p3 = uv[2];
  261. double uv_a = uv_p1.distance_to(uv_p2);
  262. double uv_b = uv_p2.distance_to(uv_p3);
  263. double uv_c = uv_p3.distance_to(uv_p1);
  264. double uv_halfPerimeter = (uv_a + uv_b + uv_c) / 2.0;
  265. uv_area += sqrt(
  266. uv_halfPerimeter * (uv_halfPerimeter - uv_a) * (uv_halfPerimeter - uv_b) * (uv_halfPerimeter - uv_c));
  267. }
  268. }
  269. if (uv_area < 0.0001f) {
  270. uv_area = 1.0;
  271. }
  272. int pixels = Math::round(ceil((1.0 / sqrt(uv_area)) * sqrt(area * default_texels_per_unit)));
  273. int size = CLAMP(pixels, 2, 4096);
  274. return Vector2i(size, size);
  275. }
  276. void BakedLightmap::_find_meshes_and_lights(Node *p_at_node, Vector<MeshesFound> &meshes, Vector<LightsFound> &lights) {
  277. AABB bounds = AABB(-extents, extents * 2.0);
  278. MeshInstance *mi = Object::cast_to<MeshInstance>(p_at_node);
  279. if (mi && mi->get_flag(GeometryInstance::FLAG_USE_BAKED_LIGHT) && mi->is_visible_in_tree()) {
  280. Ref<Mesh> mesh = mi->get_mesh();
  281. if (mesh.is_valid()) {
  282. bool all_have_uv2_and_normal = true;
  283. bool surfaces_found = false;
  284. for (int i = 0; i < mesh->get_surface_count(); i++) {
  285. if (mesh->surface_get_primitive_type(i) != Mesh::PRIMITIVE_TRIANGLES) {
  286. continue;
  287. }
  288. if (!(mesh->surface_get_format(i) & Mesh::ARRAY_FORMAT_TEX_UV2)) {
  289. all_have_uv2_and_normal = false;
  290. break;
  291. }
  292. if (!(mesh->surface_get_format(i) & Mesh::ARRAY_FORMAT_NORMAL)) {
  293. all_have_uv2_and_normal = false;
  294. break;
  295. }
  296. surfaces_found = true;
  297. }
  298. if (surfaces_found && all_have_uv2_and_normal) {
  299. Transform mesh_xform = get_global_transform().affine_inverse() * mi->get_global_transform();
  300. AABB aabb = mesh_xform.xform(mesh->get_aabb());
  301. if (bounds.intersects(aabb)) {
  302. MeshesFound mf;
  303. mf.cast_shadows = mi->get_cast_shadows_setting() != GeometryInstance::SHADOW_CASTING_SETTING_OFF;
  304. mf.generate_lightmap = mi->get_generate_lightmap();
  305. mf.xform = mesh_xform;
  306. mf.node_path = get_path_to(mi);
  307. mf.subindex = -1;
  308. mf.mesh = mesh;
  309. static const int lightmap_scale[4] = { 1, 2, 4, 8 }; //GeometryInstance3D::LIGHTMAP_SCALE_MAX = { 1, 2, 4, 8 };
  310. mf.lightmap_scale = lightmap_scale[mi->get_lightmap_scale()];
  311. Ref<Material> all_override = mi->get_material_override();
  312. for (int i = 0; i < mesh->get_surface_count(); i++) {
  313. if (all_override.is_valid()) {
  314. mf.overrides.push_back(all_override);
  315. } else {
  316. mf.overrides.push_back(mi->get_surface_material(i));
  317. }
  318. }
  319. meshes.push_back(mf);
  320. }
  321. }
  322. }
  323. }
  324. Spatial *s = Object::cast_to<Spatial>(p_at_node);
  325. if (!mi && s) {
  326. Array bmeshes = p_at_node->call("get_bake_meshes");
  327. if (bmeshes.size() && (bmeshes.size() & 1) == 0) {
  328. Transform xf = get_global_transform().affine_inverse() * s->get_global_transform();
  329. Ref<Material> all_override;
  330. GeometryInstance *gi = Object::cast_to<GeometryInstance>(p_at_node);
  331. if (gi) {
  332. all_override = gi->get_material_override();
  333. }
  334. for (int i = 0; i < bmeshes.size(); i += 2) {
  335. Ref<Mesh> mesh = bmeshes[i];
  336. if (!mesh.is_valid()) {
  337. continue;
  338. }
  339. Transform mesh_xform = xf * bmeshes[i + 1];
  340. AABB aabb = mesh_xform.xform(mesh->get_aabb());
  341. if (!bounds.intersects(aabb)) {
  342. continue;
  343. }
  344. MeshesFound mf;
  345. mf.xform = mesh_xform;
  346. mf.node_path = get_path_to(s);
  347. mf.subindex = i / 2;
  348. mf.lightmap_scale = 1;
  349. mf.mesh = mesh;
  350. if (gi) {
  351. mf.cast_shadows = gi->get_cast_shadows_setting() != GeometryInstance::SHADOW_CASTING_SETTING_OFF;
  352. mf.generate_lightmap = gi->get_generate_lightmap();
  353. } else {
  354. mf.cast_shadows = true;
  355. mf.generate_lightmap = true;
  356. }
  357. for (int j = 0; j < mesh->get_surface_count(); j++) {
  358. mf.overrides.push_back(all_override);
  359. }
  360. meshes.push_back(mf);
  361. }
  362. }
  363. }
  364. Light *light = Object::cast_to<Light>(p_at_node);
  365. if (light && light->get_bake_mode() != Light::BAKE_DISABLED) {
  366. LightsFound lf;
  367. lf.xform = get_global_transform().affine_inverse() * light->get_global_transform();
  368. lf.light = light;
  369. lights.push_back(lf);
  370. }
  371. for (int i = 0; i < p_at_node->get_child_count(); i++) {
  372. Node *child = p_at_node->get_child(i);
  373. if (!child->get_owner()) {
  374. continue; //maybe a helper
  375. }
  376. _find_meshes_and_lights(child, meshes, lights);
  377. }
  378. }
  379. void BakedLightmap::_get_material_images(const MeshesFound &p_found_mesh, Lightmapper::MeshData &r_mesh_data, Vector<Ref<Texture>> &r_albedo_textures, Vector<Ref<Texture>> &r_emission_textures) {
  380. for (int i = 0; i < p_found_mesh.mesh->get_surface_count(); ++i) {
  381. Ref<SpatialMaterial> mat = p_found_mesh.overrides[i];
  382. if (mat.is_null()) {
  383. mat = p_found_mesh.mesh->surface_get_material(i);
  384. }
  385. Ref<Texture> albedo_texture;
  386. Color albedo_add = Color(1, 1, 1, 1);
  387. Color albedo_mul = Color(1, 1, 1, 1);
  388. Ref<Texture> emission_texture;
  389. Color emission_add = Color(0, 0, 0, 0);
  390. Color emission_mul = Color(1, 1, 1, 1);
  391. if (mat.is_valid()) {
  392. albedo_texture = mat->get_texture(SpatialMaterial::TEXTURE_ALBEDO);
  393. if (albedo_texture.is_valid()) {
  394. albedo_mul = mat->get_albedo();
  395. albedo_add = Color(0, 0, 0, 0);
  396. } else {
  397. albedo_add = mat->get_albedo();
  398. }
  399. emission_texture = mat->get_texture(SpatialMaterial::TEXTURE_EMISSION);
  400. Color emission_color = mat->get_emission();
  401. float emission_energy = mat->get_emission_energy();
  402. if (mat->get_emission_operator() == SpatialMaterial::EMISSION_OP_ADD) {
  403. emission_mul = Color(1, 1, 1) * emission_energy;
  404. emission_add = emission_color * emission_energy;
  405. } else {
  406. emission_mul = emission_color * emission_energy;
  407. emission_add = Color(0, 0, 0);
  408. }
  409. }
  410. Lightmapper::MeshData::TextureDef albedo;
  411. albedo.mul = albedo_mul;
  412. albedo.add = albedo_add;
  413. if (albedo_texture.is_valid()) {
  414. albedo.tex_rid = albedo_texture->get_rid();
  415. r_albedo_textures.push_back(albedo_texture);
  416. }
  417. r_mesh_data.albedo.push_back(albedo);
  418. Lightmapper::MeshData::TextureDef emission;
  419. emission.mul = emission_mul;
  420. emission.add = emission_add;
  421. if (emission_texture.is_valid()) {
  422. emission.tex_rid = emission_texture->get_rid();
  423. r_emission_textures.push_back(emission_texture);
  424. }
  425. r_mesh_data.emission.push_back(emission);
  426. }
  427. }
  428. void BakedLightmap::_save_image(String &r_base_path, Ref<Image> r_img, bool p_use_srgb) {
  429. if (use_hdr) {
  430. r_base_path += ".exr";
  431. } else {
  432. r_base_path += ".png";
  433. }
  434. String relative_path = r_base_path;
  435. if (relative_path.begins_with("res://")) {
  436. relative_path = relative_path.substr(6, relative_path.length());
  437. }
  438. bool hdr_grayscale = use_hdr && !use_color;
  439. r_img->lock();
  440. for (int i = 0; i < r_img->get_height(); i++) {
  441. for (int j = 0; j < r_img->get_width(); j++) {
  442. Color c = r_img->get_pixel(j, i);
  443. c.r = MAX(c.r, environment_min_light.r);
  444. c.g = MAX(c.g, environment_min_light.g);
  445. c.b = MAX(c.b, environment_min_light.b);
  446. if (hdr_grayscale) {
  447. c = Color(c.get_v(), 0.0f, 0.0f);
  448. }
  449. if (p_use_srgb) {
  450. c = c.to_srgb();
  451. }
  452. r_img->set_pixel(j, i, c);
  453. }
  454. }
  455. r_img->unlock();
  456. if (!use_color) {
  457. if (use_hdr) {
  458. r_img->convert(Image::FORMAT_RH);
  459. } else {
  460. r_img->convert(Image::FORMAT_L8);
  461. }
  462. }
  463. if (use_hdr) {
  464. r_img->save_exr(relative_path, !use_color);
  465. } else {
  466. r_img->save_png(relative_path);
  467. }
  468. }
  469. bool BakedLightmap::_lightmap_bake_step_function(float p_completion, const String &p_text, void *ud, bool p_refresh) {
  470. BakeStepUD *bsud = (BakeStepUD *)ud;
  471. bool ret = false;
  472. if (bsud->func) {
  473. ret = bsud->func(bsud->from_percent + p_completion * (bsud->to_percent - bsud->from_percent), p_text, bsud->ud, p_refresh);
  474. }
  475. return ret;
  476. }
  477. BakedLightmap::BakeError BakedLightmap::bake(Node *p_from_node, String p_data_save_path) {
  478. if (!p_from_node && !get_parent()) {
  479. return BAKE_ERROR_NO_ROOT;
  480. }
  481. bool no_save_path = false;
  482. if (p_data_save_path == "" && (get_light_data().is_null() || !get_light_data()->get_path().is_resource_file())) {
  483. no_save_path = true;
  484. }
  485. if (p_data_save_path == "") {
  486. if (get_light_data().is_null()) {
  487. no_save_path = true;
  488. } else {
  489. p_data_save_path = get_light_data()->get_path();
  490. if (!p_data_save_path.is_resource_file()) {
  491. no_save_path = true;
  492. }
  493. }
  494. }
  495. if (no_save_path) {
  496. if (image_path == "") {
  497. return BAKE_ERROR_NO_SAVE_PATH;
  498. } else {
  499. p_data_save_path = image_path;
  500. }
  501. WARN_PRINT("Using the deprecated property \"image_path\" as a save path, consider providing a better save path via the \"data_save_path\" parameter");
  502. p_data_save_path = image_path.plus_file("BakedLightmap.lmbake");
  503. }
  504. {
  505. //check for valid save path
  506. DirAccessRef d = DirAccess::open(p_data_save_path.get_base_dir());
  507. if (!d) {
  508. ERR_FAIL_V_MSG(BAKE_ERROR_NO_SAVE_PATH, "Invalid save path '" + p_data_save_path + "'.");
  509. }
  510. }
  511. uint32_t time_started = OS::get_singleton()->get_ticks_msec();
  512. if (bake_step_function) {
  513. bool cancelled = bake_step_function(0.0, TTR("Finding meshes and lights"), nullptr, true);
  514. if (cancelled) {
  515. bake_end_function(time_started);
  516. return BAKE_ERROR_USER_ABORTED;
  517. }
  518. }
  519. Ref<Lightmapper> lightmapper = Lightmapper::create();
  520. if (lightmapper.is_null()) {
  521. bake_end_function(time_started);
  522. return BAKE_ERROR_NO_LIGHTMAPPER;
  523. }
  524. Vector<LightsFound> lights_found;
  525. Vector<MeshesFound> meshes_found;
  526. _find_meshes_and_lights(p_from_node ? p_from_node : get_parent(), meshes_found, lights_found);
  527. if (meshes_found.size() == 0) {
  528. bake_end_function(time_started);
  529. return BAKE_ERROR_NO_MESHES;
  530. }
  531. for (int m_i = 0; m_i < meshes_found.size(); m_i++) {
  532. if (bake_step_function) {
  533. float p = (float)(m_i) / meshes_found.size();
  534. bool cancelled = bake_step_function(p * 0.05, vformat(TTR("Preparing geometry (%d/%d)"), m_i + 1, meshes_found.size()), nullptr, false);
  535. if (cancelled) {
  536. bake_end_function(time_started);
  537. return BAKE_ERROR_USER_ABORTED;
  538. }
  539. }
  540. MeshesFound &mf = meshes_found.write[m_i];
  541. Size2i lightmap_size = mf.mesh->get_lightmap_size_hint();
  542. if (lightmap_size == Vector2i(0, 0)) {
  543. lightmap_size = _compute_lightmap_size(mf);
  544. }
  545. lightmap_size *= mf.lightmap_scale;
  546. Lightmapper::MeshData md;
  547. {
  548. Dictionary d;
  549. d["path"] = mf.node_path;
  550. if (mf.subindex >= 0) {
  551. d["subindex"] = mf.subindex;
  552. }
  553. d["cast_shadows"] = mf.cast_shadows;
  554. d["generate_lightmap"] = mf.generate_lightmap;
  555. d["node_name"] = mf.node_path.get_name(mf.node_path.get_name_count() - 1);
  556. md.userdata = d;
  557. }
  558. Basis normal_xform = mf.xform.basis.inverse().transposed();
  559. for (int i = 0; i < mf.mesh->get_surface_count(); i++) {
  560. if (mf.mesh->surface_get_primitive_type(i) != Mesh::PRIMITIVE_TRIANGLES) {
  561. continue;
  562. }
  563. Array a = mf.mesh->surface_get_arrays(i);
  564. Vector<Vector3> vertices = a[Mesh::ARRAY_VERTEX];
  565. const Vector3 *vr = vertices.ptr();
  566. Vector<Vector2> uv2 = a[Mesh::ARRAY_TEX_UV2];
  567. const Vector2 *uv2r = nullptr;
  568. Vector<Vector2> uv = a[Mesh::ARRAY_TEX_UV];
  569. const Vector2 *uvr = nullptr;
  570. Vector<Vector3> normals = a[Mesh::ARRAY_NORMAL];
  571. const Vector3 *nr = nullptr;
  572. Vector<int> index = a[Mesh::ARRAY_INDEX];
  573. ERR_CONTINUE(uv2.size() == 0);
  574. ERR_CONTINUE(normals.size() == 0);
  575. if (!uv.empty()) {
  576. uvr = uv.ptr();
  577. }
  578. uv2r = uv2.ptr();
  579. nr = normals.ptr();
  580. int facecount;
  581. const int *ir = nullptr;
  582. if (index.size()) {
  583. facecount = index.size() / 3;
  584. ir = index.ptr();
  585. } else {
  586. facecount = vertices.size() / 3;
  587. }
  588. md.surface_facecounts.push_back(facecount);
  589. for (int j = 0; j < facecount; j++) {
  590. uint32_t vidx[3];
  591. if (ir) {
  592. for (int k = 0; k < 3; k++) {
  593. vidx[k] = ir[j * 3 + k];
  594. }
  595. } else {
  596. for (int k = 0; k < 3; k++) {
  597. vidx[k] = j * 3 + k;
  598. }
  599. }
  600. for (int k = 0; k < 3; k++) {
  601. Vector3 v = mf.xform.xform(vr[vidx[k]]);
  602. md.points.push_back(v);
  603. md.uv2.push_back(uv2r[vidx[k]]);
  604. md.normal.push_back(normal_xform.xform(nr[vidx[k]]).normalized());
  605. if (uvr != nullptr) {
  606. md.uv.push_back(uvr[vidx[k]]);
  607. }
  608. }
  609. }
  610. }
  611. Vector<Ref<Texture>> albedo_textures;
  612. Vector<Ref<Texture>> emission_textures;
  613. _get_material_images(mf, md, albedo_textures, emission_textures);
  614. for (int j = 0; j < albedo_textures.size(); j++) {
  615. lightmapper->add_albedo_texture(albedo_textures[j]);
  616. }
  617. for (int j = 0; j < emission_textures.size(); j++) {
  618. lightmapper->add_emission_texture(emission_textures[j]);
  619. }
  620. lightmapper->add_mesh(md, lightmap_size);
  621. }
  622. for (int i = 0; i < lights_found.size(); i++) {
  623. Light *light = lights_found[i].light;
  624. Transform xf = lights_found[i].xform;
  625. if (Object::cast_to<DirectionalLight>(light)) {
  626. DirectionalLight *l = Object::cast_to<DirectionalLight>(light);
  627. lightmapper->add_directional_light(light->get_bake_mode() == Light::BAKE_ALL, -xf.basis.get_axis(Vector3::AXIS_Z).normalized(), l->get_color(), l->get_param(Light::PARAM_ENERGY), l->get_param(Light::PARAM_INDIRECT_ENERGY), l->get_param(Light::PARAM_SIZE));
  628. } else if (Object::cast_to<OmniLight>(light)) {
  629. OmniLight *l = Object::cast_to<OmniLight>(light);
  630. lightmapper->add_omni_light(light->get_bake_mode() == Light::BAKE_ALL, xf.origin, l->get_color(), l->get_param(Light::PARAM_ENERGY), l->get_param(Light::PARAM_INDIRECT_ENERGY), l->get_param(Light::PARAM_RANGE), l->get_param(Light::PARAM_ATTENUATION), l->get_param(Light::PARAM_SIZE));
  631. } else if (Object::cast_to<SpotLight>(light)) {
  632. SpotLight *l = Object::cast_to<SpotLight>(light);
  633. lightmapper->add_spot_light(light->get_bake_mode() == Light::BAKE_ALL, xf.origin, -xf.basis.get_axis(Vector3::AXIS_Z).normalized(), l->get_color(), l->get_param(Light::PARAM_ENERGY), l->get_param(Light::PARAM_INDIRECT_ENERGY), l->get_param(Light::PARAM_RANGE), l->get_param(Light::PARAM_ATTENUATION), l->get_param(Light::PARAM_SPOT_ANGLE), l->get_param(Light::PARAM_SPOT_ATTENUATION), l->get_param(Light::PARAM_SIZE));
  634. }
  635. }
  636. Ref<Image> environment_image;
  637. Basis environment_xform;
  638. if (environment_mode != ENVIRONMENT_MODE_DISABLED) {
  639. if (bake_step_function) {
  640. bake_step_function(0.1, TTR("Preparing environment"), nullptr, true);
  641. }
  642. switch (environment_mode) {
  643. case ENVIRONMENT_MODE_DISABLED: {
  644. //nothing
  645. } break;
  646. case ENVIRONMENT_MODE_SCENE: {
  647. Ref<World> world = get_world();
  648. if (world.is_valid()) {
  649. Ref<Environment> env = world->get_environment();
  650. if (env.is_null()) {
  651. env = world->get_fallback_environment();
  652. }
  653. if (env.is_valid()) {
  654. environment_image = _get_irradiance_map(env, Vector2i(128, 64));
  655. environment_xform = get_global_transform().affine_inverse().basis * env->get_sky_orientation();
  656. }
  657. }
  658. } break;
  659. case ENVIRONMENT_MODE_CUSTOM_SKY: {
  660. if (environment_custom_sky.is_valid()) {
  661. environment_image = _get_irradiance_from_sky(environment_custom_sky, environment_custom_energy, Vector2i(128, 64));
  662. environment_xform.set_euler(environment_custom_sky_rotation_degrees * Math_PI / 180.0);
  663. }
  664. } break;
  665. case ENVIRONMENT_MODE_CUSTOM_COLOR: {
  666. environment_image.instance();
  667. environment_image->create(128, 64, false, Image::FORMAT_RGBF);
  668. Color c = environment_custom_color;
  669. c.r *= environment_custom_energy;
  670. c.g *= environment_custom_energy;
  671. c.b *= environment_custom_energy;
  672. environment_image->lock();
  673. for (int i = 0; i < 128; i++) {
  674. for (int j = 0; j < 64; j++) {
  675. environment_image->set_pixel(i, j, c);
  676. }
  677. }
  678. environment_image->unlock();
  679. } break;
  680. }
  681. }
  682. BakeStepUD bsud;
  683. bsud.func = bake_step_function;
  684. bsud.ud = nullptr;
  685. bsud.from_percent = 0.1;
  686. bsud.to_percent = 0.9;
  687. bool gen_atlas = OS::get_singleton()->get_current_video_driver() == OS::VIDEO_DRIVER_GLES2 ? false : generate_atlas;
  688. Lightmapper::BakeError bake_err = lightmapper->bake(Lightmapper::BakeQuality(bake_quality), use_denoiser, bounces, bounce_indirect_energy, bias, gen_atlas, max_atlas_size, environment_image, environment_xform, _lightmap_bake_step_function, &bsud, bake_substep_function);
  689. if (bake_err != Lightmapper::BAKE_OK) {
  690. bake_end_function(time_started);
  691. switch (bake_err) {
  692. case Lightmapper::BAKE_ERROR_USER_ABORTED: {
  693. return BAKE_ERROR_USER_ABORTED;
  694. }
  695. case Lightmapper::BAKE_ERROR_LIGHTMAP_TOO_SMALL: {
  696. return BAKE_ERROR_LIGHTMAP_SIZE;
  697. }
  698. case Lightmapper::BAKE_ERROR_NO_MESHES: {
  699. return BAKE_ERROR_NO_MESHES;
  700. }
  701. default: {
  702. }
  703. }
  704. return BAKE_ERROR_NO_LIGHTMAPPER;
  705. }
  706. Ref<BakedLightmapData> data;
  707. if (get_light_data().is_valid()) {
  708. data = get_light_data();
  709. set_light_data(Ref<BakedLightmapData>()); //clear
  710. data->clear_data();
  711. } else {
  712. data.instance();
  713. }
  714. if (capture_enabled) {
  715. if (bake_step_function) {
  716. bool cancelled = bake_step_function(0.85, TTR("Generating capture"), nullptr, true);
  717. if (cancelled) {
  718. bake_end_function(time_started);
  719. return BAKE_ERROR_USER_ABORTED;
  720. }
  721. }
  722. VoxelLightBaker voxel_baker;
  723. int bake_subdiv;
  724. int capture_subdiv;
  725. AABB bake_bounds;
  726. {
  727. bake_bounds = AABB(-extents, extents * 2.0);
  728. int subdiv = nearest_power_of_2_templated(int(bake_bounds.get_longest_axis_size() / capture_cell_size));
  729. bake_bounds.size[bake_bounds.get_longest_axis_index()] = subdiv * capture_cell_size;
  730. bake_subdiv = nearest_shift(subdiv) + 1;
  731. capture_subdiv = bake_subdiv;
  732. float css = capture_cell_size;
  733. while (css < capture_cell_size && capture_subdiv > 2) {
  734. capture_subdiv--;
  735. css *= 2.0;
  736. }
  737. }
  738. voxel_baker.begin_bake(capture_subdiv + 1, bake_bounds);
  739. for (int mesh_id = 0; mesh_id < meshes_found.size(); mesh_id++) {
  740. MeshesFound &mf = meshes_found.write[mesh_id];
  741. voxel_baker.plot_mesh(mf.xform, mf.mesh, mf.overrides, Ref<Material>());
  742. }
  743. VoxelLightBaker::BakeQuality capt_quality = VoxelLightBaker::BakeQuality::BAKE_QUALITY_HIGH;
  744. if (capture_quality == BakedLightmap::BakeQuality::BAKE_QUALITY_LOW) {
  745. capt_quality = VoxelLightBaker::BakeQuality::BAKE_QUALITY_LOW;
  746. } else if (capture_quality == BakedLightmap::BakeQuality::BAKE_QUALITY_MEDIUM) {
  747. capt_quality = VoxelLightBaker::BakeQuality::BAKE_QUALITY_MEDIUM;
  748. }
  749. voxel_baker.begin_bake_light(capt_quality, capture_propagation);
  750. for (int i = 0; i < lights_found.size(); i++) {
  751. LightsFound &lf = lights_found.write[i];
  752. switch (lf.light->get_light_type()) {
  753. case VS::LIGHT_DIRECTIONAL: {
  754. voxel_baker.plot_light_directional(-lf.xform.basis.get_axis(2), lf.light->get_color(), lf.light->get_param(Light::PARAM_ENERGY), lf.light->get_param(Light::PARAM_INDIRECT_ENERGY), lf.light->get_bake_mode() == Light::BAKE_ALL);
  755. } break;
  756. case VS::LIGHT_OMNI: {
  757. voxel_baker.plot_light_omni(lf.xform.origin, lf.light->get_color(), lf.light->get_param(Light::PARAM_ENERGY), lf.light->get_param(Light::PARAM_INDIRECT_ENERGY), lf.light->get_param(Light::PARAM_RANGE), lf.light->get_param(Light::PARAM_ATTENUATION), lf.light->get_bake_mode() == Light::BAKE_ALL);
  758. } break;
  759. case VS::LIGHT_SPOT: {
  760. voxel_baker.plot_light_spot(lf.xform.origin, lf.xform.basis.get_axis(2), lf.light->get_color(), lf.light->get_param(Light::PARAM_ENERGY), lf.light->get_param(Light::PARAM_INDIRECT_ENERGY), lf.light->get_param(Light::PARAM_RANGE), lf.light->get_param(Light::PARAM_ATTENUATION), lf.light->get_param(Light::PARAM_SPOT_ANGLE), lf.light->get_param(Light::PARAM_SPOT_ATTENUATION), lf.light->get_bake_mode() == Light::BAKE_ALL);
  761. } break;
  762. }
  763. }
  764. voxel_baker.end_bake();
  765. AABB bounds = AABB(-extents, extents * 2);
  766. data->set_cell_subdiv(capture_subdiv);
  767. data->set_bounds(bounds);
  768. data->set_octree(voxel_baker.create_capture_octree(capture_subdiv));
  769. {
  770. float bake_bound_size = bake_bounds.get_longest_axis_size();
  771. Transform to_bounds;
  772. to_bounds.basis.scale(Vector3(bake_bound_size, bake_bound_size, bake_bound_size));
  773. to_bounds.origin = bounds.position;
  774. Transform to_grid;
  775. to_grid.basis.scale(Vector3(1 << (capture_subdiv - 1), 1 << (capture_subdiv - 1), 1 << (capture_subdiv - 1)));
  776. Transform to_cell_space = to_grid * to_bounds.affine_inverse();
  777. data->set_cell_space_transform(to_cell_space);
  778. }
  779. }
  780. if (bake_step_function) {
  781. bool cancelled = bake_step_function(0.9, TTR("Saving lightmaps"), nullptr, true);
  782. if (cancelled) {
  783. bake_end_function(time_started);
  784. return BAKE_ERROR_USER_ABORTED;
  785. }
  786. }
  787. Vector<Ref<Image>> images;
  788. for (int i = 0; i < lightmapper->get_bake_texture_count(); i++) {
  789. images.push_back(lightmapper->get_bake_texture(i));
  790. }
  791. bool use_srgb = use_color && !use_hdr;
  792. if (gen_atlas) {
  793. Ref<Image> large_image;
  794. large_image.instance();
  795. large_image->create(images[0]->get_width(), images[0]->get_height() * images.size(), false, images[0]->get_format());
  796. for (int i = 0; i < images.size(); i++) {
  797. large_image->blit_rect(images[i], Rect2(0, 0, images[0]->get_width(), images[0]->get_height()), Point2(0, images[0]->get_height() * i));
  798. }
  799. Ref<TextureLayered> texture;
  800. String base_path = p_data_save_path.get_basename();
  801. if (ResourceLoader::import) {
  802. _save_image(base_path, large_image, use_srgb);
  803. Ref<ConfigFile> config;
  804. config.instance();
  805. if (FileAccess::exists(base_path + ".import")) {
  806. config->load(base_path + ".import");
  807. } else {
  808. // Set only if settings don't exist, to keep user choice
  809. config->set_value("params", "compress/mode", 0);
  810. }
  811. config->set_value("remap", "importer", "texture_array");
  812. config->set_value("remap", "type", "TextureArray");
  813. config->set_value("params", "detect_3d", false);
  814. config->set_value("params", "flags/repeat", false);
  815. config->set_value("params", "flags/filter", true);
  816. config->set_value("params", "flags/mipmaps", false);
  817. config->set_value("params", "flags/srgb", use_srgb);
  818. config->set_value("params", "slices/horizontal", 1);
  819. config->set_value("params", "slices/vertical", images.size());
  820. config->save(base_path + ".import");
  821. ResourceLoader::import(base_path);
  822. texture = ResourceLoader::load(base_path); //if already loaded, it will be updated on refocus?
  823. } else {
  824. base_path += ".texarr";
  825. Ref<TextureLayered> tex;
  826. bool set_path = true;
  827. if (ResourceCache::has(base_path)) {
  828. tex = Ref<Resource>((Resource *)ResourceCache::get(base_path));
  829. set_path = false;
  830. }
  831. if (!tex.is_valid()) {
  832. tex.instance();
  833. }
  834. tex->create(images[0]->get_width(), images[0]->get_height(), images.size(), images[0]->get_format(), Texture::FLAGS_DEFAULT);
  835. for (int i = 0; i < images.size(); i++) {
  836. tex->set_layer_data(images[i], i);
  837. }
  838. ResourceSaver::save(base_path, tex, ResourceSaver::FLAG_CHANGE_PATH);
  839. if (set_path) {
  840. tex->set_path(base_path);
  841. }
  842. texture = tex;
  843. }
  844. for (int i = 0; i < lightmapper->get_bake_mesh_count(); i++) {
  845. if (meshes_found[i].generate_lightmap) {
  846. Dictionary d = lightmapper->get_bake_mesh_userdata(i);
  847. NodePath np = d["path"];
  848. int32_t subindex = -1;
  849. if (d.has("subindex")) {
  850. subindex = d["subindex"];
  851. }
  852. Rect2 uv_rect = lightmapper->get_bake_mesh_uv_scale(i);
  853. int slice_index = lightmapper->get_bake_mesh_texture_slice(i);
  854. data->add_user(np, texture, slice_index, uv_rect, subindex);
  855. }
  856. }
  857. } else {
  858. for (int i = 0; i < lightmapper->get_bake_mesh_count(); i++) {
  859. if (!meshes_found[i].generate_lightmap) {
  860. continue;
  861. }
  862. Ref<Texture> texture;
  863. String base_path = p_data_save_path.get_base_dir().plus_file(images[i]->get_name());
  864. if (ResourceLoader::import) {
  865. _save_image(base_path, images[i], use_srgb);
  866. Ref<ConfigFile> config;
  867. config.instance();
  868. if (FileAccess::exists(base_path + ".import")) {
  869. config->load(base_path + ".import");
  870. } else {
  871. // Set only if settings don't exist, to keep user choice
  872. config->set_value("params", "compress/mode", 0);
  873. }
  874. config->set_value("remap", "importer", "texture");
  875. config->set_value("remap", "type", "StreamTexture");
  876. config->set_value("params", "detect_3d", false);
  877. config->set_value("params", "flags/repeat", false);
  878. config->set_value("params", "flags/filter", true);
  879. config->set_value("params", "flags/mipmaps", false);
  880. config->set_value("params", "flags/srgb", use_srgb);
  881. config->save(base_path + ".import");
  882. ResourceLoader::import(base_path);
  883. texture = ResourceLoader::load(base_path); //if already loaded, it will be updated on refocus?
  884. } else {
  885. base_path += ".tex";
  886. Ref<ImageTexture> tex;
  887. bool set_path = true;
  888. if (ResourceCache::has(base_path)) {
  889. tex = Ref<Resource>((Resource *)ResourceCache::get(base_path));
  890. set_path = false;
  891. }
  892. if (!tex.is_valid()) {
  893. tex.instance();
  894. }
  895. tex->create_from_image(images[i], Texture::FLAGS_DEFAULT);
  896. ResourceSaver::save(base_path, tex, ResourceSaver::FLAG_CHANGE_PATH);
  897. if (set_path) {
  898. tex->set_path(base_path);
  899. }
  900. texture = tex;
  901. }
  902. Dictionary d = lightmapper->get_bake_mesh_userdata(i);
  903. NodePath np = d["path"];
  904. int32_t subindex = -1;
  905. if (d.has("subindex")) {
  906. subindex = d["subindex"];
  907. }
  908. Rect2 uv_rect = Rect2(0, 0, 1, 1);
  909. int slice_index = -1;
  910. data->add_user(np, texture, slice_index, uv_rect, subindex);
  911. }
  912. }
  913. if (bake_step_function) {
  914. bool cancelled = bake_step_function(1.0, TTR("Done"), nullptr, true);
  915. if (cancelled) {
  916. bake_end_function(time_started);
  917. return BAKE_ERROR_USER_ABORTED;
  918. }
  919. }
  920. Error err = ResourceSaver::save(p_data_save_path, data);
  921. data->set_path(p_data_save_path);
  922. if (err != OK) {
  923. bake_end_function(time_started);
  924. return BAKE_ERROR_CANT_CREATE_IMAGE;
  925. }
  926. set_light_data(data);
  927. bake_end_function(time_started);
  928. return BAKE_ERROR_OK;
  929. }
  930. void BakedLightmap::set_capture_cell_size(float p_cell_size) {
  931. capture_cell_size = MAX(0.1, p_cell_size);
  932. }
  933. float BakedLightmap::get_capture_cell_size() const {
  934. return capture_cell_size;
  935. }
  936. void BakedLightmap::set_extents(const Vector3 &p_extents) {
  937. extents = p_extents;
  938. update_gizmo();
  939. _change_notify("extents");
  940. }
  941. Vector3 BakedLightmap::get_extents() const {
  942. return extents;
  943. }
  944. void BakedLightmap::set_default_texels_per_unit(const float &p_bake_texels_per_unit) {
  945. default_texels_per_unit = MAX(0.0, p_bake_texels_per_unit);
  946. }
  947. float BakedLightmap::get_default_texels_per_unit() const {
  948. return default_texels_per_unit;
  949. }
  950. void BakedLightmap::set_capture_enabled(bool p_enable) {
  951. capture_enabled = p_enable;
  952. _change_notify();
  953. }
  954. bool BakedLightmap::get_capture_enabled() const {
  955. return capture_enabled;
  956. }
  957. void BakedLightmap::_notification(int p_what) {
  958. if (p_what == NOTIFICATION_READY) {
  959. if (light_data.is_valid()) {
  960. _assign_lightmaps();
  961. }
  962. request_ready(); //will need ready again if re-enters tree
  963. }
  964. if (p_what == NOTIFICATION_EXIT_TREE) {
  965. if (light_data.is_valid()) {
  966. _clear_lightmaps();
  967. }
  968. }
  969. }
  970. void BakedLightmap::_assign_lightmaps() {
  971. ERR_FAIL_COND(!light_data.is_valid());
  972. bool atlassed_on_gles2 = false;
  973. for (int i = 0; i < light_data->get_user_count(); i++) {
  974. Ref<Resource> lightmap = light_data->get_user_lightmap(i);
  975. ERR_CONTINUE(!lightmap.is_valid());
  976. ERR_CONTINUE(!Object::cast_to<Texture>(lightmap.ptr()) && !Object::cast_to<TextureLayered>(lightmap.ptr()));
  977. Node *node = get_node(light_data->get_user_path(i));
  978. int instance_idx = light_data->get_user_instance(i);
  979. if (instance_idx >= 0) {
  980. RID instance = node->call("get_bake_mesh_instance", instance_idx);
  981. if (instance.is_valid()) {
  982. int slice = light_data->get_user_lightmap_slice(i);
  983. atlassed_on_gles2 = atlassed_on_gles2 || (slice != -1 && OS::get_singleton()->get_current_video_driver() == OS::VIDEO_DRIVER_GLES2);
  984. VS::get_singleton()->instance_set_use_lightmap(instance, get_instance(), lightmap->get_rid(), slice, light_data->get_user_lightmap_uv_rect(i));
  985. }
  986. } else {
  987. VisualInstance *vi = Object::cast_to<VisualInstance>(node);
  988. ERR_CONTINUE(!vi);
  989. int slice = light_data->get_user_lightmap_slice(i);
  990. atlassed_on_gles2 = atlassed_on_gles2 || (slice != -1 && OS::get_singleton()->get_current_video_driver() == OS::VIDEO_DRIVER_GLES2);
  991. VS::get_singleton()->instance_set_use_lightmap(vi->get_instance(), get_instance(), lightmap->get_rid(), slice, light_data->get_user_lightmap_uv_rect(i));
  992. }
  993. }
  994. if (atlassed_on_gles2) {
  995. ERR_PRINT("GLES2 doesn't support layered textures, so lightmap atlassing is not supported. Please re-bake the lightmap or switch to GLES3.");
  996. }
  997. }
  998. void BakedLightmap::_clear_lightmaps() {
  999. ERR_FAIL_COND(!light_data.is_valid());
  1000. for (int i = 0; i < light_data->get_user_count(); i++) {
  1001. Node *node = get_node(light_data->get_user_path(i));
  1002. int instance_idx = light_data->get_user_instance(i);
  1003. if (instance_idx >= 0) {
  1004. RID instance = node->call("get_bake_mesh_instance", instance_idx);
  1005. if (instance.is_valid()) {
  1006. VS::get_singleton()->instance_set_use_lightmap(instance, get_instance(), RID(), -1, Rect2(0, 0, 1, 1));
  1007. }
  1008. } else {
  1009. VisualInstance *vi = Object::cast_to<VisualInstance>(node);
  1010. ERR_CONTINUE(!vi);
  1011. VS::get_singleton()->instance_set_use_lightmap(vi->get_instance(), get_instance(), RID(), -1, Rect2(0, 0, 1, 1));
  1012. }
  1013. }
  1014. }
  1015. Ref<Image> BakedLightmap::_get_irradiance_from_sky(Ref<Sky> p_sky, float p_energy, Vector2i p_size) {
  1016. if (p_sky.is_null()) {
  1017. return Ref<Image>();
  1018. }
  1019. Ref<Image> sky_image;
  1020. Ref<PanoramaSky> panorama = p_sky;
  1021. if (panorama.is_valid()) {
  1022. sky_image = panorama->get_panorama()->get_data();
  1023. }
  1024. Ref<ProceduralSky> procedural = p_sky;
  1025. if (procedural.is_valid()) {
  1026. sky_image = procedural->get_data();
  1027. }
  1028. if (sky_image.is_null()) {
  1029. return Ref<Image>();
  1030. }
  1031. sky_image->convert(Image::FORMAT_RGBF);
  1032. sky_image->resize(p_size.x, p_size.y, Image::INTERPOLATE_CUBIC);
  1033. if (p_energy != 1.0) {
  1034. sky_image->lock();
  1035. for (int i = 0; i < p_size.y; i++) {
  1036. for (int j = 0; j < p_size.x; j++) {
  1037. sky_image->set_pixel(j, i, sky_image->get_pixel(j, i) * p_energy);
  1038. }
  1039. }
  1040. sky_image->unlock();
  1041. }
  1042. return sky_image;
  1043. }
  1044. Ref<Image> BakedLightmap::_get_irradiance_map(Ref<Environment> p_env, Vector2i p_size) {
  1045. Environment::BGMode bg_mode = p_env->get_background();
  1046. switch (bg_mode) {
  1047. case Environment::BG_SKY: {
  1048. return _get_irradiance_from_sky(p_env->get_sky(), p_env->get_bg_energy(), Vector2i(128, 64));
  1049. }
  1050. case Environment::BG_CLEAR_COLOR:
  1051. case Environment::BG_COLOR: {
  1052. Color c = bg_mode == Environment::BG_CLEAR_COLOR ? Color(GLOBAL_GET("rendering/environment/default_clear_color")) : p_env->get_bg_color();
  1053. c.r *= p_env->get_bg_energy();
  1054. c.g *= p_env->get_bg_energy();
  1055. c.b *= p_env->get_bg_energy();
  1056. Ref<Image> ret;
  1057. ret.instance();
  1058. ret->create(p_size.x, p_size.y, false, Image::FORMAT_RGBF);
  1059. ret->fill(c);
  1060. return ret;
  1061. }
  1062. default: {
  1063. }
  1064. }
  1065. return Ref<Image>();
  1066. }
  1067. void BakedLightmap::set_light_data(const Ref<BakedLightmapData> &p_data) {
  1068. if (light_data.is_valid()) {
  1069. if (is_inside_tree()) {
  1070. _clear_lightmaps();
  1071. }
  1072. set_base(RID());
  1073. }
  1074. light_data = p_data;
  1075. _change_notify();
  1076. if (light_data.is_valid()) {
  1077. set_base(light_data->get_rid());
  1078. if (is_inside_tree()) {
  1079. _assign_lightmaps();
  1080. }
  1081. }
  1082. }
  1083. Ref<BakedLightmapData> BakedLightmap::get_light_data() const {
  1084. return light_data;
  1085. }
  1086. void BakedLightmap::set_capture_propagation(float p_propagation) {
  1087. capture_propagation = p_propagation;
  1088. }
  1089. float BakedLightmap::get_capture_propagation() const {
  1090. return capture_propagation;
  1091. }
  1092. void BakedLightmap::set_capture_quality(BakeQuality p_quality) {
  1093. capture_quality = p_quality;
  1094. }
  1095. BakedLightmap::BakeQuality BakedLightmap::get_capture_quality() const {
  1096. return capture_quality;
  1097. }
  1098. void BakedLightmap::set_generate_atlas(bool p_enabled) {
  1099. generate_atlas = p_enabled;
  1100. }
  1101. bool BakedLightmap::is_generate_atlas_enabled() const {
  1102. return generate_atlas;
  1103. }
  1104. void BakedLightmap::set_max_atlas_size(int p_size) {
  1105. ERR_FAIL_COND(p_size < 2048);
  1106. max_atlas_size = p_size;
  1107. }
  1108. int BakedLightmap::get_max_atlas_size() const {
  1109. return max_atlas_size;
  1110. }
  1111. void BakedLightmap::set_bake_quality(BakeQuality p_quality) {
  1112. bake_quality = p_quality;
  1113. _change_notify();
  1114. }
  1115. BakedLightmap::BakeQuality BakedLightmap::get_bake_quality() const {
  1116. return bake_quality;
  1117. }
  1118. #ifndef DISABLE_DEPRECATED
  1119. void BakedLightmap::set_image_path(const String &p_path) {
  1120. image_path = p_path;
  1121. }
  1122. String BakedLightmap::get_image_path() const {
  1123. return image_path;
  1124. }
  1125. #endif
  1126. void BakedLightmap::set_use_denoiser(bool p_enable) {
  1127. use_denoiser = p_enable;
  1128. }
  1129. bool BakedLightmap::is_using_denoiser() const {
  1130. return use_denoiser;
  1131. }
  1132. void BakedLightmap::set_use_hdr(bool p_enable) {
  1133. use_hdr = p_enable;
  1134. }
  1135. bool BakedLightmap::is_using_hdr() const {
  1136. return use_hdr;
  1137. }
  1138. void BakedLightmap::set_use_color(bool p_enable) {
  1139. use_color = p_enable;
  1140. }
  1141. bool BakedLightmap::is_using_color() const {
  1142. return use_color;
  1143. }
  1144. void BakedLightmap::set_environment_mode(EnvironmentMode p_mode) {
  1145. environment_mode = p_mode;
  1146. _change_notify();
  1147. }
  1148. BakedLightmap::EnvironmentMode BakedLightmap::get_environment_mode() const {
  1149. return environment_mode;
  1150. }
  1151. void BakedLightmap::set_environment_custom_sky(const Ref<Sky> &p_sky) {
  1152. environment_custom_sky = p_sky;
  1153. }
  1154. Ref<Sky> BakedLightmap::get_environment_custom_sky() const {
  1155. return environment_custom_sky;
  1156. }
  1157. void BakedLightmap::set_environment_custom_sky_rotation_degrees(const Vector3 &p_rotation) {
  1158. environment_custom_sky_rotation_degrees = p_rotation;
  1159. }
  1160. Vector3 BakedLightmap::get_environment_custom_sky_rotation_degrees() const {
  1161. return environment_custom_sky_rotation_degrees;
  1162. }
  1163. void BakedLightmap::set_environment_custom_color(const Color &p_color) {
  1164. environment_custom_color = p_color;
  1165. }
  1166. Color BakedLightmap::get_environment_custom_color() const {
  1167. return environment_custom_color;
  1168. }
  1169. void BakedLightmap::set_environment_custom_energy(float p_energy) {
  1170. environment_custom_energy = p_energy;
  1171. }
  1172. float BakedLightmap::get_environment_custom_energy() const {
  1173. return environment_custom_energy;
  1174. }
  1175. void BakedLightmap::set_environment_min_light(Color p_min_light) {
  1176. environment_min_light = p_min_light;
  1177. }
  1178. Color BakedLightmap::get_environment_min_light() const {
  1179. return environment_min_light;
  1180. }
  1181. void BakedLightmap::set_bounces(int p_bounces) {
  1182. ERR_FAIL_COND(p_bounces < 0 || p_bounces > 16);
  1183. bounces = p_bounces;
  1184. }
  1185. int BakedLightmap::get_bounces() const {
  1186. return bounces;
  1187. }
  1188. void BakedLightmap::set_bounce_indirect_energy(float p_indirect_energy) {
  1189. ERR_FAIL_COND(p_indirect_energy < 0.0);
  1190. bounce_indirect_energy = p_indirect_energy;
  1191. }
  1192. float BakedLightmap::get_bounce_indirect_energy() const {
  1193. return bounce_indirect_energy;
  1194. }
  1195. void BakedLightmap::set_bias(float p_bias) {
  1196. ERR_FAIL_COND(p_bias < 0.00001f);
  1197. bias = p_bias;
  1198. }
  1199. float BakedLightmap::get_bias() const {
  1200. return bias;
  1201. }
  1202. AABB BakedLightmap::get_aabb() const {
  1203. return AABB(-extents, extents * 2);
  1204. }
  1205. PoolVector<Face3> BakedLightmap::get_faces(uint32_t p_usage_flags) const {
  1206. return PoolVector<Face3>();
  1207. }
  1208. void BakedLightmap::_validate_property(PropertyInfo &property) const {
  1209. if (property.name.begins_with("environment_custom_sky") && environment_mode != ENVIRONMENT_MODE_CUSTOM_SKY) {
  1210. property.usage = 0;
  1211. }
  1212. if (property.name == "environment_custom_color" && environment_mode != ENVIRONMENT_MODE_CUSTOM_COLOR) {
  1213. property.usage = 0;
  1214. }
  1215. if (property.name == "environment_custom_energy" && environment_mode != ENVIRONMENT_MODE_CUSTOM_COLOR && environment_mode != ENVIRONMENT_MODE_CUSTOM_SKY) {
  1216. property.usage = 0;
  1217. }
  1218. if (property.name.begins_with("atlas") && OS::get_singleton()->get_current_video_driver() == OS::VIDEO_DRIVER_GLES2) {
  1219. property.usage = PROPERTY_USAGE_NOEDITOR;
  1220. }
  1221. if (property.name.begins_with("capture") && property.name != "capture_enabled" && !capture_enabled) {
  1222. property.usage = 0;
  1223. }
  1224. }
  1225. void BakedLightmap::_bind_methods() {
  1226. ClassDB::bind_method(D_METHOD("set_light_data", "data"), &BakedLightmap::set_light_data);
  1227. ClassDB::bind_method(D_METHOD("get_light_data"), &BakedLightmap::get_light_data);
  1228. ClassDB::bind_method(D_METHOD("set_bake_quality", "quality"), &BakedLightmap::set_bake_quality);
  1229. ClassDB::bind_method(D_METHOD("get_bake_quality"), &BakedLightmap::get_bake_quality);
  1230. ClassDB::bind_method(D_METHOD("set_bounces", "bounces"), &BakedLightmap::set_bounces);
  1231. ClassDB::bind_method(D_METHOD("get_bounces"), &BakedLightmap::get_bounces);
  1232. ClassDB::bind_method(D_METHOD("set_bounce_indirect_energy", "bounce_indirect_energy"), &BakedLightmap::set_bounce_indirect_energy);
  1233. ClassDB::bind_method(D_METHOD("get_bounce_indirect_energy"), &BakedLightmap::get_bounce_indirect_energy);
  1234. ClassDB::bind_method(D_METHOD("set_bias", "bias"), &BakedLightmap::set_bias);
  1235. ClassDB::bind_method(D_METHOD("get_bias"), &BakedLightmap::get_bias);
  1236. ClassDB::bind_method(D_METHOD("set_environment_mode", "mode"), &BakedLightmap::set_environment_mode);
  1237. ClassDB::bind_method(D_METHOD("get_environment_mode"), &BakedLightmap::get_environment_mode);
  1238. ClassDB::bind_method(D_METHOD("set_environment_custom_sky", "sky"), &BakedLightmap::set_environment_custom_sky);
  1239. ClassDB::bind_method(D_METHOD("get_environment_custom_sky"), &BakedLightmap::get_environment_custom_sky);
  1240. ClassDB::bind_method(D_METHOD("set_environment_custom_sky_rotation_degrees", "rotation"), &BakedLightmap::set_environment_custom_sky_rotation_degrees);
  1241. ClassDB::bind_method(D_METHOD("get_environment_custom_sky_rotation_degrees"), &BakedLightmap::get_environment_custom_sky_rotation_degrees);
  1242. ClassDB::bind_method(D_METHOD("set_environment_custom_color", "color"), &BakedLightmap::set_environment_custom_color);
  1243. ClassDB::bind_method(D_METHOD("get_environment_custom_color"), &BakedLightmap::get_environment_custom_color);
  1244. ClassDB::bind_method(D_METHOD("set_environment_custom_energy", "energy"), &BakedLightmap::set_environment_custom_energy);
  1245. ClassDB::bind_method(D_METHOD("get_environment_custom_energy"), &BakedLightmap::get_environment_custom_energy);
  1246. ClassDB::bind_method(D_METHOD("set_environment_min_light", "min_light"), &BakedLightmap::set_environment_min_light);
  1247. ClassDB::bind_method(D_METHOD("get_environment_min_light"), &BakedLightmap::get_environment_min_light);
  1248. ClassDB::bind_method(D_METHOD("set_use_denoiser", "use_denoiser"), &BakedLightmap::set_use_denoiser);
  1249. ClassDB::bind_method(D_METHOD("is_using_denoiser"), &BakedLightmap::is_using_denoiser);
  1250. ClassDB::bind_method(D_METHOD("set_use_hdr", "use_denoiser"), &BakedLightmap::set_use_hdr);
  1251. ClassDB::bind_method(D_METHOD("is_using_hdr"), &BakedLightmap::is_using_hdr);
  1252. ClassDB::bind_method(D_METHOD("set_use_color", "use_denoiser"), &BakedLightmap::set_use_color);
  1253. ClassDB::bind_method(D_METHOD("is_using_color"), &BakedLightmap::is_using_color);
  1254. ClassDB::bind_method(D_METHOD("set_generate_atlas", "enabled"), &BakedLightmap::set_generate_atlas);
  1255. ClassDB::bind_method(D_METHOD("is_generate_atlas_enabled"), &BakedLightmap::is_generate_atlas_enabled);
  1256. ClassDB::bind_method(D_METHOD("set_max_atlas_size", "max_atlas_size"), &BakedLightmap::set_max_atlas_size);
  1257. ClassDB::bind_method(D_METHOD("get_max_atlas_size"), &BakedLightmap::get_max_atlas_size);
  1258. ClassDB::bind_method(D_METHOD("set_capture_quality", "capture_quality"), &BakedLightmap::set_capture_quality);
  1259. ClassDB::bind_method(D_METHOD("get_capture_quality"), &BakedLightmap::get_capture_quality);
  1260. ClassDB::bind_method(D_METHOD("set_extents", "extents"), &BakedLightmap::set_extents);
  1261. ClassDB::bind_method(D_METHOD("get_extents"), &BakedLightmap::get_extents);
  1262. ClassDB::bind_method(D_METHOD("set_default_texels_per_unit", "texels"), &BakedLightmap::set_default_texels_per_unit);
  1263. ClassDB::bind_method(D_METHOD("get_default_texels_per_unit"), &BakedLightmap::get_default_texels_per_unit);
  1264. ClassDB::bind_method(D_METHOD("set_capture_propagation", "propagation"), &BakedLightmap::set_capture_propagation);
  1265. ClassDB::bind_method(D_METHOD("get_capture_propagation"), &BakedLightmap::get_capture_propagation);
  1266. ClassDB::bind_method(D_METHOD("set_capture_enabled", "enabled"), &BakedLightmap::set_capture_enabled);
  1267. ClassDB::bind_method(D_METHOD("get_capture_enabled"), &BakedLightmap::get_capture_enabled);
  1268. ClassDB::bind_method(D_METHOD("set_capture_cell_size", "capture_cell_size"), &BakedLightmap::set_capture_cell_size);
  1269. ClassDB::bind_method(D_METHOD("get_capture_cell_size"), &BakedLightmap::get_capture_cell_size);
  1270. #ifndef DISABLE_DEPRECATED
  1271. ClassDB::bind_method(D_METHOD("set_image_path", "image_path"), &BakedLightmap::set_image_path);
  1272. ClassDB::bind_method(D_METHOD("get_image_path"), &BakedLightmap::get_image_path);
  1273. #endif
  1274. ClassDB::bind_method(D_METHOD("bake", "from_node", "data_save_path"), &BakedLightmap::bake, DEFVAL(Variant()), DEFVAL(""));
  1275. ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "extents"), "set_extents", "get_extents");
  1276. ADD_GROUP("Tweaks", "");
  1277. ADD_PROPERTY(PropertyInfo(Variant::INT, "quality", PROPERTY_HINT_ENUM, "Low,Medium,High,Ultra"), "set_bake_quality", "get_bake_quality");
  1278. ADD_PROPERTY(PropertyInfo(Variant::INT, "bounces", PROPERTY_HINT_RANGE, "0,16,1"), "set_bounces", "get_bounces");
  1279. ADD_PROPERTY(PropertyInfo(Variant::REAL, "bounce_indirect_energy", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_bounce_indirect_energy", "get_bounce_indirect_energy");
  1280. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_denoiser"), "set_use_denoiser", "is_using_denoiser");
  1281. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_hdr"), "set_use_hdr", "is_using_hdr");
  1282. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_color"), "set_use_color", "is_using_color");
  1283. ADD_PROPERTY(PropertyInfo(Variant::REAL, "bias", PROPERTY_HINT_RANGE, "0.00001,0.1,0.00001,or_greater"), "set_bias", "get_bias");
  1284. ADD_PROPERTY(PropertyInfo(Variant::REAL, "default_texels_per_unit", PROPERTY_HINT_RANGE, "0.0,64.0,0.01,or_greater"), "set_default_texels_per_unit", "get_default_texels_per_unit");
  1285. ADD_GROUP("Atlas", "atlas_");
  1286. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "atlas_generate"), "set_generate_atlas", "is_generate_atlas_enabled");
  1287. ADD_PROPERTY(PropertyInfo(Variant::INT, "atlas_max_size"), "set_max_atlas_size", "get_max_atlas_size");
  1288. ADD_GROUP("Environment", "environment_");
  1289. ADD_PROPERTY(PropertyInfo(Variant::INT, "environment_mode", PROPERTY_HINT_ENUM, "Disabled,Scene,Custom Sky,Custom Color"), "set_environment_mode", "get_environment_mode");
  1290. ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "environment_custom_sky", PROPERTY_HINT_RESOURCE_TYPE, "Sky"), "set_environment_custom_sky", "get_environment_custom_sky");
  1291. ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "environment_custom_sky_rotation_degrees", PROPERTY_HINT_NONE), "set_environment_custom_sky_rotation_degrees", "get_environment_custom_sky_rotation_degrees");
  1292. ADD_PROPERTY(PropertyInfo(Variant::COLOR, "environment_custom_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_environment_custom_color", "get_environment_custom_color");
  1293. ADD_PROPERTY(PropertyInfo(Variant::REAL, "environment_custom_energy", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_environment_custom_energy", "get_environment_custom_energy");
  1294. ADD_PROPERTY(PropertyInfo(Variant::COLOR, "environment_min_light", PROPERTY_HINT_COLOR_NO_ALPHA), "set_environment_min_light", "get_environment_min_light");
  1295. ADD_GROUP("Capture", "capture_");
  1296. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "capture_enabled"), "set_capture_enabled", "get_capture_enabled");
  1297. ADD_PROPERTY(PropertyInfo(Variant::REAL, "capture_cell_size", PROPERTY_HINT_RANGE, "0.25,2.0,0.05,or_greater"), "set_capture_cell_size", "get_capture_cell_size");
  1298. ADD_PROPERTY(PropertyInfo(Variant::INT, "capture_quality", PROPERTY_HINT_ENUM, "Low,Medium,High"), "set_capture_quality", "get_capture_quality");
  1299. ADD_PROPERTY(PropertyInfo(Variant::REAL, "capture_propagation", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_capture_propagation", "get_capture_propagation");
  1300. ADD_GROUP("Data", "");
  1301. #ifndef DISABLE_DEPRECATED
  1302. ADD_PROPERTY(PropertyInfo(Variant::STRING, "image_path", PROPERTY_HINT_DIR, "", 0), "set_image_path", "get_image_path");
  1303. #endif
  1304. ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "light_data", PROPERTY_HINT_RESOURCE_TYPE, "BakedLightmapData"), "set_light_data", "get_light_data");
  1305. BIND_ENUM_CONSTANT(BAKE_QUALITY_LOW);
  1306. BIND_ENUM_CONSTANT(BAKE_QUALITY_MEDIUM);
  1307. BIND_ENUM_CONSTANT(BAKE_QUALITY_HIGH);
  1308. BIND_ENUM_CONSTANT(BAKE_QUALITY_ULTRA);
  1309. BIND_ENUM_CONSTANT(BAKE_ERROR_OK);
  1310. BIND_ENUM_CONSTANT(BAKE_ERROR_NO_SAVE_PATH);
  1311. BIND_ENUM_CONSTANT(BAKE_ERROR_NO_MESHES);
  1312. BIND_ENUM_CONSTANT(BAKE_ERROR_CANT_CREATE_IMAGE);
  1313. BIND_ENUM_CONSTANT(BAKE_ERROR_LIGHTMAP_SIZE);
  1314. BIND_ENUM_CONSTANT(BAKE_ERROR_INVALID_MESH);
  1315. BIND_ENUM_CONSTANT(BAKE_ERROR_USER_ABORTED);
  1316. BIND_ENUM_CONSTANT(BAKE_ERROR_NO_LIGHTMAPPER);
  1317. BIND_ENUM_CONSTANT(BAKE_ERROR_NO_ROOT);
  1318. BIND_ENUM_CONSTANT(ENVIRONMENT_MODE_DISABLED);
  1319. BIND_ENUM_CONSTANT(ENVIRONMENT_MODE_SCENE);
  1320. BIND_ENUM_CONSTANT(ENVIRONMENT_MODE_CUSTOM_SKY);
  1321. BIND_ENUM_CONSTANT(ENVIRONMENT_MODE_CUSTOM_COLOR);
  1322. }
  1323. BakedLightmap::BakedLightmap() {
  1324. extents = Vector3(10, 10, 10);
  1325. default_texels_per_unit = 16.0f;
  1326. bake_quality = BAKE_QUALITY_MEDIUM;
  1327. capture_quality = BAKE_QUALITY_MEDIUM;
  1328. capture_propagation = 1;
  1329. capture_enabled = true;
  1330. bounces = 3;
  1331. bounce_indirect_energy = 1.0;
  1332. image_path = "";
  1333. set_disable_scale(true);
  1334. capture_cell_size = 0.5;
  1335. environment_mode = ENVIRONMENT_MODE_DISABLED;
  1336. environment_custom_color = Color(0.2, 0.7, 1.0);
  1337. environment_custom_energy = 1.0;
  1338. environment_min_light = Color(0.0, 0.0, 0.0);
  1339. use_denoiser = true;
  1340. use_hdr = true;
  1341. use_color = true;
  1342. bias = 0.005;
  1343. generate_atlas = true;
  1344. max_atlas_size = 4096;
  1345. }