diff --git a/Editor/LightWindow.cpp b/Editor/LightWindow.cpp index b5c3ace8f..510d41698 100644 --- a/Editor/LightWindow.cpp +++ b/Editor/LightWindow.cpp @@ -9,7 +9,7 @@ void LightWindow::Create(EditorComponent* _editor) { editor = _editor; wi::gui::Window::Create(ICON_POINTLIGHT " Light", wi::gui::Window::WindowControls::COLLAPSE | wi::gui::Window::WindowControls::CLOSE); - SetSize(XMFLOAT2(650, 900)); + SetSize(XMFLOAT2(650, 940)); closeButton.SetTooltip("Delete LightComponent"); OnClose([=](wi::gui::EventArgs args) { @@ -162,6 +162,23 @@ void LightWindow::Create(EditorComponent* _editor) innerConeAngleSlider.SetTooltip("Adjust the inner cone aperture for spotlight.\n(The inner cone will always be inside the outer cone)"); AddWidget(&innerConeAngleSlider); + volumetricBoostSlider.Create(0, 10, 0, 1000, "Volumetric boost: "); + volumetricBoostSlider.SetSize(XMFLOAT2(wid, hei)); + volumetricBoostSlider.SetPos(XMFLOAT2(x, y += step)); + volumetricBoostSlider.OnSlide([&](wi::gui::EventArgs args) { + wi::scene::Scene& scene = editor->GetCurrentScene(); + for (auto& x : editor->translator.selected) + { + LightComponent* light = scene.lights.GetComponent(x.entity); + if (light != nullptr) + { + light->volumetric_boost = args.fValue; + } + } + }); + volumetricBoostSlider.SetTooltip("Adjust the volumetric fog effect's strength just for this light"); + AddWidget(&volumetricBoostSlider); + shadowCheckBox.Create("Shadow: "); shadowCheckBox.SetSize(XMFLOAT2(hei, hei)); shadowCheckBox.SetPos(XMFLOAT2(x, y += step)); @@ -373,6 +390,7 @@ void LightWindow::SetEntity(Entity entity) lengthSlider.SetValue(light->length); outerConeAngleSlider.SetValue(light->outerConeAngle); innerConeAngleSlider.SetValue(light->innerConeAngle); + volumetricBoostSlider.SetValue(light->volumetric_boost); shadowCheckBox.SetEnabled(true); shadowCheckBox.SetCheck(light->IsCastingShadow()); haloCheckBox.SetEnabled(true); @@ -548,6 +566,7 @@ void LightWindow::ResizeLayout() add(rangeSlider); add(outerConeAngleSlider); add(innerConeAngleSlider); + add(volumetricBoostSlider); add(radiusSlider); add(lengthSlider); add_right(shadowCheckBox); diff --git a/Editor/LightWindow.h b/Editor/LightWindow.h index 6e9e154d8..9d5e0db05 100644 --- a/Editor/LightWindow.h +++ b/Editor/LightWindow.h @@ -18,6 +18,7 @@ public: wi::gui::Slider lengthSlider; wi::gui::Slider outerConeAngleSlider; wi::gui::Slider innerConeAngleSlider; + wi::gui::Slider volumetricBoostSlider; wi::gui::CheckBox shadowCheckBox; wi::gui::CheckBox haloCheckBox; wi::gui::CheckBox volumetricsCheckBox; diff --git a/WickedEngine/shaders/volumetricLight_DirectionalPS.hlsl b/WickedEngine/shaders/volumetricLight_DirectionalPS.hlsl index 3de5c3703..984c90200 100644 --- a/WickedEngine/shaders/volumetricLight_DirectionalPS.hlsl +++ b/WickedEngine/shaders/volumetricLight_DirectionalPS.hlsl @@ -70,7 +70,7 @@ float4 main(VertexToPixel input) : SV_TARGET } // Evaluate sample height for height fog calculation, given 0 for V: - shadow *= GetFogAmount(cameraDistance - marchedDistance, P, 0); + shadow *= g_xColor.y + GetFogAmount(cameraDistance - marchedDistance, P, 0); shadow *= scattering; accumulation += shadow; diff --git a/WickedEngine/shaders/volumetricLight_PointPS.hlsl b/WickedEngine/shaders/volumetricLight_PointPS.hlsl index 4154d627a..034fd43ad 100644 --- a/WickedEngine/shaders/volumetricLight_PointPS.hlsl +++ b/WickedEngine/shaders/volumetricLight_PointPS.hlsl @@ -67,7 +67,7 @@ float4 main(VertexToPixel input) : SV_TARGET } // Evaluate sample height for height fog calculation, given 0 for V: - attenuation *= GetFogAmount(cameraDistance - marchedDistance, P, float3(0.0, 0.0, 0.0)); + attenuation *= g_xColor.y + GetFogAmount(cameraDistance - marchedDistance, P, float3(0.0, 0.0, 0.0)); attenuation *= ComputeScattering(saturate(dot(L, -V))); accumulation += attenuation; diff --git a/WickedEngine/shaders/volumetricLight_SpotPS.hlsl b/WickedEngine/shaders/volumetricLight_SpotPS.hlsl index 72ea5edf6..35684b5d9 100644 --- a/WickedEngine/shaders/volumetricLight_SpotPS.hlsl +++ b/WickedEngine/shaders/volumetricLight_SpotPS.hlsl @@ -71,7 +71,8 @@ float4 main(VertexToPixel input) : SV_TARGET // If camera is outside light volume, do a cone trace to determine closest point on cone: float tnear = 0; float tfar = 0; - if(intersectInfiniteCone(GetCamera().position, -V, light.position, light.GetDirection(), g_xColor.y, g_xColor.z, tnear, tfar)) + float2 sina2_cosa2 = unpack_half2(asuint(g_xColor.z)); + if(intersectInfiniteCone(GetCamera().position, -V, light.position, light.GetDirection(), sina2_cosa2.x, sina2_cosa2.y, tnear, tfar)) { rayEnd = GetCamera().position - V * max(0, tnear); //return float4(1,0,0,1); @@ -117,7 +118,7 @@ float4 main(VertexToPixel input) : SV_TARGET } // Evaluate sample height for exponential fog calculation, given 0 for V: - attenuation *= GetFogAmount(cameraDistance - marchedDistance, P, float3(0.0, 0.0, 0.0)); + attenuation *= g_xColor.y + GetFogAmount(cameraDistance - marchedDistance, P, float3(0.0, 0.0, 0.0)); attenuation *= ComputeScattering(saturate(dot(L, -V))); accumulation += attenuation; diff --git a/WickedEngine/wiRenderer.cpp b/WickedEngine/wiRenderer.cpp index 05f7169d4..549c1b497 100644 --- a/WickedEngine/wiRenderer.cpp +++ b/WickedEngine/wiRenderer.cpp @@ -5955,6 +5955,7 @@ void DrawVolumeLights( { MiscCB miscCb; miscCb.g_xColor.x = float(type_idx); + miscCb.g_xColor.y = light.volumetric_boost; device->BindDynamicConstantBuffer(miscCb, CB_GETBINDSLOT(MiscCB), cmd); device->Draw(3, 0, cmd); // full screen triangle @@ -5964,6 +5965,7 @@ void DrawVolumeLights( { MiscCB miscCb; miscCb.g_xColor.x = float(type_idx); + miscCb.g_xColor.y = light.volumetric_boost; float sca = light.GetRange() + 1; XMStoreFloat4x4(&miscCb.g_xTransform, XMMatrixScaling(sca, sca, sca) * XMMatrixTranslationFromVector(XMLoadFloat3(&light.position)) * VP); device->BindDynamicConstantBuffer(miscCb, CB_GETBINDSLOT(MiscCB), cmd); @@ -5975,8 +5977,10 @@ void DrawVolumeLights( { MiscCB miscCb; miscCb.g_xColor.x = float(type_idx); - miscCb.g_xColor.y = std::pow(std::sin(light.outerConeAngle), 2.0f); - miscCb.g_xColor.z = std::pow(std::cos(light.outerConeAngle), 2.0f); + miscCb.g_xColor.y = light.volumetric_boost; + + uint packed = wi::math::pack_half2(std::pow(std::sin(light.outerConeAngle), 2.0f), std::pow(std::cos(light.outerConeAngle), 2.0f)); + std::memcpy(&miscCb.g_xColor.z, &packed, sizeof(packed)); const XMVECTOR LightPos = XMLoadFloat3(&light.position); const XMVECTOR LightDirection = XMLoadFloat3(&light.direction); diff --git a/WickedEngine/wiScene.h b/WickedEngine/wiScene.h index 30bf00295..b20315a65 100644 --- a/WickedEngine/wiScene.h +++ b/WickedEngine/wiScene.h @@ -39,7 +39,7 @@ namespace wi::scene wi::ecs::ComponentManager& rigidbodies = componentLibrary.Register("wi::scene::Scene::rigidbodies", 4); // version = 4 wi::ecs::ComponentManager& softbodies = componentLibrary.Register("wi::scene::Scene::softbodies", 3); // version = 3 wi::ecs::ComponentManager& armatures = componentLibrary.Register("wi::scene::Scene::armatures"); - wi::ecs::ComponentManager& lights = componentLibrary.Register("wi::scene::Scene::lights", 2); // version = 2 + wi::ecs::ComponentManager& lights = componentLibrary.Register("wi::scene::Scene::lights", 3); // version = 3 wi::ecs::ComponentManager& cameras = componentLibrary.Register("wi::scene::Scene::cameras"); wi::ecs::ComponentManager& probes = componentLibrary.Register("wi::scene::Scene::probes", 1); // version = 1 wi::ecs::ComponentManager& forces = componentLibrary.Register("wi::scene::Scene::forces", 1); // version = 1 diff --git a/WickedEngine/wiScene_Components.h b/WickedEngine/wiScene_Components.h index 67f682a00..e408ce7a5 100644 --- a/WickedEngine/wiScene_Components.h +++ b/WickedEngine/wiScene_Components.h @@ -1065,6 +1065,7 @@ namespace wi::scene float innerConeAngle = 0; // default value is 0, means only outer cone angle is used float radius = 0.025f; float length = 0; + float volumetric_boost = 0; // increase the strength of volumetric fog only for this light wi::vector cascade_distances = { 8,80,800 }; wi::vector lensFlareNames; diff --git a/WickedEngine/wiScene_Serializers.cpp b/WickedEngine/wiScene_Serializers.cpp index bf697f7a8..3edf16189 100644 --- a/WickedEngine/wiScene_Serializers.cpp +++ b/WickedEngine/wiScene_Serializers.cpp @@ -978,6 +978,10 @@ namespace wi::scene archive >> radius; archive >> length; } + if (seri.GetVersion() >= 3) + { + archive >> volumetric_boost; + } wi::jobsystem::Execute(seri.ctx, [&](wi::jobsystem::JobArgs args) { lensFlareRimTextures.resize(lensFlareNames.size()); @@ -1046,6 +1050,10 @@ namespace wi::scene archive << radius; archive << length; } + if (seri.GetVersion() >= 3) + { + archive << volumetric_boost; + } } } void CameraComponent::Serialize(wi::Archive& archive, EntitySerializer& seri) diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index 7cda6e478..f678bc87b 100644 --- a/WickedEngine/wiVersion.cpp +++ b/WickedEngine/wiVersion.cpp @@ -9,7 +9,7 @@ namespace wi::version // minor features, major updates, breaking compatibility changes const int minor = 71; // minor bug fixes, alterations, refactors, updates - const int revision = 542; + const int revision = 543; const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);