From 9347548001b7e31929d7f8465d6d6db6f93a91e2 Mon Sep 17 00:00:00 2001 From: Hans-Kristian Arntzen Date: Tue, 5 Jun 2018 23:28:27 +0200 Subject: [PATCH] Move over to the new KHR_lights. --- application/application.cpp | 6 ++-- renderer/lights/lights.hpp | 4 +++ renderer/scene.cpp | 4 ++- scene_formats/gltf.cpp | 62 ++++++++++++++++----------------- scene_formats/gltf_export.cpp | 51 +++++++++++++-------------- scene_formats/light_export.cpp | 8 ++--- scene_formats/scene_formats.hpp | 2 +- tools/gltf_repacker.cpp | 4 +-- 8 files changed, 69 insertions(+), 72 deletions(-) diff --git a/application/application.cpp b/application/application.cpp index ad1fb0f04..308decb7d 100644 --- a/application/application.cpp +++ b/application/application.cpp @@ -388,8 +388,7 @@ bool SceneViewerApplication::on_key_down(const KeyboardEvent &e) light.type = SceneFormats::LightInfo::Type::Spot; light.outer_cone = 0.9f; light.inner_cone = 0.92f; - light.quadratic_falloff = 0.1f; - light.color = vec3(1.0f); + light.color = vec3(10.0f); node->transform.translation = pos; node->transform.rotation = conjugate(look_at_arbitrary_up(selected_camera->get_front())); @@ -407,8 +406,7 @@ bool SceneViewerApplication::on_key_down(const KeyboardEvent &e) SceneFormats::LightInfo light; light.type = SceneFormats::LightInfo::Type::Point; - light.quadratic_falloff = 0.1f; - light.color = vec3(1.0f); + light.color = vec3(10.0f); node->transform.translation = pos; scene.create_light(light, node.get()); diff --git a/renderer/lights/lights.hpp b/renderer/lights/lights.hpp index d35944a73..4013b6bcc 100644 --- a/renderer/lights/lights.hpp +++ b/renderer/lights/lights.hpp @@ -45,6 +45,10 @@ class PositionalLight : public AbstractRenderable } void set_maximum_range(float range); + float get_maximum_range() const + { + return cutoff_range; + } bool has_static_aabb() const override { diff --git a/renderer/scene.cpp b/renderer/scene.cpp index f669aee44..d306012f0 100644 --- a/renderer/scene.cpp +++ b/renderer/scene.cpp @@ -442,7 +442,9 @@ EntityHandle Scene::create_light(const SceneFormats::LightInfo &light, Node *nod } auto &positional = static_cast(*renderable); - positional.set_color(light.color / light.quadratic_falloff); + positional.set_color(light.color); + if (light.range > 0.0f) + positional.set_maximum_range(light.range); entity->allocate_component()->light = &positional; entity->allocate_component()->renderable = renderable; diff --git a/scene_formats/gltf.cpp b/scene_formats/gltf.cpp index a99542cae..6098bc8a0 100644 --- a/scene_formats/gltf.cpp +++ b/scene_formats/gltf.cpp @@ -620,6 +620,9 @@ void Parser::parse(const string &original_path, const string &json) Document doc; doc.Parse(json); + if (doc.HasParseError()) + throw logic_error("Parser error found."); + const auto add_buffer = [&](const Value &buf) { const char *uri = nullptr; if (buf.HasMember("uri")) @@ -1085,9 +1088,9 @@ void Parser::parse(const string &original_path, const string &json) if (value.HasMember("extensions")) { auto &ext = value["extensions"]; - if (ext.HasMember("KHR_lights_cmn")) + if (ext.HasMember("KHR_lights")) { - auto &cmn = ext["KHR_lights_cmn"]; + auto &cmn = ext["KHR_lights"]; if (cmn.HasMember("light")) { auto index = cmn["light"].GetUint(); @@ -1286,6 +1289,10 @@ void Parser::parse(const string &original_path, const string &json) if (light.HasMember("name")) info.name = light["name"].GetString(); + float intensity = 1.0f; + if (light.HasMember("intensity")) + intensity = light["intensity"].GetFloat(); + if (light.HasMember("color")) { auto &color = light["color"]; @@ -1293,6 +1300,10 @@ void Parser::parse(const string &original_path, const string &json) info.color.y = color[1].GetFloat(); info.color.z = color[2].GetFloat(); } + else + info.color = vec3(1.0f); + + info.color *= intensity; auto *type = light["type"].GetString(); if (strcmp(type, "point") == 0) @@ -1306,41 +1317,28 @@ void Parser::parse(const string &original_path, const string &json) else throw logic_error("Invalid light type."); - if (info.type == LightInfo::Type::Spot || info.type == LightInfo::Type::Point) - { - auto &pos = light["positional"]; + info.range = 0.0f; + if (light.HasMember("range")) + info.range = light["range"].GetFloat(); - if (pos.HasMember("constantAttenuation")) - { - float constant_falloff = pos["constantAttenuation"].GetFloat(); - if (constant_falloff != 0.0f) - LOGI("Constant falloff is not 0, this will be ignored.\n"); - } - - if (pos.HasMember("linearAttenuation")) - { - float linear_falloff = pos["linearAttenuation"].GetFloat(); - if (linear_falloff != 0.0f) - LOGI("Linear falloff is not 0, this will be ignored.\n"); - } - - info.quadratic_falloff = 1.0f; - if (pos.HasMember("quadraticAttenuation")) - info.quadratic_falloff = pos["quadraticAttenuation"].GetFloat(); + info.inner_cone = std::cos(0.0f); + info.outer_cone = std::cos(pi() / 4.0f); - if (pos.HasMember("spot")) + if (info.type == LightInfo::Type::Spot) + { + if (light.HasMember("spot")) { - auto &spot = pos["spot"]; - if (spot.HasMember("innerAngle")) + auto &spot = light["spot"]; + if (spot.HasMember("innerConeAngle")) { - info.inner_cone = spot["innerAngle"].GetFloat(); - info.inner_cone = std::sqrt(1.0f - info.inner_cone * info.inner_cone); + info.inner_cone = spot["innerConeAngle"].GetFloat(); + info.inner_cone = std::cos(info.inner_cone); } - if (spot.HasMember("outerAngle")) + if (spot.HasMember("outerConeAngle")) { - info.outer_cone = spot["outerAngle"].GetFloat(); - info.outer_cone = std::sqrt(1.0f - info.outer_cone * info.outer_cone); + info.outer_cone = spot["outerConeAngle"].GetFloat(); + info.outer_cone = std::cos(info.outer_cone); } } } @@ -1392,9 +1390,9 @@ void Parser::parse(const string &original_path, const string &json) if (doc.HasMember("extensions")) { auto &ext = doc["extensions"]; - if (ext.HasMember("KHR_lights_cmn") && ext["KHR_lights_cmn"].HasMember("lights")) + if (ext.HasMember("KHR_lights") && ext["KHR_lights"].HasMember("lights")) { - auto &lights = ext["KHR_lights_cmn"]["lights"]; + auto &lights = ext["KHR_lights"]["lights"]; iterate_elements(lights, add_light); } } diff --git a/scene_formats/gltf_export.cpp b/scene_formats/gltf_export.cpp index 87201f19b..2c057042a 100644 --- a/scene_formats/gltf_export.cpp +++ b/scene_formats/gltf_export.cpp @@ -1529,11 +1529,11 @@ bool export_scene_to_glb(const SceneInformation &scene, const string &path, cons if (!scene.lights.empty()) { Value req(kArrayType); - req.PushBack("KHR_lights_cmn", allocator); + req.PushBack("KHR_lights", allocator); doc.AddMember("extensionsRequired", req, allocator); Value used(kArrayType); - used.PushBack("KHR_lights_cmn", allocator); + used.PushBack("KHR_lights", allocator); doc.AddMember("extensionsUsed", used, allocator); } @@ -1585,7 +1585,7 @@ bool export_scene_to_glb(const SceneInformation &scene, const string &path, cons Value ext(kObjectType); Value cmn(kObjectType); cmn.AddMember("light", uint32_t(&light - scene.lights.data()), allocator); - ext.AddMember("KHR_lights_cmn", cmn, allocator); + ext.AddMember("KHR_lights", cmn, allocator); n.AddMember("extensions", ext, allocator); break; } @@ -2018,58 +2018,56 @@ bool export_scene_to_glb(const SceneInformation &scene, const string &path, cons if (!scene.lights.empty()) { Value ext(kObjectType); - Value lights_cmn(kObjectType); + Value khr_lights(kObjectType); Value lights(kArrayType); for (auto &light : scene.lights) { Value l(kObjectType); - Value positional(kObjectType); Value color(kArrayType); - Value spot(kObjectType); - color.PushBack(light.color.x, allocator); - color.PushBack(light.color.y, allocator); - color.PushBack(light.color.z, allocator); + float intensity = muglm::max(muglm::max(light.color.x, light.color.y), light.color.z); + if (intensity == 0.0f) + intensity = 1.0f; + + color.PushBack(light.color.x / intensity, allocator); + color.PushBack(light.color.y / intensity, allocator); + color.PushBack(light.color.z / intensity, allocator); + + if (intensity != 1.0f) + l.AddMember("intensity", intensity, allocator); l.AddMember("color", color, allocator); switch (light.type) { case LightInfo::Type::Spot: + { + Value spot(kObjectType); + spot.AddMember("innerConeAngle", muglm::acos(light.inner_cone), allocator); + spot.AddMember("outerConeAngle", muglm::acos(light.outer_cone), allocator); l.AddMember("type", "spot", allocator); - l.AddMember("profile", "CMN", allocator); - if (light.quadratic_falloff != 0.0f) - positional.AddMember("quadraticAttenuation", light.quadratic_falloff, allocator); - - spot.AddMember("innerAngle", muglm::sqrt(std::max(1.0f - light.inner_cone * light.inner_cone, 0.0f)), allocator); - spot.AddMember("outerAngle", muglm::sqrt(std::max(1.0f - light.outer_cone * light.outer_cone, 0.0f)), allocator); - positional.AddMember("spot", spot, allocator); - - l.AddMember("positional", positional, allocator); + l.AddMember("spot", spot, allocator); break; + } case LightInfo::Type::Point: l.AddMember("type", "point", allocator); - l.AddMember("profile", "CMN", allocator); - if (light.quadratic_falloff != 0.0f) - positional.AddMember("quadraticAttenuation", light.quadratic_falloff, allocator); - l.AddMember("positional", positional, allocator); break; case LightInfo::Type::Directional: l.AddMember("type", "directional", allocator); - l.AddMember("profile", "CMN", allocator); break; case LightInfo::Type::Ambient: l.AddMember("type", "ambient", allocator); + break; } lights.PushBack(l, allocator); } - lights_cmn.AddMember("lights", lights, allocator); - ext.AddMember("KHR_lights_cmn", lights_cmn, allocator); + khr_lights.AddMember("lights", lights, allocator); + ext.AddMember("KHR_lights", khr_lights, allocator); doc.AddMember("extensions", ext, allocator); } @@ -2190,7 +2188,8 @@ bool export_scene_to_glb(const SceneInformation &scene, const string &path, cons memcpy(mapped, "JSON", 4); mapped += 4; - memcpy(mapped, buffer.GetString(), buffer.GetLength()); + const char *json_str = buffer.GetString(); + memcpy(mapped, json_str, buffer.GetLength()); size_t pad_length = aligned_size(buffer.GetLength()) - buffer.GetLength(); memset(mapped + buffer.GetLength(), ' ', pad_length); mapped += aligned_size(buffer.GetLength()); diff --git a/scene_formats/light_export.cpp b/scene_formats/light_export.cpp index 1eece1f42..66de638f2 100644 --- a/scene_formats/light_export.cpp +++ b/scene_formats/light_export.cpp @@ -81,9 +81,7 @@ std::string export_lights_to_json(const DirectionalParameters &dir, Scene &scene color.PushBack(s.get_color().y, allocator); color.PushBack(s.get_color().z, allocator); spot.AddMember("color", color, allocator); - spot.AddMember("constantFalloff", 0.0f, allocator); - spot.AddMember("linearFalloff", 0.0f, allocator); - spot.AddMember("quadraticFalloff", 1.0f, allocator); + spot.AddMember("range", s.get_maximum_range(), allocator); spot.AddMember("position", pos, allocator); spot.AddMember("direction", dir, allocator); spots.PushBack(spot, allocator); @@ -97,9 +95,7 @@ std::string export_lights_to_json(const DirectionalParameters &dir, Scene &scene color.PushBack(p.get_color().y, allocator); color.PushBack(p.get_color().z, allocator); point.AddMember("color", color, allocator); - point.AddMember("constantFalloff", 0.0f, allocator); - point.AddMember("linearFalloff", 0.0f, allocator); - point.AddMember("quadraticFalloff", 1.0f, allocator); + point.AddMember("range", p.get_maximum_range(), allocator); point.AddMember("position", pos, allocator); points.PushBack(point, allocator); } diff --git a/scene_formats/scene_formats.hpp b/scene_formats/scene_formats.hpp index 4a6f3a5f9..b3f493e2a 100644 --- a/scene_formats/scene_formats.hpp +++ b/scene_formats/scene_formats.hpp @@ -207,7 +207,7 @@ struct LightInfo float inner_cone = 0.40f; float outer_cone = 0.45f; vec3 color = vec3(1.0f); - float quadratic_falloff = 1.0f; + float range = 0.0f; bool attached_to_node = false; }; diff --git a/tools/gltf_repacker.cpp b/tools/gltf_repacker.cpp index 4c675aad9..a9ff7b0da 100644 --- a/tools/gltf_repacker.cpp +++ b/tools/gltf_repacker.cpp @@ -297,7 +297,7 @@ int main(int argc, char *argv[]) light.color = vec3(color[0].GetFloat(), color[1].GetFloat(), color[2].GetFloat()); light_node.transform.rotation = conjugate(look_at_arbitrary_up(vec3(dir[0].GetFloat(), dir[1].GetFloat(), dir[2].GetFloat()))); light_node.transform.translation = vec3(pos[0].GetFloat(), pos[1].GetFloat(), pos[2].GetFloat()); - light.quadratic_falloff = spot["quadraticFalloff"].GetFloat(); + light.range = spot["range"].GetFloat(); light.outer_cone = spot["outerCone"].GetFloat(); light.inner_cone = spot["innerCone"].GetFloat(); @@ -321,7 +321,7 @@ int main(int argc, char *argv[]) light_node.transform.translation = vec3(pos[0].GetFloat(), pos[1].GetFloat(), pos[2].GetFloat()); light.color = vec3(color[0].GetFloat(), color[1].GetFloat(), color[2].GetFloat()); - light.quadratic_falloff = point["quadraticFalloff"].GetFloat(); + light.range = point["range"].GetFloat(); lights.push_back(light); nodes.push_back(light_node);