Updated lightmap baker to dynamically calculate lightmap sizes based on surface area.
This commit is contained in:
parent
05a0a68c72
commit
09737ef6a7
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue