diff --git a/src/PrepareLightsPass.cpp b/src/PrepareLightsPass.cpp index 3ffcbef..1e2821b 100644 --- a/src/PrepareLightsPass.cpp +++ b/src/PrepareLightsPass.cpp @@ -208,25 +208,43 @@ static bool ConvertLight(const donut::engine::Light& light, PolymorphicLightInfo polymorphic.scalars = fp32ToFp16(halfAngularSizeRad) | (fp32ToFp16(solidAngle) << 16); return true; } - case LightType_Spot: { - auto& spot = static_cast(light); - float projectedArea = dm::PI_f * square(spot.radius); - float3 radiance = spot.color * spot.intensity / projectedArea; + case LightType_Spot: + case LightType_SpotProfile: { + auto& spot = static_cast(light); + if (spot.radius == 0.f) + { + float3 flux = spot.color * spot.intensity; + + polymorphic.colorTypeAndFlags = (uint32_t)PolymorphicLightType::kPoint << kPolymorphicLightTypeShift; + packLightColor(flux, polymorphic); + polymorphic.center = float3(spot.GetPosition()); + } + else + { + float projectedArea = dm::PI_f * square(spot.radius); + float3 radiance = spot.color * spot.intensity / projectedArea; + + polymorphic.colorTypeAndFlags = (uint32_t)PolymorphicLightType::kSphere << kPolymorphicLightTypeShift; + packLightColor(radiance, polymorphic); + polymorphic.center = float3(spot.GetPosition()); + polymorphic.scalars = fp32ToFp16(spot.radius); + } + float softness = saturate(1.f - spot.innerAngle / spot.outerAngle); - polymorphic.colorTypeAndFlags = (uint32_t)PolymorphicLightType::kSphere << kPolymorphicLightTypeShift; polymorphic.colorTypeAndFlags |= kPolymorphicLightShapingEnableBit; - packLightColor(radiance, polymorphic); - polymorphic.center = float3(spot.GetPosition()); - polymorphic.scalars = fp32ToFp16(spot.radius); polymorphic.primaryAxis = packNormalizedVector(float3(normalize(spot.GetDirection()))); polymorphic.cosConeAngleAndSoftness = fp32ToFp16(cosf(dm::radians(spot.outerAngle))); polymorphic.cosConeAngleAndSoftness |= fp32ToFp16(softness) << 16; - if (spot.profileTextureIndex >= 0) + if (spot.GetLightType() == LightType_SpotProfile) { - polymorphic.iesProfileIndex = spot.profileTextureIndex; - polymorphic.colorTypeAndFlags |= kPolymorphicLightIesProfileEnableBit; + auto& spotWithProfile = static_cast(light); + if (spotWithProfile.profileTextureIndex >= 0) + { + polymorphic.iesProfileIndex = spotWithProfile.profileTextureIndex; + polymorphic.colorTypeAndFlags |= kPolymorphicLightIesProfileEnableBit; + } } return true; diff --git a/src/SampleScene.h b/src/SampleScene.h index c7275d9..7be1c60 100644 --- a/src/SampleScene.h +++ b/src/SampleScene.h @@ -17,6 +17,7 @@ constexpr int LightType_Environment = 1000; constexpr int LightType_Cylinder = 1001; constexpr int LightType_Disk = 1002; constexpr int LightType_Rect = 1003; +constexpr int LightType_SpotProfile = 1004; class SpotLightWithProfile : public donut::engine::SpotLight { @@ -26,6 +27,7 @@ class SpotLightWithProfile : public donut::engine::SpotLight void Load(const Json::Value& node) override; void Store(Json::Value& node) const override; + [[nodiscard]] int GetLightType() const override { return LightType_SpotProfile; } [[nodiscard]] std::shared_ptr Clone() override; }; diff --git a/src/UserInterface.cpp b/src/UserInterface.cpp index 66a544d..1031bcc 100644 --- a/src/UserInterface.cpp +++ b/src/UserInterface.cpp @@ -1121,38 +1121,43 @@ void UserInterface::SceneSettings() break; } case LightType_Spot: + case LightType_SpotProfile: { - SpotLightWithProfile& spotLight = static_cast(*m_SelectedLight); + engine::SpotLight& spotLight = static_cast(*m_SelectedLight); app::LightEditor_Spot(spotLight); - ImGui::PushItemWidth(150.f); - if (ImGui::BeginCombo("IES Profile", spotLight.profileName.empty() ? "(none)" : spotLight.profileName.c_str())) + if (spotLight.GetLightType() == LightType_SpotProfile) { - bool selected = spotLight.profileName.empty(); - if (ImGui::Selectable("(none)", &selected) && selected) - { - spotLight.profileName = ""; - spotLight.profileTextureIndex = -1; - } - - for (auto profile : m_ui.resources->iesProfiles) + SpotLightWithProfile& spotLightProfile = static_cast(*m_SelectedLight); + ImGui::PushItemWidth(150.f); + if (ImGui::BeginCombo("IES Profile", spotLightProfile.profileName.empty() ? "(none)" : spotLightProfile.profileName.c_str())) { - selected = profile->name == spotLight.profileName; - if (ImGui::Selectable(profile->name.c_str(), &selected) && selected) + bool selected = spotLightProfile.profileName.empty(); + if (ImGui::Selectable("(none)", &selected) && selected) { - spotLight.profileName = profile->name; - spotLight.profileTextureIndex = -1; + spotLightProfile.profileName = ""; + spotLightProfile.profileTextureIndex = -1; } - if (selected) + for (auto profile : m_ui.resources->iesProfiles) { - ImGui::SetItemDefaultFocus(); + selected = profile->name == spotLightProfile.profileName; + if (ImGui::Selectable(profile->name.c_str(), &selected) && selected) + { + spotLightProfile.profileName = profile->name; + spotLightProfile.profileTextureIndex = -1; + } + + if (selected) + { + ImGui::SetItemDefaultFocus(); + } } - } - ImGui::EndCombo(); + ImGui::EndCombo(); + } + ImGui::PopItemWidth(); } - ImGui::PopItemWidth(); if (ImGui::Button("Place Here")) { diff --git a/src/main.cpp b/src/main.cpp index 6f10311..85bc986 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -285,7 +285,7 @@ class SceneRenderer : public app::ApplicationBase { for (const auto& light : m_Scene->GetSceneGraph()->GetLights()) { - if (light->GetLightType() == LightType_Spot) + if (light->GetLightType() == LightType_SpotProfile) { SpotLightWithProfile& spotLight = static_cast(*light);