per-light volumetric fog boost #924

This commit is contained in:
Turánszki János
2024-08-17 08:05:25 +02:00
parent a902485135
commit 293689b1e2
10 changed files with 43 additions and 9 deletions
+20 -1
View File
@@ -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);
+1
View File
@@ -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;
@@ -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;
@@ -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;
@@ -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;
+6 -2
View File
@@ -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);
+1 -1
View File
@@ -39,7 +39,7 @@ namespace wi::scene
wi::ecs::ComponentManager<RigidBodyPhysicsComponent>& rigidbodies = componentLibrary.Register<RigidBodyPhysicsComponent>("wi::scene::Scene::rigidbodies", 4); // version = 4
wi::ecs::ComponentManager<SoftBodyPhysicsComponent>& softbodies = componentLibrary.Register<SoftBodyPhysicsComponent>("wi::scene::Scene::softbodies", 3); // version = 3
wi::ecs::ComponentManager<ArmatureComponent>& armatures = componentLibrary.Register<ArmatureComponent>("wi::scene::Scene::armatures");
wi::ecs::ComponentManager<LightComponent>& lights = componentLibrary.Register<LightComponent>("wi::scene::Scene::lights", 2); // version = 2
wi::ecs::ComponentManager<LightComponent>& lights = componentLibrary.Register<LightComponent>("wi::scene::Scene::lights", 3); // version = 3
wi::ecs::ComponentManager<CameraComponent>& cameras = componentLibrary.Register<CameraComponent>("wi::scene::Scene::cameras");
wi::ecs::ComponentManager<EnvironmentProbeComponent>& probes = componentLibrary.Register<EnvironmentProbeComponent>("wi::scene::Scene::probes", 1); // version = 1
wi::ecs::ComponentManager<ForceFieldComponent>& forces = componentLibrary.Register<ForceFieldComponent>("wi::scene::Scene::forces", 1); // version = 1
+1
View File
@@ -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<float> cascade_distances = { 8,80,800 };
wi::vector<std::string> lensFlareNames;
+8
View File
@@ -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)
+1 -1
View File
@@ -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);