From 892bbf0e13af65327d6ad645510b4cdf88b8fc58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tur=C3=A1nszki=20J=C3=A1nos?= Date: Thu, 16 Mar 2023 17:38:55 +0100 Subject: [PATCH] decal slopeBlendPower --- .../ScriptingAPI-Documentation.md | 2 ++ Editor/DecalWindow.cpp | 19 ++++++++++++++++-- Editor/DecalWindow.h | 3 ++- WickedEngine/shaders/objectHF.hlsli | 6 ++++-- WickedEngine/shaders/surfaceHF.hlsli | 3 ++- WickedEngine/wiRenderer.cpp | 2 ++ WickedEngine/wiScene.cpp | 2 +- WickedEngine/wiScene.h | 2 +- WickedEngine/wiScene_BindLua.cpp | 20 +++++++++++++++++++ WickedEngine/wiScene_BindLua.h | 2 ++ WickedEngine/wiScene_Components.h | 2 ++ WickedEngine/wiScene_Serializers.cpp | 10 ++++++++++ WickedEngine/wiVersion.cpp | 2 +- 13 files changed, 66 insertions(+), 9 deletions(-) diff --git a/Content/Documentation/ScriptingAPI-Documentation.md b/Content/Documentation/ScriptingAPI-Documentation.md index 6ebb5e340..4f03fe690 100644 --- a/Content/Documentation/ScriptingAPI-Documentation.md +++ b/Content/Documentation/ScriptingAPI-Documentation.md @@ -1162,6 +1162,8 @@ The decal component is a textured sticker that can be put down onto meshes. Most - SetBaseColorOnlyAlpha(bool value) -- Set decal to only use alpha from base color texture. Useful for blending normalmap-only decals - IsBaseColorOnlyAlpha() : bool +- SetSlopeBlendPower(float value) +- GetSlopeBlendPower() : float ## Canvas diff --git a/Editor/DecalWindow.cpp b/Editor/DecalWindow.cpp index b9859bdfb..08343267d 100644 --- a/Editor/DecalWindow.cpp +++ b/Editor/DecalWindow.cpp @@ -10,7 +10,7 @@ void DecalWindow::Create(EditorComponent* _editor) { editor = _editor; wi::gui::Window::Create(ICON_DECAL " Decal", wi::gui::Window::WindowControls::COLLAPSE | wi::gui::Window::WindowControls::CLOSE); - SetSize(XMFLOAT2(300, 180)); + SetSize(XMFLOAT2(300, 200)); closeButton.SetTooltip("Delete DecalComponent"); OnClose([=](wi::gui::EventArgs args) { @@ -53,6 +53,19 @@ void DecalWindow::Create(EditorComponent* _editor) }); AddWidget(&onlyalphaCheckBox); + slopeBlendPowerSlider.Create(0, 8, 0, 1000, "Slope Blend: "); + slopeBlendPowerSlider.SetSize(XMFLOAT2(100, hei)); + slopeBlendPowerSlider.SetTooltip("Set a power factor for blending on surface slopes. 0 = no slope blend, increasing = more slope blend"); + slopeBlendPowerSlider.OnSlide([=](wi::gui::EventArgs args) { + Scene& scene = editor->GetCurrentScene(); + DecalComponent* decal = scene.decals.GetComponent(entity); + if (decal != nullptr) + { + decal->slopeBlendPower = args.fValue; + } + }); + AddWidget(&slopeBlendPowerSlider); + y += step; infoLabel.Create(""); @@ -80,6 +93,7 @@ void DecalWindow::SetEntity(Entity entity) { SetEnabled(true); onlyalphaCheckBox.SetCheck(decal->IsBaseColorOnlyAlpha()); + slopeBlendPowerSlider.SetValue(decal->slopeBlendPower); } else { @@ -98,7 +112,7 @@ void DecalWindow::ResizeLayout() auto add = [&](wi::gui::Widget& widget) { if (!widget.IsVisible()) return; - const float margin_left = 80; + const float margin_left = 100; const float margin_right = 40; widget.SetPos(XMFLOAT2(margin_left, y)); widget.SetSize(XMFLOAT2(width - margin_left - margin_right, widget.GetScale().y)); @@ -127,5 +141,6 @@ void DecalWindow::ResizeLayout() add_fullwidth(infoLabel); add_right(placementCheckBox); add_right(onlyalphaCheckBox); + add(slopeBlendPowerSlider); } diff --git a/Editor/DecalWindow.h b/Editor/DecalWindow.h index 7c130eb1f..9adc45201 100644 --- a/Editor/DecalWindow.h +++ b/Editor/DecalWindow.h @@ -12,9 +12,10 @@ public: wi::ecs::Entity entity; void SetEntity(wi::ecs::Entity entity); + wi::gui::Label infoLabel; wi::gui::CheckBox placementCheckBox; wi::gui::CheckBox onlyalphaCheckBox; - wi::gui::Label infoLabel; + wi::gui::Slider slopeBlendPowerSlider; void ResizeLayout() override; }; diff --git a/WickedEngine/shaders/objectHF.hlsli b/WickedEngine/shaders/objectHF.hlsli index c0fb22e9a..c680f7d4a 100644 --- a/WickedEngine/shaders/objectHF.hlsli +++ b/WickedEngine/shaders/objectHF.hlsli @@ -532,7 +532,8 @@ inline void ForwardDecals(inout Surface surface, inout float4 surfaceMap) float4 decalColor = decal.GetColor(); // blend out if close to cube Z: const float edgeBlend = 1 - pow(saturate(abs(clipSpacePos.z)), 8); - decalColor.a *= edgeBlend; + const float slopeBlend = decal.GetConeAngleCos() > 0 ? pow(saturate(dot(surface.N, decal.GetDirection())), decal.GetConeAngleCos()) : 1; + decalColor.a *= edgeBlend * slopeBlend; [branch] if (decalTexture >= 0) { @@ -862,7 +863,8 @@ inline void TiledDecals(inout Surface surface, uint flatTileIndex, inout float4 float4 decalColor = decal.GetColor(); // blend out if close to cube Z: const float edgeBlend = 1 - pow(saturate(abs(clipSpacePos.z)), 8); - decalColor.a *= edgeBlend; + const float slopeBlend = decal.GetConeAngleCos() > 0 ? pow(saturate(dot(surface.N, decal.GetDirection())), decal.GetConeAngleCos()) : 1; + decalColor.a *= edgeBlend * slopeBlend; [branch] if (decalTexture >= 0) { diff --git a/WickedEngine/shaders/surfaceHF.hlsli b/WickedEngine/shaders/surfaceHF.hlsli index df5cbdcfa..bd8107551 100644 --- a/WickedEngine/shaders/surfaceHF.hlsli +++ b/WickedEngine/shaders/surfaceHF.hlsli @@ -534,7 +534,8 @@ struct Surface float4 decalColor = decal.GetColor(); // blend out if close to cube Z: const float edgeBlend = 1 - pow(saturate(abs(clipSpacePos.z)), 8); - decalColor.a *= edgeBlend; + const float slopeBlend = decal.GetConeAngleCos() > 0 ? pow(saturate(dot(N, decal.GetDirection())), decal.GetConeAngleCos()) : 1; + decalColor.a *= edgeBlend * slopeBlend; [branch] if (decalTexture >= 0) { diff --git a/WickedEngine/wiRenderer.cpp b/WickedEngine/wiRenderer.cpp index cbbf8f039..e560c5d5e 100644 --- a/WickedEngine/wiRenderer.cpp +++ b/WickedEngine/wiRenderer.cpp @@ -3768,6 +3768,8 @@ void UpdateRenderData( float emissive_mul = 1 + decal.emissive; shaderentity.SetColor(float4(decal.color.x * emissive_mul, decal.color.y * emissive_mul, decal.color.z * emissive_mul, decal.color.w)); shaderentity.shadowAtlasMulAdd = decal.texMulAdd; + shaderentity.SetConeAngleCos(decal.slopeBlendPower); + shaderentity.SetDirection(decal.front); shaderentity.SetIndices(matrixCounter, 0); shadermatrix = XMMatrixInverse(nullptr, XMLoadFloat4x4(&decal.world)); diff --git a/WickedEngine/wiScene.cpp b/WickedEngine/wiScene.cpp index 3b10b5d7f..8471fa011 100644 --- a/WickedEngine/wiScene.cpp +++ b/WickedEngine/wiScene.cpp @@ -3770,7 +3770,7 @@ namespace wi::scene decal.world = transform.world; XMMATRIX W = XMLoadFloat4x4(&decal.world); - XMVECTOR front = XMVectorSet(0, 0, 1, 0); + XMVECTOR front = XMVectorSet(0, 0, -1, 0); front = XMVector3TransformNormal(front, W); XMStoreFloat3(&decal.front, front); diff --git a/WickedEngine/wiScene.h b/WickedEngine/wiScene.h index 3590faf0d..656ddf229 100644 --- a/WickedEngine/wiScene.h +++ b/WickedEngine/wiScene.h @@ -39,7 +39,7 @@ namespace wi::scene wi::ecs::ComponentManager& cameras = componentLibrary.Register("wi::scene::Scene::cameras"); wi::ecs::ComponentManager& probes = componentLibrary.Register("wi::scene::Scene::probes"); wi::ecs::ComponentManager& forces = componentLibrary.Register("wi::scene::Scene::forces", 1); // version = 1 - wi::ecs::ComponentManager& decals = componentLibrary.Register("wi::scene::Scene::decals"); + wi::ecs::ComponentManager& decals = componentLibrary.Register("wi::scene::Scene::decals", 1); // version = 1 wi::ecs::ComponentManager& animations = componentLibrary.Register("wi::scene::Scene::animations", 1); // version = 1 wi::ecs::ComponentManager& animation_datas = componentLibrary.Register("wi::scene::Scene::animation_datas"); wi::ecs::ComponentManager& emitters = componentLibrary.Register("wi::scene::Scene::emitters"); diff --git a/WickedEngine/wiScene_BindLua.cpp b/WickedEngine/wiScene_BindLua.cpp index 848f81dd9..613dc1b05 100644 --- a/WickedEngine/wiScene_BindLua.cpp +++ b/WickedEngine/wiScene_BindLua.cpp @@ -5805,6 +5805,8 @@ int HumanoidComponent_BindLua::SetLookAt(lua_State* L) Luna::FunctionType DecalComponent_BindLua::methods[] = { lunamethod(DecalComponent_BindLua, SetBaseColorOnlyAlpha), lunamethod(DecalComponent_BindLua, IsBaseColorOnlyAlpha), + lunamethod(DecalComponent_BindLua, SetSlopeBlendPower), + lunamethod(DecalComponent_BindLua, GetSlopeBlendPower), { NULL, NULL } }; Luna::PropertyType DecalComponent_BindLua::properties[] = { @@ -5829,5 +5831,23 @@ int DecalComponent_BindLua::IsBaseColorOnlyAlpha(lua_State* L) wi::lua::SSetBool(L, component->IsBaseColorOnlyAlpha()); return 1; } +int DecalComponent_BindLua::SetSlopeBlendPower(lua_State* L) +{ + int argc = wi::lua::SGetArgCount(L); + if (argc > 0) + { + component->slopeBlendPower = wi::lua::SGetFloat(L, 1); + } + else + { + wi::lua::SError(L, "SetSlopeBlendPower(float value) not enough arguments!"); + } + return 0; +} +int DecalComponent_BindLua::GetSlopeBlendPower(lua_State* L) +{ + wi::lua::SSetFloat(L, component->slopeBlendPower); + return 1; +} } diff --git a/WickedEngine/wiScene_BindLua.h b/WickedEngine/wiScene_BindLua.h index 7c884e59d..48704ca26 100644 --- a/WickedEngine/wiScene_BindLua.h +++ b/WickedEngine/wiScene_BindLua.h @@ -1685,6 +1685,8 @@ namespace wi::lua::scene int SetBaseColorOnlyAlpha(lua_State* L); int IsBaseColorOnlyAlpha(lua_State* L); + int SetSlopeBlendPower(lua_State* L); + int GetSlopeBlendPower(lua_State* L); }; } diff --git a/WickedEngine/wiScene_Components.h b/WickedEngine/wiScene_Components.h index 93b6ad092..09585fdf5 100644 --- a/WickedEngine/wiScene_Components.h +++ b/WickedEngine/wiScene_Components.h @@ -1052,6 +1052,8 @@ namespace wi::scene }; uint32_t _flags = EMPTY; + float slopeBlendPower = 0; + // Set decal to only use alpha from base color texture. Useful for blending normalmap-only decals constexpr void SetBaseColorOnlyAlpha(bool value) { if (value) { _flags |= BASECOLOR_ONLY_ALPHA; } else { _flags ^= BASECOLOR_ONLY_ALPHA; } } diff --git a/WickedEngine/wiScene_Serializers.cpp b/WickedEngine/wiScene_Serializers.cpp index 72829c0e3..43b673da4 100644 --- a/WickedEngine/wiScene_Serializers.cpp +++ b/WickedEngine/wiScene_Serializers.cpp @@ -983,10 +983,20 @@ namespace wi::scene if (archive.IsReadMode()) { archive >> _flags; + + if (seri.GetVersion() >= 1) + { + archive >> slopeBlendPower; + } } else { archive << _flags; + + if (seri.GetVersion() >= 1) + { + archive << slopeBlendPower; + } } } void AnimationComponent::Serialize(wi::Archive& archive, EntitySerializer& seri) diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index 86cb15152..6f9714fbe 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 = 179; + const int revision = 180; const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);