From 331af7bf354a3323bbe6ecb8a6cc58cd097995ac Mon Sep 17 00:00:00 2001 From: Romain Guy Date: Tue, 21 Mar 2023 10:08:20 -0700 Subject: [PATCH] Add sun size and halo properties to glTF viewer controls. (#6655) This change also simplifies libviewer by removing duplicated code. --- libs/viewer/include/viewer/Settings.h | 5 ++- libs/viewer/include/viewer/ViewerGui.h | 2 -- libs/viewer/src/Settings.cpp | 14 +++++++- libs/viewer/src/ViewerGui.cpp | 45 ++++++-------------------- 4 files changed, 27 insertions(+), 39 deletions(-) diff --git a/libs/viewer/include/viewer/Settings.h b/libs/viewer/include/viewer/Settings.h index 33ff8c0ef8..4c8b0abed0 100644 --- a/libs/viewer/include/viewer/Settings.h +++ b/libs/viewer/include/viewer/Settings.h @@ -82,7 +82,7 @@ using LightManager = filament::LightManager; void applySettings(Engine* engine, const ViewSettings& settings, View* dest); void applySettings(Engine* engine, const MaterialSettings& settings, MaterialInstance* dest); void applySettings(Engine* engine, const LightSettings& settings, IndirectLight* ibl, utils::Entity sunlight, - utils::Entity* sceneLights, size_t sceneLightCount, LightManager* lm, Scene* scene, View* view); + const utils::Entity* sceneLights, size_t sceneLightCount, LightManager* lm, Scene* scene, View* view); void applySettings(Engine* engine, const ViewerOptions& settings, Camera* camera, Skybox* skybox, Renderer* renderer); @@ -204,6 +204,9 @@ struct LightSettings { LightManager::ShadowOptions shadowOptions; SoftShadowOptions softShadowOptions; float sunlightIntensity = 100000.0f; + float sunlightHaloSize = 10.0f; + float sunlightHaloFalloff = 80.0f; + float sunlightAngularRadius = 1.9f; math::float3 sunlightDirection = {0.6, -1.0, -0.8}; math::float3 sunlightColor = filament::Color::toLinear({ 0.98, 0.92, 0.89}); float iblIntensity = 30000.0f; diff --git a/libs/viewer/include/viewer/ViewerGui.h b/libs/viewer/include/viewer/ViewerGui.h index bb7c434815..76b5f3a422 100644 --- a/libs/viewer/include/viewer/ViewerGui.h +++ b/libs/viewer/include/viewer/ViewerGui.h @@ -234,8 +234,6 @@ public: private: using SceneMask = gltfio::NodeManager::SceneMask; - void updateIndirectLight(); - bool isRemoteMode() const { return mAsset == nullptr; } void sceneSelectionUI(); diff --git a/libs/viewer/src/Settings.cpp b/libs/viewer/src/Settings.cpp index ceb13cc1c3..5e4497952b 100644 --- a/libs/viewer/src/Settings.cpp +++ b/libs/viewer/src/Settings.cpp @@ -412,6 +412,12 @@ static int parse(jsmntok_t const* tokens, int i, const char* jsonChunk, LightSet i = parse(tokens, i + 1, jsonChunk, &out->softShadowOptions); } else if (compare(tok, jsonChunk, "sunlightIntensity") == 0) { i = parse(tokens, i + 1, jsonChunk, &out->sunlightIntensity); + } else if (compare(tok, jsonChunk, "sunlightHaloSize") == 0) { + i = parse(tokens, i + 1, jsonChunk, &out->sunlightHaloSize); + } else if (compare(tok, jsonChunk, "sunlightHaloFalloff") == 0) { + i = parse(tokens, i + 1, jsonChunk, &out->sunlightHaloFalloff); + } else if (compare(tok, jsonChunk, "sunlightAngularRadius") == 0) { + i = parse(tokens, i + 1, jsonChunk, &out->sunlightAngularRadius); } else if (compare(tok, jsonChunk, "sunlightDirection") == 0) { i = parse(tokens, i + 1, jsonChunk, &out->sunlightDirection); } else if (compare(tok, jsonChunk, "sunlightColor") == 0) { @@ -537,7 +543,7 @@ void applySettings(Engine* engine, const MaterialSettings& settings, MaterialIns } void applySettings(Engine* engine, const LightSettings& settings, IndirectLight* ibl, utils::Entity sunlight, - utils::Entity* sceneLights, size_t sceneLightCount, LightManager* lm, Scene* scene, View* view) { + const utils::Entity* sceneLights, size_t sceneLightCount, LightManager* lm, Scene* scene, View* view) { auto light = lm->getInstance(sunlight); if (light) { if (settings.enableSunlight) { @@ -546,6 +552,9 @@ void applySettings(Engine* engine, const LightSettings& settings, IndirectLight* scene->remove(sunlight); } lm->setIntensity(light, settings.sunlightIntensity); + lm->setSunHaloSize(light, settings.sunlightHaloSize); + lm->setSunHaloFalloff(light, settings.sunlightHaloFalloff); + lm->setSunAngularRadius(light, settings.sunlightAngularRadius); lm->setDirection(light, normalize(settings.sunlightDirection)); lm->setColor(light, settings.sunlightColor); lm->setShadowCaster(light, settings.enableShadows); @@ -765,6 +774,9 @@ static std::ostream& operator<<(std::ostream& out, const LightSettings& in) { << "\"shadowOptions\": " << (in.shadowOptions) << ",\n" << "\"softShadowOptions\": " << (in.softShadowOptions) << ",\n" << "\"sunlightIntensity\": " << (in.sunlightIntensity) << ",\n" + << "\"sunlightHaloSize\": " << (in.sunlightHaloSize) << ",\n" + << "\"sunlightHaloFalloff\": " << (in.sunlightHaloFalloff) << ",\n" + << "\"sunlightAngularRadius\": " << (in.sunlightAngularRadius) << ",\n" << "\"sunlightDirection\": " << (in.sunlightDirection) << ",\n" << "\"sunlightColor\": " << (in.sunlightColor) << ",\n" << "\"iblIntensity\": " << (in.iblIntensity) << ",\n" diff --git a/libs/viewer/src/ViewerGui.cpp b/libs/viewer/src/ViewerGui.cpp index c7cdb257a0..0964989bf3 100644 --- a/libs/viewer/src/ViewerGui.cpp +++ b/libs/viewer/src/ViewerGui.cpp @@ -382,9 +382,9 @@ ViewerGui::ViewerGui(filament::Engine* engine, filament::Scene* scene, filament: .intensity(mSettings.lighting.sunlightIntensity) .direction(normalize(mSettings.lighting.sunlightDirection)) .castShadows(true) - .sunAngularRadius(1.0f) - .sunHaloSize(2.0f) - .sunHaloFalloff(80.0f) + .sunAngularRadius(mSettings.lighting.sunlightAngularRadius) + .sunHaloSize(mSettings.lighting.sunlightHaloSize) + .sunHaloFalloff(mSettings.lighting.sunlightHaloFalloff) .build(*engine, mSunlight); if (mSettings.lighting.enableSunlight) { mScene->addEntity(mSunlight); @@ -462,7 +462,6 @@ void ViewerGui::setIndirectLight(filament::IndirectLight* ibl, mSettings.lighting.sunlightDirection = d; mSettings.lighting.sunlightColor = c.rgb; mSettings.lighting.sunlightIntensity = c[3] * ibl->getIntensity(); - updateIndirectLight(); } } } @@ -482,14 +481,6 @@ void ViewerGui::updateRootTransform() { tcm.setTransform(root, transform); } -void ViewerGui::updateIndirectLight() { - using namespace filament::math; - if (mIndirectLight) { - mIndirectLight->setIntensity(mSettings.lighting.iblIntensity); - mIndirectLight->setRotation(mat3f::rotation(mSettings.lighting.iblRotation, float3{ 0, 1, 0 })); - } -} - void ViewerGui::sceneSelectionUI() { // Build a list of checkboxes, one for each glTF scene. bool changed = false; @@ -774,7 +765,7 @@ void ViewerGui::updateUserInterface() { int lowpass = (int) ssao.lowPassFilter; bool upsampling = ssao.upsampling != View::QualityLevel::LOW; - bool halfRes = ssao.resolution == 1.0f ? false : true; + bool halfRes = ssao.resolution != 1.0f; ImGui::SliderInt("Quality", &quality, 0, 3); ImGui::SliderInt("Low Pass", &lowpass, 0, 2); ImGui::Checkbox("Bent Normals", &ssao.bentNormals); @@ -841,7 +832,10 @@ void ViewerGui::updateUserInterface() { } if (ImGui::CollapsingHeader("Sunlight")) { ImGui::Checkbox("Enable sunlight", &light.enableSunlight); - ImGui::SliderFloat("Sun intensity", &light.sunlightIntensity, 50000.0, 150000.0f); + ImGui::SliderFloat("Sun intensity", &light.sunlightIntensity, 50000.0f, 150000.0f); + ImGui::SliderFloat("Halo size", &light.sunlightHaloSize, 1.01f, 40.0f); + ImGui::SliderFloat("Halo falloff", &light.sunlightHaloFalloff, 4.0f, 1024.0f); + ImGui::SliderFloat("Sun radius", &light.sunlightAngularRadius, 0.1f, 10.0f); ImGuiExt::DirectionWidget("Sun direction", light.sunlightDirection.v); } if (ImGui::CollapsingHeader("All lights")) { @@ -1016,25 +1010,8 @@ void ViewerGui::updateUserInterface() { // At this point, all View settings have been modified, // so we can now push them into the Filament View. applySettings(mEngine, mSettings.view, mView); - - mView->setSoftShadowOptions(mSettings.lighting.softShadowOptions); - - if (light.enableSunlight) { - mScene->addEntity(mSunlight); - auto sun = lm.getInstance(mSunlight); - lm.setIntensity(sun, light.sunlightIntensity); - lm.setDirection(sun, normalize(light.sunlightDirection)); - lm.setColor(sun, light.sunlightColor); - lm.setShadowCaster(sun, light.enableShadows); - lm.setShadowOptions(sun, light.shadowOptions); - } else { - mScene->remove(mSunlight); - } - - lm.forEachComponent([this, &lm, &light](utils::Entity e, LightManager::Instance ci) { - lm.setShadowOptions(ci, light.shadowOptions); - lm.setShadowCaster(ci, light.enableShadows); - }); + applySettings(mEngine, mSettings.lighting, mIndirectLight, mSunlight, + lm.getEntities(), lm.getComponentCount(), &lm, mScene, mView); // TODO(prideout): add support for hierarchy, animation and variant selection in remote mode. To // support these features, we will need to send a message (list of strings) from DebugServer to @@ -1112,8 +1089,6 @@ void ViewerGui::updateUserInterface() { mSidebarWidth = ImGui::GetWindowWidth(); ImGui::End(); - - updateIndirectLight(); } } // namespace viewer