diff options
-rw-r--r-- | scene/3d/baked_lightmap.cpp | 20 | ||||
-rw-r--r-- | scene/3d/baked_lightmap.h | 4 | ||||
-rw-r--r-- | scene/3d/voxel_light_baker.cpp | 75 | ||||
-rw-r--r-- | scene/3d/voxel_light_baker.h | 2 |
4 files changed, 91 insertions, 10 deletions
diff --git a/scene/3d/baked_lightmap.cpp b/scene/3d/baked_lightmap.cpp index 2b12e78158..c5ff4dadbc 100644 --- a/scene/3d/baked_lightmap.cpp +++ b/scene/3d/baked_lightmap.cpp @@ -221,6 +221,15 @@ Vector3 BakedLightmap::get_extents() const { return extents; } +void BakedLightmap::set_bake_default_texels_per_unit(const float &p_bake_texels_per_unit) { + bake_default_texels_per_unit = p_bake_texels_per_unit; + update_gizmo(); +} + +float BakedLightmap::get_bake_default_texels_per_unit() const { + return bake_default_texels_per_unit; +} + void BakedLightmap::_find_meshes_and_lights(Node *p_at_node, List<PlotMesh> &plot_meshes, List<PlotLight> &plot_lights) { MeshInstance *mi = Object::cast_to<MeshInstance>(p_at_node); @@ -236,7 +245,7 @@ void BakedLightmap::_find_meshes_and_lights(Node *p_at_node, List<PlotMesh> &plo } } - if (all_have_uv2 && mesh->get_lightmap_size_hint() != Size2()) { + if (all_have_uv2) { //READY TO BAKE! size hint could be computed if not found, actually.. AABB aabb = mesh->get_aabb(); @@ -463,7 +472,7 @@ BakedLightmap::BakeError BakedLightmap::bake(Node *p_from_node, bool p_create_vi btd.text = RTR("Lighting Meshes: ") + mesh_name + " (" + itos(pmc) + "/" + itos(mesh_list.size()) + ")"; btd.pass = step; btd.last_step = 0; - err = baker.make_lightmap(E->get().local_xform, E->get().mesh, lm, _bake_time, &btd); + err = baker.make_lightmap(E->get().local_xform, E->get().mesh, bake_default_texels_per_unit, lm, _bake_time, &btd); if (err != OK) { bake_end_function(); if (err == ERR_SKIP) @@ -473,7 +482,7 @@ BakedLightmap::BakeError BakedLightmap::bake(Node *p_from_node, bool p_create_vi step += 100; } else { - err = baker.make_lightmap(E->get().local_xform, E->get().mesh, lm); + err = baker.make_lightmap(E->get().local_xform, E->get().mesh, bake_default_texels_per_unit, lm); } if (err == OK) { @@ -790,6 +799,9 @@ void BakedLightmap::_bind_methods() { ClassDB::bind_method(D_METHOD("set_extents", "extents"), &BakedLightmap::set_extents); ClassDB::bind_method(D_METHOD("get_extents"), &BakedLightmap::get_extents); + ClassDB::bind_method(D_METHOD("set_bake_default_texels_per_unit", "texels"), &BakedLightmap::set_bake_default_texels_per_unit); + ClassDB::bind_method(D_METHOD("get_bake_default_texels_per_unit"), &BakedLightmap::get_bake_default_texels_per_unit); + ClassDB::bind_method(D_METHOD("set_propagation", "propagation"), &BakedLightmap::set_propagation); ClassDB::bind_method(D_METHOD("get_propagation"), &BakedLightmap::get_propagation); @@ -814,6 +826,7 @@ void BakedLightmap::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::REAL, "bake_energy", PROPERTY_HINT_RANGE, "0,32,0.01"), "set_energy", "get_energy"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "bake_hdr"), "set_hdr", "is_hdr"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "bake_extents"), "set_extents", "get_extents"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "bake_default_texels_per_unit"), "set_bake_default_texels_per_unit", "get_bake_default_texels_per_unit"); ADD_GROUP("Capture", "capture_"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "capture_cell_size", PROPERTY_HINT_RANGE, "0.01,64,0.01"), "set_capture_cell_size", "get_capture_cell_size"); ADD_GROUP("Data", ""); @@ -836,6 +849,7 @@ void BakedLightmap::_bind_methods() { BakedLightmap::BakedLightmap() { extents = Vector3(10, 10, 10); + bake_default_texels_per_unit = 20; bake_cell_size = 0.25; capture_cell_size = 0.5; diff --git a/scene/3d/baked_lightmap.h b/scene/3d/baked_lightmap.h index bb3f84719a..fac4ad3908 100644 --- a/scene/3d/baked_lightmap.h +++ b/scene/3d/baked_lightmap.h @@ -119,6 +119,7 @@ private: float bake_cell_size; float capture_cell_size; Vector3 extents; + float bake_default_texels_per_unit; float propagation; float energy; BakeQuality bake_quality; @@ -178,6 +179,9 @@ public: void set_extents(const Vector3 &p_extents); Vector3 get_extents() const; + void set_bake_default_texels_per_unit(const float &p_extents); + float get_bake_default_texels_per_unit() const; + void set_propagation(float p_propagation); float get_propagation() const; diff --git a/scene/3d/voxel_light_baker.cpp b/scene/3d/voxel_light_baker.cpp index 75b419ca58..001d70dae9 100644 --- a/scene/3d/voxel_light_baker.cpp +++ b/scene/3d/voxel_light_baker.cpp @@ -1794,19 +1794,82 @@ void VoxelLightBaker::_lightmap_bake_point(uint32_t p_x, LightMap *p_line) { } } -Error VoxelLightBaker::make_lightmap(const Transform &p_xform, Ref<Mesh> &p_mesh, LightMapData &r_lightmap, bool (*p_bake_time_func)(void *, float, float), void *p_bake_time_ud) { +Error VoxelLightBaker::make_lightmap(const Transform &p_xform, Ref<Mesh> &p_mesh, float default_texels_per_unit, LightMapData &r_lightmap, bool (*p_bake_time_func)(void *, float, float), void *p_bake_time_ud) { //transfer light information to a lightmap Ref<Mesh> mesh = p_mesh; - int width = mesh->get_lightmap_size_hint().x; - int height = mesh->get_lightmap_size_hint().y; - //step 1 - create lightmap + int width; + int height; Vector<LightMap> lightmap; - lightmap.resize(width * height); - Transform xform = to_cell_space * p_xform; + if (mesh->get_lightmap_size_hint() == Size2()) { + double area = 0; + double uv_area = 0; + for (int i = 0; i < mesh->get_surface_count(); i++) { + Array arrays = mesh->surface_get_arrays(i); + PoolVector<Vector3> vertices = arrays[Mesh::ARRAY_VERTEX]; + PoolVector<Vector2> uv2 = arrays[Mesh::ARRAY_TEX_UV2]; + PoolVector<int> indices = arrays[Mesh::ARRAY_INDEX]; + + ERR_FAIL_COND_V(vertices.size() == 0, ERR_INVALID_PARAMETER); + ERR_FAIL_COND_V(uv2.size() == 0, ERR_INVALID_PARAMETER); + + int vc = vertices.size(); + PoolVector<Vector3>::Read vr = vertices.read(); + PoolVector<Vector2>::Read u2r = uv2.read(); + PoolVector<int>::Read ir; + int ic = 0; + + if (indices.size()) { + ic = indices.size(); + ir = indices.read(); + } + + int faces = ic ? ic / 3 : vc / 3; + for (int j = 0; j < faces; j++) { + Vector3 vertex[3]; + Vector2 uv[3]; + + for (int k = 0; k < 3; k++) { + int idx = ic ? ir[j * 3 + k] : j * 3 + k; + vertex[k] = xform.xform(vr[idx]); + uv[k] = u2r[idx]; + } + + Vector3 p1 = vertex[0]; + Vector3 p2 = vertex[1]; + Vector3 p3 = vertex[2]; + double a = p1.distance_to(p2); + double b = p2.distance_to(p3); + double c = p3.distance_to(p1); + double halfPerimeter = (a + b + c) / 2.0; + area += sqrt(halfPerimeter * (halfPerimeter - a) * (halfPerimeter - b) * (halfPerimeter - c)); + + Vector2 uv_p1 = uv[0]; + Vector2 uv_p2 = uv[1]; + Vector2 uv_p3 = uv[2]; + double uv_a = uv_p1.distance_to(uv_p2); + double uv_b = uv_p2.distance_to(uv_p3); + double uv_c = uv_p3.distance_to(uv_p1); + double uv_halfPerimeter = (uv_a + uv_b + uv_c) / 2.0; + uv_area += sqrt(uv_halfPerimeter * (uv_halfPerimeter - uv_a) * (uv_halfPerimeter - uv_b) * (uv_halfPerimeter - uv_c)); + } + } + + if (uv_area < 0.0001f) { + uv_area = 1.0; + } + + int pixels = (ceil((1.0 / sqrt(uv_area)) * sqrt(area * default_texels_per_unit))); + width = height = CLAMP(pixels, 2, 4096); + } else { + width = mesh->get_lightmap_size_hint().x; + height = mesh->get_lightmap_size_hint().y; + } + + lightmap.resize(width * height); //step 2 plot faces to lightmap for (int i = 0; i < mesh->get_surface_count(); i++) { diff --git a/scene/3d/voxel_light_baker.h b/scene/3d/voxel_light_baker.h index 295e099d47..2e2efc62ff 100644 --- a/scene/3d/voxel_light_baker.h +++ b/scene/3d/voxel_light_baker.h @@ -177,7 +177,7 @@ public: PoolVector<float> light; }; - Error make_lightmap(const Transform &p_xform, Ref<Mesh> &p_mesh, LightMapData &r_lightmap, bool (*p_bake_time_func)(void *, float, float) = NULL, void *p_bake_time_ud = NULL); + Error make_lightmap(const Transform &p_xform, Ref<Mesh> &p_mesh, float default_texels_per_unit, LightMapData &r_lightmap, bool (*p_bake_time_func)(void *, float, float) = NULL, void *p_bake_time_ud = NULL); PoolVector<int> create_gi_probe_data(); Ref<MultiMesh> create_debug_multimesh(DebugMode p_mode = DEBUG_ALBEDO); |